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(());
}
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::<Vec<_>>()
)
.into_iter()
.flat_map(|w| {
w.toplevel()
.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>(
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)
}

View file

@ -35,15 +35,25 @@ pub struct WinitState {
backend: Rc<RefCell<WinitGraphicsBackend>>,
//_global: GlobalDrop<WlOutput>,
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>, state: &mut State) -> Result<()> {
@ -186,6 +200,7 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, 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

View file

@ -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()