Flutter Engine
 
Loading...
Searching...
No Matches
frame_timings_recorder_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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
5#include <format>
6#include <thread>
7
12
15
16#include "gtest/gtest.h"
17
18namespace flutter {
19
20using testing::MockRasterCache;
21
22TEST(FrameTimingsRecorderTest, RecordVsync) {
23 auto recorder = std::make_unique<FrameTimingsRecorder>();
24 const auto st = fml::TimePoint::Now();
25 const auto en = st + fml::TimeDelta::FromMillisecondsF(16);
26 recorder->RecordVsync(st, en);
27
28 ASSERT_EQ(st, recorder->GetVsyncStartTime());
29 ASSERT_EQ(en, recorder->GetVsyncTargetTime());
30}
31
32TEST(FrameTimingsRecorderTest, RecordBuildTimes) {
33 auto recorder = std::make_unique<FrameTimingsRecorder>();
34
35 const auto st = fml::TimePoint::Now();
36 const auto en = st + fml::TimeDelta::FromMillisecondsF(16);
37 recorder->RecordVsync(st, en);
38
39 const auto build_start = fml::TimePoint::Now();
40 const auto build_end = build_start + fml::TimeDelta::FromMillisecondsF(16);
41 recorder->RecordBuildStart(build_start);
42 recorder->RecordBuildEnd(build_end);
43
44 ASSERT_EQ(build_start, recorder->GetBuildStartTime());
45 ASSERT_EQ(build_end, recorder->GetBuildEndTime());
46}
47
48TEST(FrameTimingsRecorderTest, RecordRasterTimes) {
49 auto recorder = std::make_unique<FrameTimingsRecorder>();
50
51 const auto st = fml::TimePoint::Now();
52 const auto en = st + fml::TimeDelta::FromMillisecondsF(16);
53 recorder->RecordVsync(st, en);
54
55 const auto build_start = fml::TimePoint::Now();
56 const auto build_end = build_start + fml::TimeDelta::FromMillisecondsF(16);
57 recorder->RecordBuildStart(build_start);
58 recorder->RecordBuildEnd(build_end);
59
60 using namespace std::chrono_literals;
61
62 const auto raster_start = fml::TimePoint::Now();
63 recorder->RecordRasterStart(raster_start);
64 const auto before_raster_end_wall_time = fml::TimePoint::CurrentWallTime();
65 std::this_thread::sleep_for(1ms);
66 const auto timing = recorder->RecordRasterEnd();
67 std::this_thread::sleep_for(1ms);
68 const auto after_raster_end_wall_time = fml::TimePoint::CurrentWallTime();
69
70 ASSERT_EQ(raster_start, recorder->GetRasterStartTime());
71 ASSERT_GT(recorder->GetRasterEndWallTime(), before_raster_end_wall_time);
72 ASSERT_LT(recorder->GetRasterEndWallTime(), after_raster_end_wall_time);
73 ASSERT_EQ(recorder->GetFrameNumber(), timing.GetFrameNumber());
74 ASSERT_EQ(recorder->GetLayerCacheCount(), 0u);
75 ASSERT_EQ(recorder->GetLayerCacheBytes(), 0u);
76 ASSERT_EQ(recorder->GetPictureCacheCount(), 0u);
77 ASSERT_EQ(recorder->GetPictureCacheBytes(), 0u);
78}
79
80TEST(FrameTimingsRecorderTest, RecordRasterTimesWithCache) {
81 auto recorder = std::make_unique<FrameTimingsRecorder>();
82
83 const auto st = fml::TimePoint::Now();
84 const auto en = st + fml::TimeDelta::FromMillisecondsF(16);
85 recorder->RecordVsync(st, en);
86
87 const auto build_start = fml::TimePoint::Now();
88 const auto build_end = build_start + fml::TimeDelta::FromMillisecondsF(16);
89 recorder->RecordBuildStart(build_start);
90 recorder->RecordBuildEnd(build_end);
91
92 using namespace std::chrono_literals;
93
94 MockRasterCache cache(1, 10);
95 cache.BeginFrame();
96
97 const auto raster_start = fml::TimePoint::Now();
98 recorder->RecordRasterStart(raster_start);
99
100 cache.AddMockLayer(100, 100);
101 size_t layer_bytes = cache.EstimateLayerCacheByteSize();
102 EXPECT_GT(layer_bytes, 0u);
103 cache.AddMockPicture(100, 100);
104 size_t picture_bytes = cache.EstimatePictureCacheByteSize();
105 EXPECT_GT(picture_bytes, 0u);
107
108 cache.EndFrame();
109
110 const auto before_raster_end_wall_time = fml::TimePoint::CurrentWallTime();
111 std::this_thread::sleep_for(1ms);
112 const auto timing = recorder->RecordRasterEnd(&cache);
113 std::this_thread::sleep_for(1ms);
114 const auto after_raster_end_wall_time = fml::TimePoint::CurrentWallTime();
115
116 ASSERT_EQ(raster_start, recorder->GetRasterStartTime());
117 ASSERT_GT(recorder->GetRasterEndWallTime(), before_raster_end_wall_time);
118 ASSERT_LT(recorder->GetRasterEndWallTime(), after_raster_end_wall_time);
119 ASSERT_EQ(recorder->GetFrameNumber(), timing.GetFrameNumber());
120 ASSERT_EQ(recorder->GetLayerCacheCount(), 1u);
121 ASSERT_EQ(recorder->GetLayerCacheBytes(), layer_bytes);
122 ASSERT_EQ(recorder->GetPictureCacheCount(), 1u);
123 ASSERT_EQ(recorder->GetPictureCacheBytes(), picture_bytes);
124}
125
126// Windows and Fuchsia don't allow testing with killed by signal.
127#if !defined(OS_FUCHSIA) && !defined(FML_OS_WIN) && \
128 (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
129
130TEST(FrameTimingsRecorderTest, ThrowWhenRecordBuildBeforeVsync) {
131 auto recorder = std::make_unique<FrameTimingsRecorder>();
132
133 const auto build_start = fml::TimePoint::Now();
134 fml::Status status = recorder->RecordBuildStartImpl(build_start);
135 EXPECT_FALSE(status.ok());
136 EXPECT_EQ(status.message(), "Check failed: state_ == State::kVsync.");
137}
138
139TEST(FrameTimingsRecorderTest, ThrowWhenRecordRasterBeforeBuildEnd) {
140 auto recorder = std::make_unique<FrameTimingsRecorder>();
141
142 const auto st = fml::TimePoint::Now();
143 const auto en = st + fml::TimeDelta::FromMillisecondsF(16);
144 recorder->RecordVsync(st, en);
145
146 const auto raster_start = fml::TimePoint::Now();
147 fml::Status status = recorder->RecordRasterStartImpl(raster_start);
148 EXPECT_FALSE(status.ok());
149 EXPECT_EQ(status.message(), "Check failed: state_ == State::kBuildEnd.");
150}
151
152#endif
153
154TEST(FrameTimingsRecorderTest, RecordersHaveUniqueFrameNumbers) {
155 auto recorder1 = std::make_unique<FrameTimingsRecorder>();
156 auto recorder2 = std::make_unique<FrameTimingsRecorder>();
157
158 ASSERT_TRUE(recorder2->GetFrameNumber() > recorder1->GetFrameNumber());
159}
160
161TEST(FrameTimingsRecorderTest, ClonedHasSameFrameNumber) {
162 auto recorder = std::make_unique<FrameTimingsRecorder>();
163
164 auto cloned =
166 ASSERT_EQ(recorder->GetFrameNumber(), cloned->GetFrameNumber());
167}
168
169TEST(FrameTimingsRecorderTest, ClonedHasSameVsyncStartAndTarget) {
170 auto recorder = std::make_unique<FrameTimingsRecorder>();
171
172 const auto now = fml::TimePoint::Now();
173 recorder->RecordVsync(now, now + fml::TimeDelta::FromMilliseconds(16));
174
175 auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kVsync);
176 ASSERT_EQ(recorder->GetFrameNumber(), cloned->GetFrameNumber());
177 ASSERT_EQ(recorder->GetVsyncStartTime(), cloned->GetVsyncStartTime());
178 ASSERT_EQ(recorder->GetVsyncTargetTime(), cloned->GetVsyncTargetTime());
179}
180
181TEST(FrameTimingsRecorderTest, ClonedHasSameBuildStart) {
182 auto recorder = std::make_unique<FrameTimingsRecorder>();
183
184 const auto now = fml::TimePoint::Now();
185 recorder->RecordVsync(now, now + fml::TimeDelta::FromMilliseconds(16));
186 recorder->RecordBuildStart(fml::TimePoint::Now());
187
188 auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kBuildStart);
189 ASSERT_EQ(recorder->GetFrameNumber(), cloned->GetFrameNumber());
190 ASSERT_EQ(recorder->GetVsyncStartTime(), cloned->GetVsyncStartTime());
191 ASSERT_EQ(recorder->GetVsyncTargetTime(), cloned->GetVsyncTargetTime());
192 ASSERT_EQ(recorder->GetBuildStartTime(), cloned->GetBuildStartTime());
193}
194
195TEST(FrameTimingsRecorderTest, ClonedHasSameBuildEnd) {
196 auto recorder = std::make_unique<FrameTimingsRecorder>();
197
198 const auto now = fml::TimePoint::Now();
199 recorder->RecordVsync(now, now + fml::TimeDelta::FromMilliseconds(16));
200 recorder->RecordBuildStart(fml::TimePoint::Now());
201 recorder->RecordBuildEnd(fml::TimePoint::Now());
202
203 auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kBuildEnd);
204 ASSERT_EQ(recorder->GetFrameNumber(), cloned->GetFrameNumber());
205 ASSERT_EQ(recorder->GetVsyncStartTime(), cloned->GetVsyncStartTime());
206 ASSERT_EQ(recorder->GetVsyncTargetTime(), cloned->GetVsyncTargetTime());
207 ASSERT_EQ(recorder->GetBuildStartTime(), cloned->GetBuildStartTime());
208 ASSERT_EQ(recorder->GetBuildEndTime(), cloned->GetBuildEndTime());
209}
210
211TEST(FrameTimingsRecorderTest, ClonedHasSameRasterStart) {
212 auto recorder = std::make_unique<FrameTimingsRecorder>();
213
214 const auto now = fml::TimePoint::Now();
215 recorder->RecordVsync(now, now + fml::TimeDelta::FromMilliseconds(16));
216 recorder->RecordBuildStart(fml::TimePoint::Now());
217 recorder->RecordBuildEnd(fml::TimePoint::Now());
218 recorder->RecordRasterStart(fml::TimePoint::Now());
219
220 auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kRasterStart);
221 ASSERT_EQ(recorder->GetFrameNumber(), cloned->GetFrameNumber());
222 ASSERT_EQ(recorder->GetVsyncStartTime(), cloned->GetVsyncStartTime());
223 ASSERT_EQ(recorder->GetVsyncTargetTime(), cloned->GetVsyncTargetTime());
224 ASSERT_EQ(recorder->GetBuildStartTime(), cloned->GetBuildStartTime());
225 ASSERT_EQ(recorder->GetBuildEndTime(), cloned->GetBuildEndTime());
226 ASSERT_EQ(recorder->GetRasterStartTime(), cloned->GetRasterStartTime());
227}
228
229TEST(FrameTimingsRecorderTest, ClonedHasSameRasterEnd) {
230 auto recorder = std::make_unique<FrameTimingsRecorder>();
231
232 const auto now = fml::TimePoint::Now();
233 recorder->RecordVsync(now, now + fml::TimeDelta::FromMilliseconds(16));
234 recorder->RecordBuildStart(fml::TimePoint::Now());
235 recorder->RecordBuildEnd(fml::TimePoint::Now());
236 recorder->RecordRasterStart(fml::TimePoint::Now());
237 recorder->RecordRasterEnd();
238
239 auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kRasterEnd);
240 ASSERT_EQ(recorder->GetFrameNumber(), cloned->GetFrameNumber());
241 ASSERT_EQ(recorder->GetVsyncStartTime(), cloned->GetVsyncStartTime());
242 ASSERT_EQ(recorder->GetVsyncTargetTime(), cloned->GetVsyncTargetTime());
243 ASSERT_EQ(recorder->GetBuildStartTime(), cloned->GetBuildStartTime());
244 ASSERT_EQ(recorder->GetBuildEndTime(), cloned->GetBuildEndTime());
245 ASSERT_EQ(recorder->GetRasterStartTime(), cloned->GetRasterStartTime());
246 ASSERT_EQ(recorder->GetRasterEndTime(), cloned->GetRasterEndTime());
247 ASSERT_EQ(recorder->GetRasterEndWallTime(), cloned->GetRasterEndWallTime());
248 ASSERT_EQ(recorder->GetLayerCacheCount(), cloned->GetLayerCacheCount());
249 ASSERT_EQ(recorder->GetLayerCacheBytes(), cloned->GetLayerCacheBytes());
250 ASSERT_EQ(recorder->GetPictureCacheCount(), cloned->GetPictureCacheCount());
251 ASSERT_EQ(recorder->GetPictureCacheBytes(), cloned->GetPictureCacheBytes());
252}
253
254TEST(FrameTimingsRecorderTest, ClonedHasSameRasterEndWithCache) {
255 auto recorder = std::make_unique<FrameTimingsRecorder>();
256 MockRasterCache cache(1, 10);
257 cache.BeginFrame();
258
259 const auto now = fml::TimePoint::Now();
260 recorder->RecordVsync(now, now + fml::TimeDelta::FromMilliseconds(16));
261 recorder->RecordBuildStart(fml::TimePoint::Now());
262 recorder->RecordBuildEnd(fml::TimePoint::Now());
263 recorder->RecordRasterStart(fml::TimePoint::Now());
264
265 cache.AddMockLayer(100, 100);
266 size_t layer_bytes = cache.EstimateLayerCacheByteSize();
267 EXPECT_GT(layer_bytes, 0u);
268 cache.AddMockPicture(100, 100);
269 size_t picture_bytes = cache.EstimatePictureCacheByteSize();
270 EXPECT_GT(picture_bytes, 0u);
272 cache.EndFrame();
273 recorder->RecordRasterEnd(&cache);
274
275 auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kRasterEnd);
276 ASSERT_EQ(recorder->GetFrameNumber(), cloned->GetFrameNumber());
277 ASSERT_EQ(recorder->GetVsyncStartTime(), cloned->GetVsyncStartTime());
278 ASSERT_EQ(recorder->GetVsyncTargetTime(), cloned->GetVsyncTargetTime());
279 ASSERT_EQ(recorder->GetBuildStartTime(), cloned->GetBuildStartTime());
280 ASSERT_EQ(recorder->GetBuildEndTime(), cloned->GetBuildEndTime());
281 ASSERT_EQ(recorder->GetRasterStartTime(), cloned->GetRasterStartTime());
282 ASSERT_EQ(recorder->GetRasterEndTime(), cloned->GetRasterEndTime());
283 ASSERT_EQ(recorder->GetRasterEndWallTime(), cloned->GetRasterEndWallTime());
284 ASSERT_EQ(recorder->GetLayerCacheCount(), cloned->GetLayerCacheCount());
285 ASSERT_EQ(recorder->GetLayerCacheBytes(), cloned->GetLayerCacheBytes());
286 ASSERT_EQ(recorder->GetPictureCacheCount(), cloned->GetPictureCacheCount());
287 ASSERT_EQ(recorder->GetPictureCacheBytes(), cloned->GetPictureCacheBytes());
288}
289
290TEST(FrameTimingsRecorderTest, FrameNumberTraceArgIsValid) {
291 auto recorder = std::make_unique<FrameTimingsRecorder>();
292
293 std::string actual_arg =
294 std::format("{}", static_cast<int>(recorder->GetFrameNumber()));
295 std::string expected_arg = recorder->GetFrameNumberTraceArg();
296
297 ASSERT_EQ(actual_arg, expected_arg);
298}
299
300} // namespace flutter
size_t EstimatePictureCacheByteSize() const
Estimate how much memory is used by picture raster cache entries in bytes.
size_t EstimateLayerCacheByteSize() const
Estimate how much memory is used by layer raster cache entries in bytes.
A RasterCache implementation that simulates the act of rendering a Layer or DisplayList without the o...
void AddMockLayer(int width, int height)
void AddMockPicture(int width, int height)
bool ok() const
Definition status.h:71
std::string_view message() const
Definition status.h:75
static constexpr TimeDelta FromMillisecondsF(double millis)
Definition time_delta.h:57
static constexpr TimeDelta FromMilliseconds(int64_t millis)
Definition time_delta.h:46
static TimePoint CurrentWallTime()
Definition time_point.cc:57
static TimePoint Now()
Definition time_point.cc:49
TEST(FrameTimingsRecorderTest, RecordVsync)