mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
Redraw on demand rather than continuously
This commit is contained in:
@@ -41,6 +41,8 @@ impl CompositorHandler for Niri {
|
|||||||
|
|
||||||
xdg_shell::handle_commit(&self.space, surface);
|
xdg_shell::handle_commit(&self.space, surface);
|
||||||
resize_grab::handle_commit(&mut self.space, surface);
|
resize_grab::handle_commit(&mut self.space, surface);
|
||||||
|
|
||||||
|
self.queue_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ impl Niri {
|
|||||||
utime: event.time(),
|
utime: event.time(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Redraw to update the cursor position.
|
||||||
|
self.queue_redraw();
|
||||||
}
|
}
|
||||||
InputEvent::PointerMotionAbsolute { event, .. } => {
|
InputEvent::PointerMotionAbsolute { event, .. } => {
|
||||||
let output = self.space.outputs().next().unwrap();
|
let output = self.space.outputs().next().unwrap();
|
||||||
@@ -112,6 +115,9 @@ impl Niri {
|
|||||||
time: event.time_msec(),
|
time: event.time_msec(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Redraw to update the cursor position.
|
||||||
|
self.queue_redraw();
|
||||||
}
|
}
|
||||||
InputEvent::PointerButton { event, .. } => {
|
InputEvent::PointerButton { event, .. } => {
|
||||||
let pointer = self.seat.get_pointer().unwrap();
|
let pointer = self.seat.get_pointer().unwrap();
|
||||||
|
|||||||
+34
-1
@@ -12,6 +12,7 @@ use smithay::input::keyboard::XkbConfig;
|
|||||||
use smithay::input::{Seat, SeatState};
|
use smithay::input::{Seat, SeatState};
|
||||||
use smithay::output::Output;
|
use smithay::output::Output;
|
||||||
use smithay::reexports::calloop::generic::Generic;
|
use smithay::reexports::calloop::generic::Generic;
|
||||||
|
use smithay::reexports::calloop::timer::{TimeoutAction, Timer};
|
||||||
use smithay::reexports::calloop::{Interest, LoopHandle, LoopSignal, Mode, PostAction};
|
use smithay::reexports::calloop::{Interest, LoopHandle, LoopSignal, Mode, PostAction};
|
||||||
use smithay::reexports::wayland_server::backend::{ClientData, ClientId, DisconnectReason};
|
use smithay::reexports::wayland_server::backend::{ClientData, ClientId, DisconnectReason};
|
||||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||||
@@ -45,6 +46,11 @@ pub struct Niri {
|
|||||||
|
|
||||||
pub seat: Seat<Self>,
|
pub seat: Seat<Self>,
|
||||||
pub output: Option<Output>,
|
pub output: Option<Output>,
|
||||||
|
|
||||||
|
// Set to `true` if there's a redraw queued on the event loop. Reset to `false` in redraw()
|
||||||
|
// which means that you cannot queue more than one redraw at once.
|
||||||
|
pub redraw_queued: bool,
|
||||||
|
pub waiting_for_vblank: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Niri {
|
impl Niri {
|
||||||
@@ -119,6 +125,8 @@ impl Niri {
|
|||||||
|
|
||||||
seat,
|
seat,
|
||||||
output: None,
|
output: None,
|
||||||
|
redraw_queued: false,
|
||||||
|
waiting_for_vblank: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +143,32 @@ impl Niri {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redraw(&mut self, backend: &mut dyn Backend) {
|
/// Schedules an immediate redraw if one is not already scheduled.
|
||||||
|
pub fn queue_redraw(&mut self) {
|
||||||
|
if self.redraw_queued || self.waiting_for_vblank {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.redraw_queued = true;
|
||||||
|
|
||||||
|
self.event_loop
|
||||||
|
.insert_source(Timer::immediate(), |_, _, data| {
|
||||||
|
let backend: &mut dyn Backend = if let Some(tty) = &mut data.tty {
|
||||||
|
tty
|
||||||
|
} else {
|
||||||
|
data.winit.as_mut().unwrap()
|
||||||
|
};
|
||||||
|
data.niri.redraw(backend);
|
||||||
|
TimeoutAction::Drop
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn redraw(&mut self, backend: &mut dyn Backend) {
|
||||||
|
assert!(self.redraw_queued);
|
||||||
|
assert!(!self.waiting_for_vblank);
|
||||||
|
self.redraw_queued = false;
|
||||||
|
|
||||||
let elements = space_render_elements(
|
let elements = space_render_elements(
|
||||||
backend.renderer(),
|
backend.renderer(),
|
||||||
[&self.space],
|
[&self.space],
|
||||||
|
|||||||
+6
-22
@@ -1,6 +1,5 @@
|
|||||||
use std::os::fd::FromRawFd;
|
use std::os::fd::FromRawFd;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use smithay::backend::allocator::dmabuf::Dmabuf;
|
use smithay::backend::allocator::dmabuf::Dmabuf;
|
||||||
@@ -17,7 +16,6 @@ use smithay::backend::session::libseat::LibSeatSession;
|
|||||||
use smithay::backend::session::{Event as SessionEvent, Session};
|
use smithay::backend::session::{Event as SessionEvent, Session};
|
||||||
use smithay::backend::udev::{self, UdevBackend, UdevEvent};
|
use smithay::backend::udev::{self, UdevBackend, UdevEvent};
|
||||||
use smithay::output::{Mode, Output, OutputModeSource, PhysicalProperties, Subpixel};
|
use smithay::output::{Mode, Output, OutputModeSource, PhysicalProperties, Subpixel};
|
||||||
use smithay::reexports::calloop::timer::{TimeoutAction, Timer};
|
|
||||||
use smithay::reexports::calloop::{LoopHandle, RegistrationToken};
|
use smithay::reexports::calloop::{LoopHandle, RegistrationToken};
|
||||||
use smithay::reexports::drm::control::connector::{
|
use smithay::reexports::drm::control::connector::{
|
||||||
Interface as ConnectorInterface, State as ConnectorState,
|
Interface as ConnectorInterface, State as ConnectorState,
|
||||||
@@ -83,7 +81,7 @@ impl Backend for Tty {
|
|||||||
assert!(!res.needs_sync());
|
assert!(!res.needs_sync());
|
||||||
if res.damage.is_some() {
|
if res.damage.is_some() {
|
||||||
match output_device.drm_compositor.queue_frame(()) {
|
match output_device.drm_compositor.queue_frame(()) {
|
||||||
Ok(()) => return,
|
Ok(()) => niri.waiting_for_vblank = true,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("error queueing frame: {err}");
|
error!("error queueing frame: {err}");
|
||||||
}
|
}
|
||||||
@@ -95,17 +93,6 @@ impl Backend for Tty {
|
|||||||
error!("error rendering frame: {err}");
|
error!("error rendering frame: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: render on demand instead of busy looping.
|
|
||||||
niri.event_loop
|
|
||||||
.insert_source(
|
|
||||||
Timer::from_duration(Duration::from_millis(6)),
|
|
||||||
|_, _, data| {
|
|
||||||
data.niri.redraw(data.tty.as_mut().unwrap());
|
|
||||||
TimeoutAction::Drop
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +144,7 @@ impl Tty {
|
|||||||
output_device.drm_compositor.reset_buffers();
|
output_device.drm_compositor.reset_buffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
niri.redraw(tty);
|
niri.queue_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -190,7 +177,7 @@ impl Tty {
|
|||||||
if let Err(err) = tty.device_added(device_id, path, niri) {
|
if let Err(err) = tty.device_added(device_id, path, niri) {
|
||||||
warn!("error adding device: {err:?}");
|
warn!("error adding device: {err:?}");
|
||||||
}
|
}
|
||||||
niri.redraw(tty);
|
niri.queue_redraw();
|
||||||
}
|
}
|
||||||
UdevEvent::Changed { device_id } => tty.device_changed(device_id, niri),
|
UdevEvent::Changed { device_id } => tty.device_changed(device_id, niri),
|
||||||
UdevEvent::Removed { device_id } => tty.device_removed(device_id, niri),
|
UdevEvent::Removed { device_id } => tty.device_removed(device_id, niri),
|
||||||
@@ -198,7 +185,7 @@ impl Tty {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
niri.redraw(self);
|
niri.queue_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device_added(
|
fn device_added(
|
||||||
@@ -250,11 +237,8 @@ impl Tty {
|
|||||||
// .windows
|
// .windows
|
||||||
// .mark_presented(&output_device.last_render_states, metadata);
|
// .mark_presented(&output_device.last_render_states, metadata);
|
||||||
|
|
||||||
// Request redraw before the next VBlank.
|
data.niri.waiting_for_vblank = false;
|
||||||
// let frame_interval = catacomb.windows.output().frame_interval();
|
data.niri.queue_redraw();
|
||||||
// let duration = frame_interval - RENDER_TIME_OFFSET;
|
|
||||||
// catacomb.backend.schedule_redraw(duration);
|
|
||||||
data.niri.redraw(tty);
|
|
||||||
}
|
}
|
||||||
DrmEvent::Error(error) => error!("DRM error: {error}"),
|
DrmEvent::Error(error) => error!("DRM error: {error}"),
|
||||||
};
|
};
|
||||||
|
|||||||
+8
-7
@@ -115,16 +115,17 @@ impl Winit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
WinitEvent::Input(event) => niri.process_input_event(&mut |_| (), event),
|
WinitEvent::Input(event) => niri.process_input_event(&mut |_| (), event),
|
||||||
_ => (),
|
WinitEvent::Focus(_) => (),
|
||||||
|
WinitEvent::Refresh => niri.queue_redraw(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Err(WinitError::WindowClosed) = res {
|
// I want this to stop compiling if more errors are added.
|
||||||
|
#[allow(clippy::single_match)]
|
||||||
|
match res {
|
||||||
|
Err(WinitError::WindowClosed) => {
|
||||||
niri.stop_signal.stop();
|
niri.stop_signal.stop();
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
res.unwrap();
|
|
||||||
}
|
}
|
||||||
|
Ok(()) => (),
|
||||||
niri.redraw(self);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user