From 01ace70655dbc349c90d293db6ffa76a0c5e78d0 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Thu, 30 Jul 2020 15:19:33 -0400 Subject: [PATCH 1/8] Change frame build time start timestamp --- shell/common/animator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 2237d1ffed3d4..9b8815358b97f 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -133,7 +133,7 @@ void Animator::BeginFrame(fml::TimePoint frame_start_time, // to service potential frame. FML_DCHECK(producer_continuation_); - last_frame_begin_time_ = frame_start_time; + last_frame_begin_time_ = fml::TimePoint::Now(); last_frame_target_time_ = frame_target_time; dart_frame_deadline_ = FxlToDartOrEarlier(frame_target_time); { From 84a11d6603ab2b86038f0b41e4e8c3d1a66b07b6 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Tue, 4 Aug 2020 13:11:15 -0400 Subject: [PATCH 2/8] add vsync start to layer_tree --- common/settings.h | 6 ++++-- flow/layers/layer_tree.cc | 4 +++- flow/layers/layer_tree.h | 8 +++++++- lib/ui/window.dart | 11 ++++++++++- lib/web_ui/lib/src/ui/window.dart | 11 ++++++++++- shell/common/animator.cc | 12 ++++++++---- shell/common/animator.h | 1 + shell/common/rasterizer.cc | 3 ++- 8 files changed, 45 insertions(+), 11 deletions(-) diff --git a/common/settings.h b/common/settings.h index 15166b8d38213..0029f2a973c5a 100644 --- a/common/settings.h +++ b/common/settings.h @@ -22,9 +22,11 @@ namespace flutter { class FrameTiming { public: - enum Phase { kBuildStart, kBuildFinish, kRasterStart, kRasterFinish, kCount }; + enum Phase {kVsyncStart, kBuildStart, kBuildFinish, kRasterStart, + kRasterFinish, kCount }; - static constexpr Phase kPhases[kCount] = {kBuildStart, kBuildFinish, + static constexpr Phase kPhases[kCount] = {kVsyncStart, + kBuildStart, kBuildFinish, kRasterStart, kRasterFinish}; fml::TimePoint Get(Phase phase) const { return data_[phase]; } diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 0f598ae6f153f..121391d69a3ba 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -21,8 +21,10 @@ LayerTree::LayerTree(const SkISize& frame_size, checkerboard_raster_cache_images_(false), checkerboard_offscreen_layers_(false) {} -void LayerTree::RecordBuildTime(fml::TimePoint build_start, +void LayerTree::RecordBuildTime(fml::TimePoint vsync_start, + fml::TimePoint build_start, fml::TimePoint target_time) { + vsync_start_ = vsync_start; build_start_ = build_start; target_time_ = target_time; build_finish_ = fml::TimePoint::Now(); diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 733284afe65db..6d799a7dc962c 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -54,7 +54,12 @@ class LayerTree { float frame_physical_depth() const { return frame_physical_depth_; } float frame_device_pixel_ratio() const { return frame_device_pixel_ratio_; } - void RecordBuildTime(fml::TimePoint build_start, fml::TimePoint target_time); + void RecordBuildTime(fml::TimePoint vsync_start, + fml::TimePoint build_start, + fml::TimePoint target_time); + fml::TimePoint vsync_start() const { return vsync_start_; } + fml::TimeDelta vsync_overhead() const { return build_start_ - vsync_start_; } + fml::TimeDelta vsync_time() const { return build_finish_ - vsync_start_; } fml::TimePoint build_start() const { return build_start_; } fml::TimePoint build_finish() const { return build_finish_; } fml::TimeDelta build_time() const { return build_finish_ - build_start_; } @@ -83,6 +88,7 @@ class LayerTree { private: std::shared_ptr root_layer_; + fml::TimePoint vsync_start_; fml::TimePoint build_start_; fml::TimePoint build_finish_; fml::TimePoint target_time_; diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 90c5603c1552f..ff4fa7701cc24 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -47,6 +47,11 @@ typedef _SetNeedsReportTimingsFunc = void Function(bool value); /// /// [FrameTiming] records a timestamp of each phase for performance analysis. enum FramePhase { + /// When the UI thread receives the vsync signal from the operating system. + /// + /// See also [FrameTiming.vsyncOverhead]. + vsyncStart, + /// When the UI thread starts building a frame. /// /// See also [FrameTiming.buildDuration]. @@ -143,6 +148,10 @@ class FrameTiming { /// {@macro dart.ui.FrameTiming.fps_milliseconds} Duration get rasterDuration => _rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.rasterStart); + /// The duration between receiving the vsync signal and starting building the + /// frame. + Duration get vsyncOverhead => _rawDuration(FramePhase.vsyncStart) - _rawDuration(FramePhase.buildStart); + /// The timespan between build start and raster finish. /// /// To achieve the lowest latency on an X fps display, this should not exceed @@ -150,7 +159,7 @@ class FrameTiming { /// {@macro dart.ui.FrameTiming.fps_milliseconds} /// /// See also [buildDuration] and [rasterDuration]. - Duration get totalSpan => _rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.buildStart); + Duration get totalSpan => _rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.vsyncStart); final List _timestamps; // in microseconds diff --git a/lib/web_ui/lib/src/ui/window.dart b/lib/web_ui/lib/src/ui/window.dart index cbe7465a69fc0..627c315a1ebc7 100644 --- a/lib/web_ui/lib/src/ui/window.dart +++ b/lib/web_ui/lib/src/ui/window.dart @@ -1005,6 +1005,11 @@ class IsolateNameServer { /// /// [FrameTiming] records a timestamp of each phase for performance analysis. enum FramePhase { + /// When the UI thread receives the vsync signal from the operating system. + /// + /// See also [FrameTiming.vsyncOverhead]. + vsyncStart, + /// When the UI thread starts building a frame. /// /// See also [FrameTiming.buildDuration]. @@ -1095,6 +1100,10 @@ class FrameTiming { _rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.rasterStart); + /// The duration between receiving the vsync signal and starting building the + /// frame. + Duration get vsyncOverhead => _rawDuration(FramePhase.vsyncStart) - _rawDuration(FramePhase.buildStart); + /// The timespan between build start and raster finish. /// /// To achieve the lowest latency on an X fps display, this should not exceed @@ -1104,7 +1113,7 @@ class FrameTiming { /// See also [buildDuration] and [rasterDuration]. Duration get totalSpan => _rawDuration(FramePhase.rasterFinish) - - _rawDuration(FramePhase.buildStart); + _rawDuration(FramePhase.vsyncStart); final List _timestamps; // in microseconds diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 9b8815358b97f..2d8007327359d 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -26,6 +26,7 @@ Animator::Animator(Delegate& delegate, task_runners_(std::move(task_runners)), waiter_(std::move(waiter)), last_frame_begin_time_(), + last_vsync_start_time_(), last_frame_target_time_(), dart_frame_deadline_(0), #if FLUTTER_SHELL_ENABLE_METAL @@ -98,7 +99,7 @@ static int64_t FxlToDartOrEarlier(fml::TimePoint time) { return (time - fxl_now).ToMicroseconds() + dart_now; } -void Animator::BeginFrame(fml::TimePoint frame_start_time, +void Animator::BeginFrame(fml::TimePoint vsync_start_time, fml::TimePoint frame_target_time) { TRACE_EVENT_ASYNC_END0("flutter", "Frame Request Pending", frame_number_++); @@ -134,6 +135,7 @@ void Animator::BeginFrame(fml::TimePoint frame_start_time, FML_DCHECK(producer_continuation_); last_frame_begin_time_ = fml::TimePoint::Now(); + last_vsync_start_time_ = vsync_start_time; last_frame_target_time_ = frame_target_time; dart_frame_deadline_ = FxlToDartOrEarlier(frame_target_time); { @@ -179,7 +181,9 @@ void Animator::Render(std::unique_ptr layer_tree) { last_layer_tree_size_ = layer_tree->frame_size(); // Note the frame time for instrumentation. - layer_tree->RecordBuildTime(last_frame_begin_time_, last_frame_target_time_); + layer_tree->RecordBuildTime(last_vsync_start_time_, + last_frame_begin_time_, + last_frame_target_time_); // Commit the pending continuation. bool result = producer_continuation_.Complete(std::move(layer_tree)); @@ -233,13 +237,13 @@ void Animator::RequestFrame(bool regenerate_layer_tree) { void Animator::AwaitVSync() { waiter_->AsyncWaitForVsync( - [self = weak_factory_.GetWeakPtr()](fml::TimePoint frame_start_time, + [self = weak_factory_.GetWeakPtr()](fml::TimePoint vsync_start_time, fml::TimePoint frame_target_time) { if (self) { if (self->CanReuseLastLayerTree()) { self->DrawLastLayerTree(); } else { - self->BeginFrame(frame_start_time, frame_target_time); + self->BeginFrame(vsync_start_time, frame_target_time); } } }); diff --git a/shell/common/animator.h b/shell/common/animator.h index 0bab57730015a..a6508fe24fa1a 100644 --- a/shell/common/animator.h +++ b/shell/common/animator.h @@ -98,6 +98,7 @@ class Animator final { std::shared_ptr waiter_; fml::TimePoint last_frame_begin_time_; + fml::TimePoint last_vsync_start_time_; fml::TimePoint last_frame_target_time_; int64_t dart_frame_deadline_; fml::RefPtr layer_tree_pipeline_; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index d43867876fd87..8eb16a27635bd 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -290,6 +290,7 @@ RasterStatus Rasterizer::DoDraw( #if !defined(OS_FUCHSIA) const fml::TimePoint frame_target_time = layer_tree->target_time(); #endif + timing.Set(FrameTiming::kVsyncStart, layer_tree->vsync_start()); timing.Set(FrameTiming::kBuildStart, layer_tree->build_start()); timing.Set(FrameTiming::kBuildFinish, layer_tree->build_finish()); timing.Set(FrameTiming::kRasterStart, fml::TimePoint::Now()); @@ -382,7 +383,7 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { // There is no way for the compositor to know how long the layer tree // construction took. Fortunately, the layer tree does. Grab that time // for instrumentation. - compositor_context_->ui_time().SetLapTime(layer_tree.build_time()); + compositor_context_->ui_time().SetLapTime(layer_tree.vsync_time()); auto* external_view_embedder = surface_->GetExternalViewEmbedder(); From 0ec79db69cd3181dc30926ab651b4e9c4dd43bf7 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Tue, 4 Aug 2020 13:20:02 -0400 Subject: [PATCH 3/8] add test --- lib/ui/window.dart | 2 +- lib/web_ui/lib/src/ui/window.dart | 2 +- testing/dart/window_test.dart | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ui/window.dart b/lib/ui/window.dart index ff4fa7701cc24..03e53272e2dfc 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -167,7 +167,7 @@ class FrameTiming { @override String toString() { - return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, totalSpan: ${_formatMS(totalSpan)})'; + return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, vsyncOverhead: ${_formatMS(vsyncOverhead)}, totalSpan: ${_formatMS(totalSpan)})'; } } diff --git a/lib/web_ui/lib/src/ui/window.dart b/lib/web_ui/lib/src/ui/window.dart index 627c315a1ebc7..035235478cb3c 100644 --- a/lib/web_ui/lib/src/ui/window.dart +++ b/lib/web_ui/lib/src/ui/window.dart @@ -1121,7 +1121,7 @@ class FrameTiming { @override String toString() { - return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, totalSpan: ${_formatMS(totalSpan)})'; + return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, vsyncOverhead: ${_formatMS(vsyncOverhead)}, totalSpan: ${_formatMS(totalSpan)})'; } } diff --git a/testing/dart/window_test.dart b/testing/dart/window_test.dart index a434482024d69..9c9d59bf0f8e1 100644 --- a/testing/dart/window_test.dart +++ b/testing/dart/window_test.dart @@ -22,8 +22,8 @@ void main() { }); test('FrameTiming.toString has the correct format', () { - final FrameTiming timing = FrameTiming([1000, 8000, 9000, 19500]); - expect(timing.toString(), 'FrameTiming(buildDuration: 7.0ms, rasterDuration: 10.5ms, totalSpan: 18.5ms)'); + final FrameTiming timing = FrameTiming([500, 1000, 8000, 9000, 19500]); + expect(timing.toString(), 'FrameTiming(buildDuration: 6.5ms, rasterDuration: 10.5ms, vsyncOverhead: 0.5ms, totalSpan: 18.5ms)'); }); test('computePlatformResolvedLocale basic', () { From 35d1bd8268f93605fc7a19a0f90d459602c89166 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Tue, 4 Aug 2020 13:28:27 -0400 Subject: [PATCH 4/8] formatting --- common/settings.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/common/settings.h b/common/settings.h index 0029f2a973c5a..1f3bb0ed750df 100644 --- a/common/settings.h +++ b/common/settings.h @@ -22,12 +22,17 @@ namespace flutter { class FrameTiming { public: - enum Phase {kVsyncStart, kBuildStart, kBuildFinish, kRasterStart, - kRasterFinish, kCount }; - - static constexpr Phase kPhases[kCount] = {kVsyncStart, - kBuildStart, kBuildFinish, - kRasterStart, kRasterFinish}; + enum Phase { + kVsyncStart, + kBuildStart, + kBuildFinish, + kRasterStart, + kRasterFinish, + kCount + }; + + static constexpr Phase kPhases[kCount] = { + kVsyncStart, kBuildStart, kBuildFinish, kRasterStart, kRasterFinish}; fml::TimePoint Get(Phase phase) const { return data_[phase]; } fml::TimePoint Set(Phase phase, fml::TimePoint value) { From 87d0982be761ff907f90369075988e8cb05fee31 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Tue, 4 Aug 2020 14:20:24 -0400 Subject: [PATCH 5/8] move tracing --- shell/common/animator.cc | 3 +++ shell/common/vsync_waiter.cc | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 2d8007327359d..fe495b6dbe0f6 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -136,6 +136,9 @@ void Animator::BeginFrame(fml::TimePoint vsync_start_time, last_frame_begin_time_ = fml::TimePoint::Now(); last_vsync_start_time_ = vsync_start_time; + fml::tracing::TraceEventAsyncComplete("flutter", "VsyncSchedulingOverhead", + last_frame_begin_time_, + last_frame_begin_time_); last_frame_target_time_ = frame_target_time; dart_frame_deadline_ = FxlToDartOrEarlier(frame_target_time); { diff --git a/shell/common/vsync_waiter.cc b/shell/common/vsync_waiter.cc index ae86fc547ea3b..7947d42cf6125 100644 --- a/shell/common/vsync_waiter.cc +++ b/shell/common/vsync_waiter.cc @@ -122,9 +122,6 @@ void VsyncWaiter::FireCallback(fml::TimePoint frame_start_time, [callback, flow_identifier, frame_start_time, frame_target_time]() { FML_TRACE_EVENT("flutter", kVsyncTraceName, "StartTime", frame_start_time, "TargetTime", frame_target_time); - fml::tracing::TraceEventAsyncComplete( - "flutter", "VsyncSchedulingOverhead", fml::TimePoint::Now(), - frame_start_time); callback(frame_start_time, frame_target_time); TRACE_FLOW_END("flutter", kVsyncFlowName, flow_identifier); }, From 8c7178cc4a5598807534a3700a18a71f682780d0 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Tue, 4 Aug 2020 15:21:04 -0400 Subject: [PATCH 6/8] remove vsync_time method --- flow/layers/layer_tree.h | 1 - shell/common/rasterizer.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 6d799a7dc962c..0ecd610c9737d 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -59,7 +59,6 @@ class LayerTree { fml::TimePoint target_time); fml::TimePoint vsync_start() const { return vsync_start_; } fml::TimeDelta vsync_overhead() const { return build_start_ - vsync_start_; } - fml::TimeDelta vsync_time() const { return build_finish_ - vsync_start_; } fml::TimePoint build_start() const { return build_start_; } fml::TimePoint build_finish() const { return build_finish_; } fml::TimeDelta build_time() const { return build_finish_ - build_start_; } diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 8eb16a27635bd..c9514c2ac056d 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -383,7 +383,7 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { // There is no way for the compositor to know how long the layer tree // construction took. Fortunately, the layer tree does. Grab that time // for instrumentation. - compositor_context_->ui_time().SetLapTime(layer_tree.vsync_time()); + compositor_context_->ui_time().SetLapTime(layer_tree.build_time()); auto* external_view_embedder = surface_->GetExternalViewEmbedder(); From 3d14526925d82619f71b0f6210e2c03c9e5ad4c0 Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Tue, 4 Aug 2020 18:51:06 -0400 Subject: [PATCH 7/8] bug fix and formatting --- lib/ui/window.dart | 8 ++++---- lib/web_ui/lib/src/ui/window.dart | 8 ++++---- shell/common/animator.cc | 5 ++--- testing/dart/window_test.dart | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 03e53272e2dfc..b11da626bd4bc 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -47,7 +47,7 @@ typedef _SetNeedsReportTimingsFunc = void Function(bool value); /// /// [FrameTiming] records a timestamp of each phase for performance analysis. enum FramePhase { - /// When the UI thread receives the vsync signal from the operating system. + /// The timestamp of the vsync signal given by the operating system. /// /// See also [FrameTiming.vsyncOverhead]. vsyncStart, @@ -150,15 +150,15 @@ class FrameTiming { /// The duration between receiving the vsync signal and starting building the /// frame. - Duration get vsyncOverhead => _rawDuration(FramePhase.vsyncStart) - _rawDuration(FramePhase.buildStart); + Duration get vsyncOverhead => _rawDuration(FramePhase.buildStart) - _rawDuration(FramePhase.vsyncStart); - /// The timespan between build start and raster finish. + /// The timespan between vsync start and raster finish. /// /// To achieve the lowest latency on an X fps display, this should not exceed /// 1000/X milliseconds. /// {@macro dart.ui.FrameTiming.fps_milliseconds} /// - /// See also [buildDuration] and [rasterDuration]. + /// See also [vsyncOverhead], [buildDuration] and [rasterDuration]. Duration get totalSpan => _rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.vsyncStart); final List _timestamps; // in microseconds diff --git a/lib/web_ui/lib/src/ui/window.dart b/lib/web_ui/lib/src/ui/window.dart index 035235478cb3c..12b8e5eb6ac25 100644 --- a/lib/web_ui/lib/src/ui/window.dart +++ b/lib/web_ui/lib/src/ui/window.dart @@ -1005,7 +1005,7 @@ class IsolateNameServer { /// /// [FrameTiming] records a timestamp of each phase for performance analysis. enum FramePhase { - /// When the UI thread receives the vsync signal from the operating system. + /// The timestamp of the vsync signal given by the operating system. /// /// See also [FrameTiming.vsyncOverhead]. vsyncStart, @@ -1102,15 +1102,15 @@ class FrameTiming { /// The duration between receiving the vsync signal and starting building the /// frame. - Duration get vsyncOverhead => _rawDuration(FramePhase.vsyncStart) - _rawDuration(FramePhase.buildStart); + Duration get vsyncOverhead => _rawDuration(FramePhase.buildStart) - _rawDuration(FramePhase.vsyncStart); - /// The timespan between build start and raster finish. + /// The timespan between vsync start and raster finish. /// /// To achieve the lowest latency on an X fps display, this should not exceed /// 1000/X milliseconds. /// {@macro dart.ui.FrameTiming.fps_milliseconds} /// - /// See also [buildDuration] and [rasterDuration]. + /// See also [vsyncOverhead], [buildDuration] and [rasterDuration]. Duration get totalSpan => _rawDuration(FramePhase.rasterFinish) - _rawDuration(FramePhase.vsyncStart); diff --git a/shell/common/animator.cc b/shell/common/animator.cc index fe495b6dbe0f6..3ca1a83788773 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -137,7 +137,7 @@ void Animator::BeginFrame(fml::TimePoint vsync_start_time, last_frame_begin_time_ = fml::TimePoint::Now(); last_vsync_start_time_ = vsync_start_time; fml::tracing::TraceEventAsyncComplete("flutter", "VsyncSchedulingOverhead", - last_frame_begin_time_, + last_vsync_start_time_, last_frame_begin_time_); last_frame_target_time_ = frame_target_time; dart_frame_deadline_ = FxlToDartOrEarlier(frame_target_time); @@ -184,8 +184,7 @@ void Animator::Render(std::unique_ptr layer_tree) { last_layer_tree_size_ = layer_tree->frame_size(); // Note the frame time for instrumentation. - layer_tree->RecordBuildTime(last_vsync_start_time_, - last_frame_begin_time_, + layer_tree->RecordBuildTime(last_vsync_start_time_, last_frame_begin_time_, last_frame_target_time_); // Commit the pending continuation. diff --git a/testing/dart/window_test.dart b/testing/dart/window_test.dart index 9c9d59bf0f8e1..d70bb9cd4dfce 100644 --- a/testing/dart/window_test.dart +++ b/testing/dart/window_test.dart @@ -23,7 +23,7 @@ void main() { test('FrameTiming.toString has the correct format', () { final FrameTiming timing = FrameTiming([500, 1000, 8000, 9000, 19500]); - expect(timing.toString(), 'FrameTiming(buildDuration: 6.5ms, rasterDuration: 10.5ms, vsyncOverhead: 0.5ms, totalSpan: 18.5ms)'); + expect(timing.toString(), 'FrameTiming(buildDuration: 7.0ms, rasterDuration: 10.5ms, vsyncOverhead: 0.5ms, totalSpan: 19.0ms)'); }); test('computePlatformResolvedLocale basic', () { From ecca65eb7068a71576e4c083fc8f118c1338e25b Mon Sep 17 00:00:00 2001 From: "Ming Lyu (CareF)" Date: Thu, 6 Aug 2020 17:57:59 -0400 Subject: [PATCH 8/8] update constructor --- lib/ui/hooks.dart | 2 +- lib/ui/window.dart | 26 +++++++++++++++++++-- lib/web_ui/lib/src/ui/window.dart | 38 +++++++++++++++++++++++++++---- testing/dart/window_test.dart | 8 ++++++- 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index c01095412a606..c2a74aa10c3ec 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -200,7 +200,7 @@ void _reportTimings(List timings) { assert(timings.length % FramePhase.values.length == 0); final List frameTimings = []; for (int i = 0; i < timings.length; i += FramePhase.values.length) { - frameTimings.add(FrameTiming(timings.sublist(i, i + FramePhase.values.length))); + frameTimings.add(FrameTiming._(timings.sublist(i, i + FramePhase.values.length))); } _invoke1(window.onReportTimings, window._onReportTimingsZone, frameTimings); } diff --git a/lib/ui/window.dart b/lib/ui/window.dart index b11da626bd4bc..4bc5e2ec5fe3f 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -87,6 +87,26 @@ enum FramePhase { /// Therefore it's recommended to only monitor and analyze performance metrics /// in profile and release modes. class FrameTiming { + /// Construct [FrameTiming] with raw timestamps in microseconds. + /// + /// This constructor is used for unit test only. Real [FrameTiming]s should + /// be retrieved from [Window.onReportTimings]. + factory FrameTiming({ + required int vsyncStart, + required int buildStart, + required int buildFinish, + required int rasterStart, + required int rasterFinish, + }) { + return FrameTiming._([ + vsyncStart, + buildStart, + buildFinish, + rasterStart, + rasterFinish + ]); + } + /// Construct [FrameTiming] with raw timestamps in microseconds. /// /// List [timestamps] must have the same number of elements as @@ -94,7 +114,7 @@ class FrameTiming { /// /// This constructor is usually only called by the Flutter engine, or a test. /// To get the [FrameTiming] of your app, see [Window.onReportTimings]. - FrameTiming(List timestamps) + FrameTiming._(List timestamps) : assert(timestamps.length == FramePhase.values.length), _timestamps = timestamps; /// Construct [FrameTiming] with given timestamp in micrseconds. @@ -111,7 +131,9 @@ class FrameTiming { required int rasterStart, required int rasterFinish }) { - return FrameTiming([ + return FrameTiming._([ + // This is for temporarily backward compatiblilty. + vsyncStart ?? buildStart, buildStart, buildFinish, rasterStart, diff --git a/lib/web_ui/lib/src/ui/window.dart b/lib/web_ui/lib/src/ui/window.dart index 12b8e5eb6ac25..b90051e637c77 100644 --- a/lib/web_ui/lib/src/ui/window.dart +++ b/lib/web_ui/lib/src/ui/window.dart @@ -1040,6 +1040,26 @@ enum FramePhase { /// Therefore it's recommended to only monitor and analyze performance metrics /// in profile and release modes. class FrameTiming { + /// Construct [FrameTiming] with raw timestamps in microseconds. + /// + /// This constructor is used for unit test only. Real [FrameTiming]s should + /// be retrieved from [Window.onReportTimings]. + factory FrameTiming({ + required int vsyncStart, + required int buildStart, + required int buildFinish, + required int rasterStart, + required int rasterFinish, + }) { + return FrameTiming._([ + vsyncStart, + buildStart, + buildFinish, + rasterStart, + rasterFinish + ]); + } + /// Construct [FrameTiming] with raw timestamps in microseconds. /// /// List [timestamps] must have the same number of elements as @@ -1047,9 +1067,8 @@ class FrameTiming { /// /// This constructor is usually only called by the Flutter engine, or a test. /// To get the [FrameTiming] of your app, see [Window.onReportTimings]. - FrameTiming(List timestamps) - : assert(timestamps.length == FramePhase.values.length), - _timestamps = timestamps; + FrameTiming._(List timestamps) + : assert(timestamps.length == FramePhase.values.length), _timestamps = timestamps; /// Construct [FrameTiming] with given timestamp in micrseconds. /// @@ -1058,13 +1077,22 @@ class FrameTiming { /// /// TODO(CareF): This is part of #20229. Remove back to default constructor /// after #20229 lands and corresponding framwork PRs land. - FrameTiming.fromTimeStamps({ + factory FrameTiming.fromTimeStamps({ int? vsyncStart, required int buildStart, required int buildFinish, required int rasterStart, required int rasterFinish - }) : _timestamps = [buildStart, buildFinish, rasterStart, rasterFinish]; + }) { + return FrameTiming._([ + // This is for temporarily backward compatiblilty. + vsyncStart ?? buildStart, + buildStart, + buildFinish, + rasterStart, + rasterFinish + ]); + } /// 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. diff --git a/testing/dart/window_test.dart b/testing/dart/window_test.dart index d70bb9cd4dfce..79767f881e7bc 100644 --- a/testing/dart/window_test.dart +++ b/testing/dart/window_test.dart @@ -22,7 +22,13 @@ void main() { }); test('FrameTiming.toString has the correct format', () { - final FrameTiming timing = FrameTiming([500, 1000, 8000, 9000, 19500]); + final FrameTiming timing = FrameTiming( + vsyncStart: 500, + buildStart: 1000, + buildFinish: 8000, + rasterStart: 9000, + rasterFinish: 19500 + ); expect(timing.toString(), 'FrameTiming(buildDuration: 7.0ms, rasterDuration: 10.5ms, vsyncOverhead: 0.5ms, totalSpan: 19.0ms)'); });