Skip to content

Commit

Permalink
plumb frame number through to framework (flutter#26233)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahwilliams authored May 19, 2021
1 parent 0a37217 commit 3db3a4c
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 14 deletions.
4 changes: 4 additions & 0 deletions common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ class FrameTiming {
return data_[phase] = value;
}

uint64_t GetFrameNumber() const { return frame_number_; }
void SetFrameNumber(uint64_t frame_number) { frame_number_ = frame_number; }

private:
fml::TimePoint data_[kCount];
uint64_t frame_number_;
};

using TaskObserverAdd =
Expand Down
1 change: 1 addition & 0 deletions flow/frame_timings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ FrameTiming FrameTimingsRecorder::RecordRasterEnd(fml::TimePoint raster_end) {
timing.Set(FrameTiming::kBuildFinish, build_end_);
timing.Set(FrameTiming::kRasterStart, raster_start_);
timing.Set(FrameTiming::kRasterFinish, raster_end_);
timing.SetFrameNumber(GetFrameNumber());
return timing;
}

Expand Down
3 changes: 2 additions & 1 deletion flow/frame_timings_recorder_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ TEST(FrameTimingsRecorderTest, RecordRasterTimes) {
const auto raster_start = fml::TimePoint::Now();
const auto raster_end = raster_start + fml::TimeDelta::FromMillisecondsF(16);
recorder->RecordRasterStart(raster_start);
recorder->RecordRasterEnd(raster_end);
const auto timing = recorder->RecordRasterEnd(raster_end);

ASSERT_EQ(raster_start, recorder->GetRasterStartTime());
ASSERT_EQ(raster_end, recorder->GetRasterEndTime());
ASSERT_EQ(recorder->GetFrameNumber(), timing.GetFrameNumber());
}

// Windows and Fuchsia don't allow testing with killed by signal.
Expand Down
19 changes: 13 additions & 6 deletions lib/ui/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,10 @@ class PlatformDispatcher {

// Called from the engine, via hooks.dart
void _reportTimings(List<int> timings) {
assert(timings.length % FramePhase.values.length == 0);
assert(timings.length % (FramePhase.values.length + 1) == 0);
final List<FrameTiming> frameTimings = <FrameTiming>[];
for (int i = 0; i < timings.length; i += FramePhase.values.length) {
frameTimings.add(FrameTiming._(timings.sublist(i, i + FramePhase.values.length)));
for (int i = 0; i < timings.length; i += FramePhase.values.length + 1) {
frameTimings.add(FrameTiming._(timings.sublist(i, i + FramePhase.values.length + 1)));
}
_invoke1(onReportTimings, _onReportTimingsZone, frameTimings);
}
Expand Down Expand Up @@ -1145,19 +1145,23 @@ class FrameTiming {
///
/// This constructor is used for unit test only. Real [FrameTiming]s should
/// be retrieved from [PlatformDispatcher.onReportTimings].
///
/// If the [frameNumber] is not provided, it defaults to `-1`.
factory FrameTiming({
required int vsyncStart,
required int buildStart,
required int buildFinish,
required int rasterStart,
required int rasterFinish,
int frameNumber = -1,
}) {
return FrameTiming._(<int>[
vsyncStart,
buildStart,
buildFinish,
rasterStart,
rasterFinish
rasterFinish,
frameNumber,
]);
}

Expand All @@ -1169,7 +1173,7 @@ class FrameTiming {
/// This constructor is usually only called by the Flutter engine, or a test.
/// To get the [FrameTiming] of your app, see [PlatformDispatcher.onReportTimings].
FrameTiming._(this._timestamps)
: assert(_timestamps.length == FramePhase.values.length);
: assert(_timestamps.length == FramePhase.values.length + 1);

/// This is a raw timestamp in microseconds from some epoch. The epoch in all
/// [FrameTiming] is the same, but it may not match [DateTime]'s epoch.
Expand Down Expand Up @@ -1214,13 +1218,16 @@ class FrameTiming {
/// See also [vsyncOverhead], [buildDuration] and [rasterDuration].
Duration get totalSpan => _rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.vsyncStart);

/// The frame key associated with this frame measurement.
int get frameNumber => _timestamps.last;

final List<int> _timestamps; // in microseconds

String _formatMS(Duration duration) => '${duration.inMicroseconds * 0.001}ms';

@override
String toString() {
return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, vsyncOverhead: ${_formatMS(vsyncOverhead)}, totalSpan: ${_formatMS(totalSpan)})';
return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, vsyncOverhead: ${_formatMS(vsyncOverhead)}, totalSpan: ${_formatMS(totalSpan)}, frameNumber: ${_timestamps.last})';
}
}

Expand Down
10 changes: 7 additions & 3 deletions lib/web_ui/lib/src/ui/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,20 @@ class FrameTiming {
required int buildFinish,
required int rasterStart,
required int rasterFinish,
int frameNumber = 1,
}) {
return FrameTiming._(<int>[
vsyncStart,
buildStart,
buildFinish,
rasterStart,
rasterFinish
rasterFinish,
frameNumber,
]);
}

