mirror of
https://github.com/flectar/mail.git
synced 2026-11-12 02:05:59 +00:00
ohos: stop waking the idle loop for unpainted frames
The 16 ms frame throttle was applied to every timeout, including when no redraw was pending, so the loop still woke at ~60 Hz after the timer change. Gate the throttle on a pending redraw and on a visible surface so an idle window sleeps until the next Slint timer or the one-second fallback.
This commit is contained in:
1 parent
1bdb351eff
commit
ab8446c594
2 files changed
+23
-10
No files matched your search
@@ -72,21 +72,29 @@ impl OhosPlatform {
|
||||
|
||||
loop {
|
||||
let now = Instant::now();
|
||||
let has_animations = self
|
||||
.window
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.is_some_and(|w| w.window().has_active_animations());
|
||||
let visible = self.visible.load(Ordering::Relaxed);
|
||||
let has_animations = visible
|
||||
&& self
|
||||
.window
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.is_some_and(|w| w.window().has_active_animations());
|
||||
let redraw_pending = visible
|
||||
&& self
|
||||
.window
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.is_some_and(|w| w.has_pending_redraw());
|
||||
let mut timeout = if self.quit.load(Ordering::Relaxed) {
|
||||
Duration::ZERO
|
||||
} else {
|
||||
self.next_timeout(has_animations)
|
||||
};
|
||||
// Throttle redraws to the animation cadence: Slint may request a
|
||||
// redraw for every frame (e.g. through `animation-tick()`), and
|
||||
// without this the loop would spin at unbounded fps.
|
||||
if now < next_frame {
|
||||
timeout = timeout.min(next_frame - now);
|
||||
// Throttle only a frame that is actually pending. Applying the
|
||||
// 16 ms redraw cadence to every timeout kept the loop awake at
|
||||
// ~60 Hz even when no frame had been requested.
|
||||
if redraw_pending {
|
||||
timeout = timeout.min(next_frame.saturating_duration_since(now));
|
||||
}
|
||||
|
||||
match rx.recv_timeout(timeout) {
|
||||
|
||||
@@ -175,6 +175,11 @@ impl OhosWindow {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether Slint has queued a frame that has not been consumed yet.
|
||||
pub fn has_pending_redraw(&self) -> bool {
|
||||
self.needs_redraw.get()
|
||||
}
|
||||
|
||||
/// Render if a redraw was requested since the last call. Software frames
|
||||
/// are handed to `present_software` (the buffer-queue presenter); GPU
|
||||
/// frames present themselves through the wgpu surface.
|
||||
|
||||
Reference in new issue
Block a user