flatland_frame_scheduling_lib/
lib.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5mod throughput_scheduler;
6
7pub use throughput_scheduler::ThroughputScheduler;
8
9use async_trait::async_trait;
10use std::cell::RefCell;
11use std::future::Future;
12use std::pin::Pin;
13use std::task::{Context, Poll, Waker};
14use {fidl_fuchsia_scenic_scheduling as frame_scheduling, fidl_fuchsia_ui_composition as flatland};
15
16#[derive(Debug, PartialEq, Copy, Clone)]
17pub struct PresentationInfo {
18    pub latch_point: zx::MonotonicInstant,
19    pub presentation_time: zx::MonotonicInstant,
20}
21
22#[derive(Debug, PartialEq, Copy, Clone)]
23pub struct PresentedInfo {
24    pub present_received_time: zx::MonotonicInstant,
25    pub actual_latch_point: zx::MonotonicInstant,
26}
27
28impl From<frame_scheduling::PresentReceivedInfo> for PresentedInfo {
29    fn from(item: frame_scheduling::PresentReceivedInfo) -> PresentedInfo {
30        PresentedInfo {
31            present_received_time: zx::MonotonicInstant::from_nanos(
32                item.present_received_time.unwrap(),
33            ),
34            actual_latch_point: zx::MonotonicInstant::from_nanos(item.latched_time.unwrap()),
35        }
36    }
37}
38
39#[derive(Debug, PartialEq, Copy, Clone)]
40pub struct PresentParameters {
41    // The latch point we're expecting to make for this update.
42    pub expected_latch_point: zx::MonotonicInstant,
43    // The time we're expecting to be presented to the display.
44    pub expected_presentation_time: zx::MonotonicInstant,
45    // The requested_presentation_time to pass into Present().
46    pub requested_presentation_time: zx::MonotonicInstant,
47    // The unsquashable boolean to pass into Present().
48    pub unsquashable: bool,
49}
50
51impl From<PresentParameters> for flatland::PresentArgs {
52    fn from(item: PresentParameters) -> flatland::PresentArgs {
53        flatland::PresentArgs {
54            requested_presentation_time: Some(item.requested_presentation_time.into_nanos()),
55            unsquashable: Some(item.unsquashable),
56            ..Default::default()
57        }
58    }
59}
60
61#[async_trait(?Send)]
62pub trait SchedulingLib {
63    // Called whenever the client has new content that it wants displayed.
64    // Eventually results in wait_to_update() resolving.
65    fn request_present(&self) {}
66    // Should be called whenever the OnFramePresented event is received.
67    fn on_frame_presented(
68        &self,
69        _actual_presentation_time: zx::MonotonicInstant,
70        _presented_infos: Vec<PresentedInfo>,
71    ) {
72    }
73    // Should be called whenever the OnNextFrameBegin event is received.
74    fn on_next_frame_begin(
75        &self,
76        additional_present_credits: u32,
77        future_presentation_infos: Vec<PresentationInfo>,
78    );
79    // Async call that resolves when the caller should render/apply updates and call Present.
80    // Caller should always be waiting on wait_to_update() to resolve.
81    async fn wait_to_update(&self) -> PresentParameters;
82}
83
84struct SchedulingFuture<'a> {
85    sched: &'a RefCell<dyn SchedulingFutureState>,
86}
87
88impl Future for SchedulingFuture<'_> {
89    type Output = ();
90    fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<()> {
91        let mut sched = self.sched.borrow_mut();
92        if sched.ready_to_wake_up() {
93            Poll::Ready(())
94        } else {
95            sched.set_waker(ctx.waker().clone());
96            Poll::Pending
97        }
98    }
99}
100trait SchedulingFutureState {
101    fn ready_to_wake_up(&self) -> bool;
102    fn set_waker(&mut self, waker: Waker);
103    fn get_waker(&self) -> &Option<Waker>;
104    fn maybe_wakeup(&self) {
105        if let Some(waker) = &self.get_waker() {
106            if self.ready_to_wake_up() {
107                waker.wake_by_ref();
108            }
109        }
110    }
111}