FrameTiming._(this._timestamps)
: assert(_timestamps.length == FramePhase.values.length);
: assert(_timestamps.length == FramePhase.values.length + 1);

int timestampInMicroseconds(FramePhase phase) => _timestamps[phase.index];

Expand All @@ -232,13 +234,15 @@ class FrameTiming {
Duration get totalSpan =>
_rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.vsyncStart);

int get frameNumber => _timestamps.last;

final List<int> _timestamps; // in microseconds

String _formatMS(Duration duration) => '${duration.inMicroseconds * 0.001}ms';

@override
String toString() {
return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, vsyncOverhead: ${_formatMS(vsyncOverhead)}, totalSpan: ${_formatMS(totalSpan)})';
return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, vsyncOverhead: ${_formatMS(vsyncOverhead)}, totalSpan: ${_formatMS(totalSpan)}, frameNumber: $frameNumber)';
}
}

Expand Down
5 changes: 3 additions & 2 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1353,8 +1353,8 @@ void Shell::ReportTimings() {
size_t Shell::UnreportedFramesCount() const {
// Check that this is running on the raster thread to avoid race conditions.
FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread());
FML_DCHECK(unreported_timings_.size() % FrameTiming::kCount == 0);
return unreported_timings_.size() / FrameTiming::kCount;
FML_DCHECK(unreported_timings_.size() % (FrameTiming::kCount + 1) == 0);
return unreported_timings_.size() / (FrameTiming::kCount + 1);
}

void Shell::OnFrameRasterized(const FrameTiming& timing) {
Expand All @@ -1375,6 +1375,7 @@ void Shell::OnFrameRasterized(const FrameTiming& timing) {
unreported_timings_.push_back(
timing.Get(phase).ToEpochDelta().ToMicroseconds());
}
unreported_timings_.push_back(timing.GetFrameNumber());

// In tests using iPhone 6S with profile mode, sending a batch of 1 frame or a
// batch of 100 frames have roughly the same cost of less than 0.1ms. Sending
Expand Down
5 changes: 3 additions & 2 deletions testing/dart/window_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ void main() {
buildStart: 1000,
buildFinish: 8000,
rasterStart: 9000,
rasterFinish: 19500
rasterFinish: 19500,
frameNumber: 23,
);
expect(timing.toString(), 'FrameTiming(buildDuration: 7.0ms, rasterDuration: 10.5ms, vsyncOverhead: 0.5ms, totalSpan: 19.0ms)');
expect(timing.toString(), 'FrameTiming(buildDuration: 7.0ms, rasterDuration: 10.5ms, vsyncOverhead: 0.5ms, totalSpan: 19.0ms, frameNumber: 23)');
});

test('computePlatformResolvedLocale basic', () {
Expand Down

0 comments on commit 3db3a4c

Please sign in to comment.