Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit fa75e2a

Browse files
committed
[fuchsia] Set presentation interval
1 parent 606e77f commit fa75e2a

File tree

4 files changed

+79
-21
lines changed

4 files changed

+79
-21
lines changed

shell/platform/fuchsia/flutter/flatland_connection.cc

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010

1111
namespace flutter_runner {
1212

13+
namespace {
14+
15+
fml::TimePoint GetNextPresentationTime(fml::TimePoint now,
16+
fml::TimePoint next_presentation_time) {
17+
return now > next_presentation_time
18+
? now + flutter_runner::kDefaultFlatlandPresentationInterval
19+
: next_presentation_time;
20+
}
21+
22+
} // namespace
23+
1324
FlatlandConnection::FlatlandConnection(
1425
std::string debug_label,
1526
fuchsia::ui::composition::FlatlandHandle flatland,
@@ -54,7 +65,6 @@ void FlatlandConnection::DoPresent() {
5465
--present_credits_;
5566

5667
fuchsia::ui::composition::PresentArgs present_args;
57-
// TODO(fxbug.dev/114588): compute a better presentation time;
5868
present_args.set_requested_presentation_time(0);
5969
present_args.set_acquire_fences(std::move(acquire_fences_));
6070
present_args.set_release_fences(std::move(previous_present_release_fences_));
@@ -85,10 +95,10 @@ void FlatlandConnection::AwaitVsync(FireCallbackCallback callback) {
8595
threadsafe_state_.fire_callback_ = callback;
8696

8797
if (threadsafe_state_.fire_callback_pending_) {
88-
fml::TimePoint now = fml::TimePoint::Now();
89-
// TODO(fxbug.dev/114588): Calculate correct frame times.
98+
const fml::TimePoint now = fml::TimePoint::Now();
9099
threadsafe_state_.fire_callback_(
91-
now, now + kDefaultFlatlandPresentationInterval);
100+
now, GetNextPresentationTime(
101+
now, threadsafe_state_.next_presentation_time_));
92102
threadsafe_state_.fire_callback_ = nullptr;
93103
threadsafe_state_.fire_callback_pending_ = false;
94104
}
@@ -97,8 +107,10 @@ void FlatlandConnection::AwaitVsync(FireCallbackCallback callback) {
97107
// This method is called from the UI thread.
98108
void FlatlandConnection::AwaitVsyncForSecondaryCallback(
99109
FireCallbackCallback callback) {
100-
fml::TimePoint now = fml::TimePoint::Now();
101-
callback(now, now);
110+
const fml::TimePoint now = fml::TimePoint::Now();
111+
std::scoped_lock<std::mutex> lock(threadsafe_state_.mutex_);
112+
callback(now, GetNextPresentationTime(
113+
now, threadsafe_state_.next_presentation_time_));
102114
}
103115

104116
void FlatlandConnection::OnError(
@@ -118,15 +130,21 @@ void FlatlandConnection::OnNextFrameBegin(
118130
}
119131

120132
if (present_credits_ > 0) {
133+
FML_CHECK(values.has_future_presentation_infos() &&
134+
!values.future_presentation_infos().empty());
135+
const auto next_presentation_time =
136+
fml::TimePoint::FromEpochDelta(fml::TimeDelta::FromNanoseconds(
137+
values.future_presentation_infos().front().presentation_time()));
138+
121139
std::scoped_lock<std::mutex> lock(threadsafe_state_.mutex_);
122140
if (threadsafe_state_.fire_callback_) {
123-
fml::TimePoint now = fml::TimePoint::Now();
124-
// TODO(fxbug.dev/114588): Calculate correct frame times.
125141
threadsafe_state_.fire_callback_(
126-
now, now + kDefaultFlatlandPresentationInterval);
142+
/*frame_start=*/fml::TimePoint::Now(),
143+
/*frame_target=*/next_presentation_time);
127144
threadsafe_state_.fire_callback_ = nullptr;
128145
} else {
129146
threadsafe_state_.fire_callback_pending_ = true;
147+
threadsafe_state_.next_presentation_time_ = next_presentation_time;
130148
}
131149
}
132150
}

shell/platform/fuchsia/flutter/flatland_connection.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "flutter/fml/closure.h"
1111
#include "flutter/fml/macros.h"
1212
#include "flutter/fml/time/time_delta.h"
13+
#include "flutter/fml/time/time_point.h"
1314

1415
#include "vsync_waiter.h"
1516

@@ -22,9 +23,10 @@ namespace flutter_runner {
2223
using on_frame_presented_event =
2324
std::function<void(fuchsia::scenic::scheduling::FramePresentedInfo)>;
2425

25-
// Set to zero for now for maximum simplicity until we have real values.
26+
// 2ms interval to target vsync is only used until Scenic sends presentation
27+
// feedback, or when we run out of present credits.
2628
static constexpr fml::TimeDelta kDefaultFlatlandPresentationInterval =
27-
fml::TimeDelta::FromSecondsF(0);
29+
fml::TimeDelta::FromMilliseconds(2);
2830

2931
// The component residing on the raster thread that is responsible for
3032
// maintaining the Flatland instance connection and presenting updates.
@@ -87,6 +89,7 @@ class FlatlandConnection final {
8789
FireCallbackCallback fire_callback_;
8890
bool fire_callback_pending_ = false;
8991
bool first_present_called_ = false;
92+
fml::TimePoint next_presentation_time_;
9093
} threadsafe_state_;
9194

9295
std::vector<zx::event> acquire_fences_;

shell/platform/fuchsia/flutter/tests/flatland_connection_unittests.cc

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ void AwaitVsyncChecked(FlatlandConnection& flatland_connection,
4040
});
4141
}
4242

43+
void AwaitVsyncChecked(FlatlandConnection& flatland_connection,
44+
bool& condition_variable,
45+
fml::TimePoint expected_frame_end) {
46+
flatland_connection.AwaitVsync(
47+
[&condition_variable, expected_frame_end = std::move(expected_frame_end)](
48+
fml::TimePoint frame_start, fml::TimePoint frame_end) {
49+
EXPECT_EQ(frame_end, expected_frame_end);
50+
condition_variable = true;
51+
});
52+
}
53+
54+
std::vector<fuchsia::scenic::scheduling::PresentationInfo>
55+
CreateFuturePresentationInfos(int presentation_time) {
56+
fuchsia::scenic::scheduling::PresentationInfo info_1;
57+
info_1.set_presentation_time(presentation_time);
58+
std::vector<fuchsia::scenic::scheduling::PresentationInfo> infos;
59+
infos.push_back(std::move(info_1));
60+
return infos;
61+
}
62+
4363
} // namespace
4464

4565
class FlatlandConnectionTest : public ::testing::Test {
@@ -61,10 +81,12 @@ class FlatlandConnectionTest : public ::testing::Test {
6181
}
6282

6383
// Syntactic sugar for OnNextFrameBegin
64-
void OnNextFrameBegin(int num_present_credits) {
84+
void OnNextFrameBegin(int num_present_credits, int presentation_time = 345) {
6585
fuchsia::ui::composition::OnNextFrameBeginValues on_next_frame_begin_values;
6686
on_next_frame_begin_values.set_additional_present_credits(
6787
num_present_credits);
88+
on_next_frame_begin_values.set_future_presentation_infos(
89+
CreateFuturePresentationInfos(presentation_time));
6890
fake_flatland().FireOnNextFrameBeginEvent(
6991
std::move(on_next_frame_begin_values));
7092
}
@@ -171,10 +193,14 @@ TEST_F(FlatlandConnectionTest, BasicPresent) {
171193
EXPECT_FALSE(await_vsync_fired);
172194

173195
// Fire the `OnNextFrameBegin` event. AwaitVsync should be fired.
196+
const int kPresentationTime = 123;
174197
AwaitVsyncChecked(flatland_connection, await_vsync_fired,
175-
kDefaultFlatlandPresentationInterval);
198+
fml::TimePoint::FromEpochDelta(
199+
fml::TimeDelta::FromNanoseconds(kPresentationTime)));
176200
fuchsia::ui::composition::OnNextFrameBeginValues on_next_frame_begin_values;
177201
on_next_frame_begin_values.set_additional_present_credits(3);
202+
on_next_frame_begin_values.set_future_presentation_infos(
203+
CreateFuturePresentationInfos(kPresentationTime));
178204
fake_flatland().FireOnNextFrameBeginEvent(
179205
std::move(on_next_frame_begin_values));
180206
loop().RunUntilIdle();
@@ -275,24 +301,29 @@ TEST_F(FlatlandConnectionTest, OutOfOrderAwait) {
275301

276302
// Set the callback with AwaitVsync, callback should not be fired
277303
await_vsync_callback_fired = false;
304+
const int kPresentationTime1 = 567;
278305
AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
279-
kDefaultFlatlandPresentationInterval);
306+
fml::TimePoint::FromEpochDelta(
307+
fml::TimeDelta::FromNanoseconds(kPresentationTime1)));
280308
EXPECT_FALSE(await_vsync_callback_fired);
281309

282-
// Fire the `OnNextFrameBegin` event. AwaitVsync callback should be fired.
310+
// Fire the `OnNextFrameBegin` event. AwaitVsync callback should be fired with
311+
// the given presentation time.
283312
await_vsync_callback_fired = false;
284-
OnNextFrameBegin(1);
313+
OnNextFrameBegin(1, kPresentationTime1);
285314
loop().RunUntilIdle();
286315
EXPECT_TRUE(await_vsync_callback_fired);
287316

288317
// Second consecutive ONFB should not call the fire callback and should
289318
// instead set it to be pending to fire on next AwaitVsync
290319
await_vsync_callback_fired = false;
291-
OnNextFrameBegin(1);
320+
const int kPresentationTime2 = 678;
321+
OnNextFrameBegin(1, kPresentationTime2);
292322
loop().RunUntilIdle();
293323
EXPECT_FALSE(await_vsync_callback_fired);
294324

295-
// Now an AwaitVsync should immediately fire the pending callback
325+
// Now an AwaitVsync should immediately fire the pending callback with the
326+
// default presentation interval.
296327
await_vsync_callback_fired = false;
297328
AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
298329
kDefaultFlatlandPresentationInterval);
@@ -301,13 +332,15 @@ TEST_F(FlatlandConnectionTest, OutOfOrderAwait) {
301332
// With the pending callback fired, The new callback should be set for the
302333
// next OnNextFrameBegin to call
303334
await_vsync_callback_fired = false;
335+
const int kPresentationTime3 = 789;
304336
AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
305-
kDefaultFlatlandPresentationInterval);
337+
fml::TimePoint::FromEpochDelta(
338+
fml::TimeDelta::FromNanoseconds(kPresentationTime3)));
306339
EXPECT_FALSE(await_vsync_callback_fired);
307340

308341
// Now OnNextFrameBegin should fire the callback
309342
await_vsync_callback_fired = false;
310-
OnNextFrameBegin(1);
343+
OnNextFrameBegin(1, kPresentationTime3);
311344
loop().RunUntilIdle();
312345
EXPECT_TRUE(await_vsync_callback_fired);
313346
}

shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,12 @@ Matcher<std::shared_ptr<FakeTransform>> IsClipTransformLayer(
300300
fuchsia::ui::composition::OnNextFrameBeginValues WithPresentCredits(
301301
uint32_t additional_present_credits) {
302302
fuchsia::ui::composition::OnNextFrameBeginValues values;
303-
304303
values.set_additional_present_credits(additional_present_credits);
304+
fuchsia::scenic::scheduling::PresentationInfo info_1;
305+
info_1.set_presentation_time(123);
306+
std::vector<fuchsia::scenic::scheduling::PresentationInfo> infos;
307+
infos.push_back(std::move(info_1));
308+
values.set_future_presentation_infos(std::move(infos));
305309
return values;
306310
}
307311

0 commit comments

Comments
 (0)