Send frame callbacks when not rendering

This commit is contained in:
Ottatop 2023-09-09 16:28:58 -05:00
parent 866f9eec5d
commit 3b65ba5c1d
4 changed files with 36 additions and 8 deletions

View file

@ -12,7 +12,10 @@ use smithay::{
},
winit::{WinitError, WinitEvent, WinitGraphicsBackend},
},
desktop::{layer_map_for_output, utils::send_frames_surface_tree},
desktop::{
layer_map_for_output,
utils::{send_frames_surface_tree, surface_primary_scanout_output},
},
input::pointer::CursorImageStatus,
output::{Output, Subpixel},
reexports::{
@ -32,7 +35,7 @@ use smithay::{
use crate::{
render::pointer::PointerElement,
state::{take_presentation_feedback, Backend, CalloopData, State},
state::{take_presentation_feedback, Backend, CalloopData, State, WithState},
};
use super::BackendData;
@ -232,16 +235,42 @@ pub fn run_winit() -> anyhow::Result<()> {
pointer_element.set_status(state.cursor_status.clone());
if state.pause_rendering {
// TODO: make a pending_windows state, when pending_windows increases,
// | pause rendering.
// | If it goes down, push a frame, then repeat until no pending_windows are left.
let pending_win_count = state
.windows
.iter()
.filter(|win| win.alive())
.filter(|win| win.with_state(|state| !state.loc_request_state.is_idle()))
.count() as u32;
if pending_win_count > 0 {
for win in state.windows.iter() {
win.send_frame(
&output,
state.clock.now(),
Some(Duration::ZERO),
surface_primary_scanout_output,
);
}
state.space.refresh();
state.popup_manager.cleanup();
display
.flush_clients()
.expect("failed to flush client buffers");
state.prev_pending_win_count = pending_win_count;
// TODO: still draw the cursor here
return TimeoutAction::ToDuration(Duration::from_millis(1));
}
state.prev_pending_win_count = pending_win_count;
let Backend::Winit(backend) = &mut state.backend else { unreachable!() };
let full_redraw = &mut backend.full_redraw;
*full_redraw = full_redraw.saturating_sub(1);

View file

@ -20,7 +20,6 @@ use smithay::{
input::{
keyboard::{keysyms, FilterResult},
pointer::{AxisFrame, ButtonEvent, MotionEvent},
SeatHandler,
},
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::ResizeEdge,
utils::{Logical, Point, SERIAL_COUNTER},

View file

@ -161,7 +161,7 @@ impl State {
//
// This *will* cause everything to freeze for a few frames, but it shouldn't impact
// anything meaningfully.
self.pause_rendering = true;
// self.pause_rendering = true;
// schedule on all idle
self.schedule(
@ -186,7 +186,7 @@ impl State {
for (loc, win) in non_pending_wins {
dt.state.space.map_element(win, loc, false);
}
dt.state.pause_rendering = false;
// dt.state.pause_rendering = false;
},
);
}

View file

@ -139,7 +139,7 @@ pub struct State {
pub xwm: Option<X11Wm>,
pub xdisplay: Option<u32>,
pub pause_rendering: bool,
pub prev_pending_win_count: u32,
}
impl State {
@ -360,7 +360,7 @@ impl State {
xwm: None,
xdisplay: None,
pause_rendering: false,
prev_pending_win_count: 0,
})
}