mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-13 12:23:38 +01:00
perf(animation): do not wake the ghost thread every 8ms for nothing
The thread that owns the ghost host window looked for messages every 8ms for as long as komorebi ran once ghost movement was on, about 125 wakeups a second doing nothing, which keeps a processor from sleeping. Poll at that rate only while there are ghosts, and every 250ms while there are none: it is woken at once by a command either way.
This commit is contained in:
1 parent
388a17d682
commit
fd6fb3047b
1 file changed
+29
-1
@@ -273,6 +273,11 @@ impl GhostHost {
|
|||||||
(self.bounds.0, self.bounds.1)
|
(self.bounds.0, self.bounds.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether there are no ghosts
|
||||||
|
fn is_idle(&self) -> bool {
|
||||||
|
self.thumbnails.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn register(
|
fn register(
|
||||||
&mut self,
|
&mut self,
|
||||||
snapshot: &Snapshot,
|
snapshot: &Snapshot,
|
||||||
@@ -396,6 +401,22 @@ unsafe fn init_layered_transparent(hwnd: HWND) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// How often the owner thread looks for messages for its windows when no
|
||||||
|
/// command comes. While there are ghosts that is often, so that they are never
|
||||||
|
/// kept waiting; while there are none the windows it has are a host nobody can
|
||||||
|
/// see and nothing is sent to, and waking up every few milliseconds for them
|
||||||
|
/// keeps the processor from sleeping.
|
||||||
|
fn poll_interval(idle: bool) -> Duration {
|
||||||
|
if idle {
|
||||||
|
IDLE_POLL_INTERVAL
|
||||||
|
} else {
|
||||||
|
BUSY_POLL_INTERVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const BUSY_POLL_INTERVAL: Duration = Duration::from_millis(8);
|
||||||
|
const IDLE_POLL_INTERVAL: Duration = Duration::from_millis(250);
|
||||||
|
|
||||||
fn run_owner_loop(cmd_rx: crossbeam_channel::Receiver<GhostCmd>) {
|
fn run_owner_loop(cmd_rx: crossbeam_channel::Receiver<GhostCmd>) {
|
||||||
let mut host = match GhostHost::create() {
|
let mut host = match GhostHost::create() {
|
||||||
Ok(host) => Some(host),
|
Ok(host) => Some(host),
|
||||||
@@ -415,7 +436,7 @@ fn run_owner_loop(cmd_rx: crossbeam_channel::Receiver<GhostCmd>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match cmd_rx.recv_timeout(Duration::from_millis(8)) {
|
match cmd_rx.recv_timeout(poll_interval(host.as_ref().is_some_and(GhostHost::is_idle))) {
|
||||||
Ok(GhostCmd::Create {
|
Ok(GhostCmd::Create {
|
||||||
snapshot,
|
snapshot,
|
||||||
start_rect,
|
start_rect,
|
||||||
@@ -658,6 +679,13 @@ mod tests {
|
|||||||
assert!(!is_swap_chain_class(""));
|
assert!(!is_swap_chain_class(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn the_owner_thread_polls_slowly_when_there_are_no_ghosts() {
|
||||||
|
assert_eq!(poll_interval(false), BUSY_POLL_INTERVAL);
|
||||||
|
assert_eq!(poll_interval(true), IDLE_POLL_INTERVAL);
|
||||||
|
assert!(IDLE_POLL_INTERVAL >= BUSY_POLL_INTERVAL * 10);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn the_ghost_is_opaque_until_the_window_is_shown_and_gone_at_the_end() {
|
fn the_ghost_is_opaque_until_the_window_is_shown_and_gone_at_the_end() {
|
||||||
assert_eq!(ghost_opacity(0.0, REVEAL_AT), 255);
|
assert_eq!(ghost_opacity(0.0, REVEAL_AT), 255);
|
||||||
|
|||||||
Reference in new issue
Block a user