From 9195a338fd7f25b3283136f41016fee068582eac Mon Sep 17 00:00:00 2001 From: Aleksander Date: Sat, 26 Oct 2024 21:57:11 +0200 Subject: [PATCH] WayVR: Redraw only if needed --- src/backend/wayvr/comp.rs | 13 +++++++++++-- src/backend/wayvr/display.rs | 10 ++++++---- src/backend/wayvr/mod.rs | 26 +++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/backend/wayvr/comp.rs b/src/backend/wayvr/comp.rs index 1c85810..6b8272e 100644 --- a/src/backend/wayvr/comp.rs +++ b/src/backend/wayvr/comp.rs @@ -1,13 +1,15 @@ use smithay::backend::renderer::utils::on_commit_buffer_handler; use smithay::input::{Seat, SeatHandler, SeatState}; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel; +use smithay::reexports::wayland_server; use smithay::reexports::wayland_server::protocol::{wl_buffer, wl_seat, wl_surface}; -use smithay::reexports::wayland_server::{self, Resource}; +use smithay::reexports::wayland_server::Resource; use smithay::wayland::buffer::BufferHandler; use smithay::wayland::shm::{ShmHandler, ShmState}; use smithay::{ delegate_compositor, delegate_data_device, delegate_seat, delegate_shm, delegate_xdg_shell, }; +use std::collections::HashSet; use std::os::fd::OwnedFd; use smithay::utils::Serial; @@ -35,8 +37,14 @@ pub struct Application { pub seat_state: SeatState, pub shm: ShmState, pub data_device: DataDeviceState, - pub wayvr_tasks: SyncEventQueue, + pub redraw_requests: HashSet, +} + +impl Application { + pub fn check_redraw(&mut self, surface: &WlSurface) -> bool { + self.redraw_requests.remove(&surface.id()) + } } impl compositor::CompositorHandler for Application { @@ -53,6 +61,7 @@ impl compositor::CompositorHandler for Application { fn commit(&mut self, surface: &WlSurface) { on_commit_buffer_handler::(surface); + self.redraw_requests.insert(surface.id()); } } diff --git a/src/backend/wayvr/display.rs b/src/backend/wayvr/display.rs index f5e4c26..0c352c4 100644 --- a/src/backend/wayvr/display.rs +++ b/src/backend/wayvr/display.rs @@ -27,10 +27,10 @@ fn generate_auth_key() -> String { uuid.to_string() } -struct DisplayWindow { - window_handle: window::WindowHandle, +pub struct DisplayWindow { + pub window_handle: window::WindowHandle, + pub toplevel: ToplevelSurface, process_handle: process::ProcessHandle, - toplevel: ToplevelSurface, } pub struct SpawnProcessResult { @@ -49,8 +49,9 @@ pub struct Display { pub name: String, pub visible: bool, pub overlay_id: Option, + pub wants_redraw: bool, wm: Rc>, - displayed_windows: Vec, + pub displayed_windows: Vec, wayland_env: super::WaylandEnv, // Render data stuff @@ -108,6 +109,7 @@ impl Display { height, name: String::from(name), displayed_windows: Vec::new(), + wants_redraw: true, egl_data, dmabuf_data, egl_image, diff --git a/src/backend/wayvr/mod.rs b/src/backend/wayvr/mod.rs index 3ed3715..fd7c0b9 100644 --- a/src/backend/wayvr/mod.rs +++ b/src/backend/wayvr/mod.rs @@ -10,7 +10,7 @@ mod smithay_wrapper; mod time; mod window; -use std::{cell::RefCell, rc::Rc}; +use std::{cell::RefCell, collections::HashSet, rc::Rc}; use comp::Application; use display::DisplayVec; @@ -94,6 +94,7 @@ impl WayVR { shm, data_device, wayvr_tasks: tasks.clone(), + redraw_requests: HashSet::new(), }; let time_start = get_millis(); @@ -118,22 +119,41 @@ impl WayVR { // millis since the start of wayvr let display = self .displays - .get(&display) + .get_mut(&display) .ok_or(anyhow::anyhow!(STR_INVALID_HANDLE_DISP))?; - let time_ms = get_millis() - self.time_start; + if !display.wants_redraw { + // Nothing changed, do not render + return Ok(()); + } if !display.visible { // Display is invisible, do not render return Ok(()); } + let time_ms = get_millis() - self.time_start; + display.tick_render(&mut self.gles_renderer, time_ms)?; + display.wants_redraw = false; Ok(()) } pub fn tick_events(&mut self) -> anyhow::Result<()> { + // Check for redraw events + self.displays.iter_mut(&mut |_, disp| { + for disp_window in &disp.displayed_windows { + if self + .manager + .state + .check_redraw(disp_window.toplevel.wl_surface()) + { + disp.wants_redraw = true; + } + } + }); + // Tick all child processes let mut to_remove: SmallVec<[(process::ProcessHandle, display::DisplayHandle); 2]> = SmallVec::new();