render: Reset buffers after non-space-tracked rendering
This commit is contained in:
parent
81374ed282
commit
969cc8dae5
4 changed files with 51 additions and 6 deletions
|
|
@ -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()?
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue