From 969cc8dae5ea20c13561d198fd1bf657506ebba6 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 26 Apr 2022 16:52:49 +0200 Subject: [PATCH] render: Reset buffers after non-space-tracked rendering --- src/backend/kms/mod.rs | 20 ++++++++++++++++---- src/backend/render/mod.rs | 16 +++++++++++++++- src/backend/winit.rs | 17 ++++++++++++++++- src/backend/x11.rs | 4 ++++ 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 395085d0..4b71068b 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -612,11 +612,23 @@ impl Surface { return Ok(()); } - let nodes = state + if render::needs_buffer_reset(&self.output, state) { + self.surface.as_mut().unwrap().reset_buffers(); + } + + let workspace = state .shell - .active_space(&self.output) - .space - .windows() + .active_space(&self.output); + let nodes = workspace + .get_fullscreen(&self.output) + .map(|w| vec![w]) + .unwrap_or_else(|| + workspace + .space + .windows() + .collect::>() + ) + .into_iter() .flat_map(|w| { w.toplevel() .get_surface()? diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index c87fe816..3da7aafc 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -104,6 +104,20 @@ impl AsGles2Renderer for GlMultiRenderer<'_> { } } +pub fn needs_buffer_reset(output: &Output, state: &Common) -> bool { + use std::sync::atomic::{AtomicBool, Ordering}; + struct DidCustomRendering(AtomicBool); + + let will_render_custom = { + let workspace = state.shell.active_space(output); + workspace.get_fullscreen(output).is_some() + }; + + let userdata = output.user_data(); + userdata.insert_if_missing(|| DidCustomRendering(AtomicBool::new(false))); + userdata.get::().unwrap().0.swap(will_render_custom, Ordering::AcqRel) != will_render_custom +} + pub fn render_output( gpu: Option<&DrmNode>, renderer: &mut R, @@ -128,7 +142,7 @@ where let workspace = state.shell.active_space(output); let maybe_fullscreen_window = workspace.get_fullscreen(output).cloned(); let res = if let Some(window) = maybe_fullscreen_window { - #[cfg(not(feature = "debug"))] + #[cfg(not(feature = "debug"))] { render_fullscreen(gpu, renderer, window, state, output, hardware_cursor) } diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 175221a2..70ed9cca 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -35,15 +35,25 @@ pub struct WinitState { backend: Rc>, //_global: GlobalDrop, output: Output, + age_reset: u8, #[cfg(feature = "debug")] fps: Fps, } impl WinitState { pub fn render_output(&mut self, state: &mut Common) -> Result<()> { + if render::needs_buffer_reset(&self.output, state) { + self.reset_buffers(); + } + let backend = &mut *self.backend.borrow_mut(); backend.bind().with_context(|| "Failed to bind buffer")?; - let age = backend.buffer_age().unwrap_or(0); + let age = if self.age_reset > 0 { + self.age_reset -= 1; + 0 + } else { + backend.buffer_age().unwrap_or(0) + }; match render::render_output( None, @@ -98,6 +108,10 @@ impl WinitState { Ok(()) } } + + pub fn reset_buffers(&mut self) { + self.age_reset = 3; + } } pub fn init_backend(event_loop: &mut EventLoop, state: &mut State) -> Result<()> { @@ -186,6 +200,7 @@ pub fn init_backend(event_loop: &mut EventLoop, state: &mut State) -> Res output: output.clone(), #[cfg(feature = "debug")] fps: Fps::default(), + age_reset: 0, }); state.common.output_conf.add_heads(std::iter::once(&output)); state diff --git a/src/backend/x11.rs b/src/backend/x11.rs index 0b81eb48..2ba5264b 100644 --- a/src/backend/x11.rs +++ b/src/backend/x11.rs @@ -179,6 +179,10 @@ impl Surface { renderer: &mut Gles2Renderer, state: &mut Common, ) -> Result<()> { + if render::needs_buffer_reset(&self.output, state) { + self.surface.reset_buffers(); + } + let (buffer, age) = self .surface .buffer()