inset_embedder/vsync.rs
1//! The screens' refreshes, for whoever paces by them beside the framework: Flutter's
2//! `VsyncWaiter`, which a host with screen ticks hands out for every screen it has, and the
3//! observer it calls. A composition layer's producer, or a host of programs that draw for their own
4//! views, waits here on the same refreshes the host draws the framework's frames at.
5//!
6//! The invariant: one wait is one call, at the first refresh of its screen after it was asked,
7//! whether or not a window on that screen is in sight; what a producer shows, and whether anyone
8//! sees it, are its own to know.
9
10use std::sync::Weak;
11
12use web_time::Instant;
13
14use crate::ScreenId;
15
16/// Flutter's `VsyncWaiter`, for any screen.
17pub trait VsyncWaiter: Send + Sync {
18 /// Calls `observer` once, on the main thread, at the next refresh of `screen`. May be called
19 /// from any thread. Asked again with the same observer before that refresh, it is still
20 /// called once. An observer that is gone by then is not called, nor one waiting on a screen
21 /// that is not connected.
22 fn next_vsync(&self, screen: ScreenId, observer: Weak<dyn VsyncObserver>);
23}
24
25/// What a [`VsyncWaiter`] calls at the refresh it was asked for.
26pub trait VsyncObserver: Send + Sync {
27 /// `at` is the host's clock when the refresh was served, and `display_time` when the picture
28 /// drawn for this refresh is expected to reach the screen, as Flutter's waiter hands on a
29 /// frame's start and target times: a macOS display link's `targetTimestamp`, the moment a
30 /// [`VideoFrameReader`](crate::VideoFrameReader) is asked for the frame of.
31 fn vsync(&self, at: Instant, display_time: Instant);
32}