render: Reset buffers after non-space-tracked rendering

This commit is contained in:
Victoria Brekenfeld 2022-04-26 16:52:49 +02:00
parent 81374ed282
commit 969cc8dae5
4 changed files with 51 additions and 6 deletions

View file

@ -612,11 +612,23 @@ impl Surface {
return Ok(()); return Ok(());
} }
let nodes = state if render::needs_buffer_reset(&self.output, state) {
self.surface.as_mut().unwrap().reset_buffers();
}
let workspace = state
.shell .shell
.active_space(&self.output) .active_space(&self.output);
.space let nodes = workspace
.windows() .get_fullscreen(&self.output)
.map(|w| vec![w])
.unwrap_or_else(||
workspace
.space
.windows()
.collect::<Vec<_>>()
)
.into_iter()
.flat_map(|w| { .flat_map(|w| {
w.toplevel() w.toplevel()
.get_surface()? .get_surface()?

View file

@ -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::<DidCustomRendering>().unwrap().0.swap(will_render_custom, Ordering::AcqRel) != will_render_custom
}
pub fn render_output<R>( pub fn render_output<R>(
gpu: Option<&DrmNode>, gpu: Option<&DrmNode>,
renderer: &mut R, renderer: &mut R,
@ -128,7 +142,7 @@ where
let workspace = state.shell.active_space(output); let workspace = state.shell.active_space(output);
let maybe_fullscreen_window = workspace.get_fullscreen(output).cloned(); let maybe_fullscreen_window = workspace.get_fullscreen(output).cloned();
let res = if let Some(window) = maybe_fullscreen_window { 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) render_fullscreen(gpu, renderer, window, state, output, hardware_cursor)
} }

View file

@ -35,15 +35,25 @@ pub struct WinitState {
backend: Rc<RefCell<WinitGraphicsBackend>>, backend: Rc<RefCell<WinitGraphicsBackend>>,
//_global: GlobalDrop<WlOutput>, //_global: GlobalDrop<WlOutput>,
output: Output, output: Output,
age_reset: u8,
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
fps: Fps, fps: Fps,
} }
impl WinitState { impl WinitState {
pub fn render_output(&mut self, state: &mut Common) -> Result<()> { 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(); let backend = &mut *self.backend.borrow_mut();
backend.bind().with_context(|| "Failed to bind buffer")?; 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( match render::render_output(
None, None,
@ -98,6 +108,10 @@ impl WinitState {
Ok(()) Ok(())
} }
} }
pub fn reset_buffers(&mut self) {
self.age_reset = 3;
}
} }
pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Result<()> { pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Result<()> {
@ -186,6 +200,7 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Res
output: output.clone(), output: output.clone(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
fps: Fps::default(), fps: Fps::default(),
age_reset: 0,
}); });
state.common.output_conf.add_heads(std::iter::once(&output)); state.common.output_conf.add_heads(std::iter::once(&output));
state state

View file

@ -179,6 +179,10 @@ impl Surface {
renderer: &mut Gles2Renderer, renderer: &mut Gles2Renderer,
state: &mut Common, state: &mut Common,
) -> Result<()> { ) -> Result<()> {
if render::needs_buffer_reset(&self.output, state) {
self.surface.reset_buffers();
}
let (buffer, age) = self let (buffer, age) = self
.surface .surface
.buffer() .buffer()