Flutter Engine
 
Loading...
Searching...
No Matches
frame_timings.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
6
7#include <memory>
8#include <string>
9
11#include "flutter/fml/logging.h"
13
14namespace flutter {
15
16namespace {
17
18const char* StateToString(FrameTimingsRecorder::State state) {
19#ifndef NDEBUG
20 switch (state) {
22 return "kUninitialized";
24 return "kVsync";
26 return "kBuildStart";
28 return "kBuildEnd";
30 return "kRasterStart";
32 return "kRasterEnd";
33 };
35#endif
36 return "";
37}
38
39} // namespace
40
41std::atomic<uint64_t> FrameTimingsRecorder::frame_number_gen_ = {1};
42
44 : frame_number_(frame_number_gen_++),
45 frame_number_trace_arg_val_(std::to_string(frame_number_)) {}
46
48 : frame_number_(frame_number),
49 frame_number_trace_arg_val_(std::to_string(frame_number_)) {}
50
52
54 std::scoped_lock state_lock(state_mutex_);
55 FML_DCHECK(state_ >= State::kVsync);
56 return vsync_start_;
57}
58
60 std::scoped_lock state_lock(state_mutex_);
61 FML_DCHECK(state_ >= State::kVsync);
62 return vsync_target_;
63}
64
66 std::scoped_lock state_lock(state_mutex_);
68 return build_start_;
69}
70
72 std::scoped_lock state_lock(state_mutex_);
74 return build_end_;
75}
76
78 std::scoped_lock state_lock(state_mutex_);
80 return raster_start_;
81}
82
84 std::scoped_lock state_lock(state_mutex_);
86 return raster_end_;
87}
88
90 std::scoped_lock state_lock(state_mutex_);
92 return raster_end_wall_time_;
93}
94
96 std::scoped_lock state_lock(state_mutex_);
98 return build_end_ - build_start_;
99}
100
101/// Count of the layer cache entries
103 std::scoped_lock state_lock(state_mutex_);
104 FML_DCHECK(state_ >= State::kRasterEnd);
105 return layer_cache_count_;
106}
107
108/// Total bytes in all layer cache entries
110 std::scoped_lock state_lock(state_mutex_);
111 FML_DCHECK(state_ >= State::kRasterEnd);
112 return layer_cache_bytes_;
113}
114
115/// Count of the picture cache entries
117 std::scoped_lock state_lock(state_mutex_);
118 FML_DCHECK(state_ >= State::kRasterEnd);
119 return picture_cache_count_;
120}
121
122/// Total bytes in all picture cache entries
124 std::scoped_lock state_lock(state_mutex_);
125 FML_DCHECK(state_ >= State::kRasterEnd);
126 return picture_cache_bytes_;
127}
128
130 fml::TimePoint vsync_target) {
131 fml::Status status = RecordVsyncImpl(vsync_start, vsync_target);
132 FML_DCHECK(status.ok());
133 (void)status;
134}
135
137 fml::Status status = RecordBuildStartImpl(build_start);
138 FML_DCHECK(status.ok());
139 (void)status;
140}
141
143 fml::Status status = RecordBuildEndImpl(build_end);
144 FML_DCHECK(status.ok());
145 (void)status;
146}
147
149 fml::Status status = RecordRasterStartImpl(raster_start);
150 FML_DCHECK(status.ok());
151 (void)status;
152}
153
154fml::Status FrameTimingsRecorder::RecordVsyncImpl(fml::TimePoint vsync_start,
155 fml::TimePoint vsync_target) {
156 std::scoped_lock state_lock(state_mutex_);
157 if (state_ != State::kUninitialized) {
159 "Check failed: state_ == State::kUninitialized.");
160 }
161 state_ = State::kVsync;
162 vsync_start_ = vsync_start;
163 vsync_target_ = vsync_target;
164 return fml::Status();
165}
166
167fml::Status FrameTimingsRecorder::RecordBuildStartImpl(
168 fml::TimePoint build_start) {
169 std::scoped_lock state_lock(state_mutex_);
170 if (state_ != State::kVsync) {
172 "Check failed: state_ == State::kVsync.");
173 }
174 state_ = State::kBuildStart;
175 build_start_ = build_start;
176 return fml::Status();
177}
178
179fml::Status FrameTimingsRecorder::RecordBuildEndImpl(fml::TimePoint build_end) {
180 std::scoped_lock state_lock(state_mutex_);
181 if (state_ != State::kBuildStart) {
183 "Check failed: state_ == State::kBuildStart.");
184 }
185 state_ = State::kBuildEnd;
186 build_end_ = build_end;
187 return fml::Status();
188}
189
190fml::Status FrameTimingsRecorder::RecordRasterStartImpl(
191 fml::TimePoint raster_start) {
192 std::scoped_lock state_lock(state_mutex_);
193 if (state_ != State::kBuildEnd) {
195 "Check failed: state_ == State::kBuildEnd.");
196 }
197 state_ = State::kRasterStart;
198 raster_start_ = raster_start;
199 return fml::Status();
200}
201
203 std::scoped_lock state_lock(state_mutex_);
205 state_ = State::kRasterEnd;
206 raster_end_ = fml::TimePoint::Now();
207 raster_end_wall_time_ = fml::TimePoint::CurrentWallTime();
208 if (cache) {
209#if !SLIMPELLER
210 const RasterCacheMetrics& layer_metrics = cache->layer_metrics();
211 const RasterCacheMetrics& picture_metrics = cache->picture_metrics();
212 layer_cache_count_ = layer_metrics.total_count();
213 layer_cache_bytes_ = layer_metrics.total_bytes();
214 picture_cache_count_ = picture_metrics.total_count();
215 picture_cache_bytes_ = picture_metrics.total_bytes();
216#endif // !SLIMPELLER
217 } else {
218 layer_cache_count_ = layer_cache_bytes_ = picture_cache_count_ =
219 picture_cache_bytes_ = 0;
220 }
221 timing_.Set(FrameTiming::kVsyncStart, vsync_start_);
222 timing_.Set(FrameTiming::kBuildStart, build_start_);
223 timing_.Set(FrameTiming::kBuildFinish, build_end_);
224 timing_.Set(FrameTiming::kRasterStart, raster_start_);
225 timing_.Set(FrameTiming::kRasterFinish, raster_end_);
226 timing_.Set(FrameTiming::kRasterFinishWallTime, raster_end_wall_time_);
228 timing_.SetRasterCacheStatistics(layer_cache_count_, layer_cache_bytes_,
229 picture_cache_count_, picture_cache_bytes_);
230 return timing_;
231}
232
234 std::scoped_lock state_lock(state_mutex_);
235 FML_DCHECK(state_ == State::kRasterEnd);
236 return timing_;
237}
238
239std::unique_ptr<FrameTimingsRecorder> FrameTimingsRecorder::CloneUntil(
240 State state) {
241 std::scoped_lock state_lock(state_mutex_);
242 std::unique_ptr<FrameTimingsRecorder> recorder =
243 std::make_unique<FrameTimingsRecorder>(frame_number_);
244 FML_DCHECK(state_ >= state);
245 recorder->state_ = state;
246
247 if (state >= State::kVsync) {
248 recorder->vsync_start_ = vsync_start_;
249 recorder->vsync_target_ = vsync_target_;
250 }
251
252 if (state >= State::kBuildStart) {
253 recorder->build_start_ = build_start_;
254 }
255
256 if (state >= State::kBuildEnd) {
257 recorder->build_end_ = build_end_;
258 }
259
260 if (state >= State::kRasterStart) {
261 recorder->raster_start_ = raster_start_;
262 }
263
264 if (state >= State::kRasterEnd) {
265 recorder->raster_end_ = raster_end_;
266 recorder->raster_end_wall_time_ = raster_end_wall_time_;
267 recorder->layer_cache_count_ = layer_cache_count_;
268 recorder->layer_cache_bytes_ = layer_cache_bytes_;
269 recorder->picture_cache_count_ = picture_cache_count_;
270 recorder->picture_cache_bytes_ = picture_cache_bytes_;
271 }
272
273 return recorder;
274}
275
277 return frame_number_;
278}
279
281 return frame_number_trace_arg_val_.c_str();
282}
283
285 FML_DCHECK(state_ == state) << "Expected state " << StateToString(state)
286 << ", actual state " << StateToString(state_);
287}
288
289} // namespace flutter
void SetFrameNumber(uint64_t frame_number)
Definition settings.h:49
fml::TimePoint Set(Phase phase, fml::TimePoint value)
Definition settings.h:44
void SetRasterCacheStatistics(size_t layer_cache_count, size_t layer_cache_bytes, size_t picture_cache_count, size_t picture_cache_bytes)
Definition settings.h:54
void RecordBuildStart(fml::TimePoint build_start)
Records a build start event.
FrameTiming RecordRasterEnd(const RasterCache *cache=nullptr)
fml::TimePoint GetVsyncStartTime() const
Timestamp of the vsync signal.
fml::TimePoint GetBuildEndTime() const
Timestamp of when the frame was finished building.
fml::TimePoint GetRasterEndTime() const
Timestamp of when the frame rasterization finished.
void RecordRasterStart(fml::TimePoint raster_start)
Records a raster start event.
std::unique_ptr< FrameTimingsRecorder > CloneUntil(State state)
Clones the recorder until (and including) the specified state.
void AssertInState(State state) const
size_t GetPictureCacheCount() const
Count of the picture cache entries.
fml::TimePoint GetRasterEndWallTime() const
Timestamp of when the frame rasterization is complete in wall-time.
size_t GetLayerCacheBytes() const
Total Bytes in all layer cache entries.
void RecordVsync(fml::TimePoint vsync_start, fml::TimePoint vsync_target)
Records a vsync event.
fml::TimePoint GetVsyncTargetTime() const
size_t GetPictureCacheBytes() const
Total Bytes in all picture cache entries.
size_t GetLayerCacheCount() const
Count of the layer cache entries.
void RecordBuildEnd(fml::TimePoint build_end)
Records a build end event.
FrameTimingsRecorder()
Default constructor, initializes the recorder with State::kUninitialized.
fml::TimePoint GetBuildStartTime() const
Timestamp of when the frame building started.
const char * GetFrameNumberTraceArg() const
Returns the frame number in a fml tracing friendly format.
fml::TimePoint GetRasterStartTime() const
Timestamp of when the frame rasterization started.
FrameTiming GetRecordedTime() const
Returns the recorded time from when RecordRasterEnd is called.
fml::TimeDelta GetBuildDuration() const
Duration of the frame build time.
const RasterCacheMetrics & picture_metrics() const
const RasterCacheMetrics & layer_metrics() const
bool ok() const
Definition status.h:71
static TimePoint CurrentWallTime()
Definition time_point.cc:57
static TimePoint Now()
Definition time_point.cc:49
#define FML_UNREACHABLE()
Definition logging.h:128
#define FML_DCHECK(condition)
Definition logging.h:122
Definition ref_ptr.h:261