diff --git a/flow/frame_timings.cc b/flow/frame_timings.cc index 094347cdb945a..0ba314a9e8a59 100644 --- a/flow/frame_timings.cc +++ b/flow/frame_timings.cc @@ -107,14 +107,19 @@ FrameTiming FrameTimingsRecorder::RecordRasterEnd(fml::TimePoint raster_end) { FML_DCHECK(state_ == State::kRasterStart); state_ = State::kRasterEnd; raster_end_ = raster_end; - FrameTiming timing; - timing.Set(FrameTiming::kVsyncStart, vsync_start_); - timing.Set(FrameTiming::kBuildStart, build_start_); - timing.Set(FrameTiming::kBuildFinish, build_end_); - timing.Set(FrameTiming::kRasterStart, raster_start_); - timing.Set(FrameTiming::kRasterFinish, raster_end_); - timing.SetFrameNumber(GetFrameNumber()); - return timing; + timing_.Set(FrameTiming::kVsyncStart, vsync_start_); + timing_.Set(FrameTiming::kBuildStart, build_start_); + timing_.Set(FrameTiming::kBuildFinish, build_end_); + timing_.Set(FrameTiming::kRasterStart, raster_start_); + timing_.Set(FrameTiming::kRasterFinish, raster_end_); + timing_.SetFrameNumber(GetFrameNumber()); + return timing_; +} + +FrameTiming FrameTimingsRecorder::GetRecordedTime() const { + std::scoped_lock state_lock(state_mutex_); + FML_DCHECK(state_ == State::kRasterEnd); + return timing_; } std::unique_ptr FrameTimingsRecorder::CloneUntil( diff --git a/flow/frame_timings.h b/flow/frame_timings.h index 7e271b7cb19df..a2d47fa63be62 100644 --- a/flow/frame_timings.h +++ b/flow/frame_timings.h @@ -94,6 +94,9 @@ class FrameTimingsRecorder { /// Returns the frame number in a fml tracing friendly format. const char* GetFrameNumberTraceArg() const; + /// Returns the recorded time from when `RecordRasterEnd` is called. + FrameTiming GetRecordedTime() const; + private: static std::atomic frame_number_gen_; @@ -110,6 +113,9 @@ class FrameTimingsRecorder { fml::TimePoint raster_start_; fml::TimePoint raster_end_; + // Set when `RecordRasterEnd` is called. Cannot be reset once set. + FrameTiming timing_; + FML_DISALLOW_COPY_ASSIGN_AND_MOVE(FrameTimingsRecorder); }; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 87653a01e85ce..c92fe7fc3d168 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -168,7 +168,8 @@ void Rasterizer::DrawLastLayerTree( if (!last_layer_tree_ || !surface_) { return; } - DrawToSurface(frame_timings_recorder->GetBuildDuration(), *last_layer_tree_); + frame_timings_recorder->RecordRasterStart(fml::TimePoint::Now()); + DrawToSurface(*frame_timings_recorder, *last_layer_tree_); } void Rasterizer::Draw( @@ -377,7 +378,7 @@ RasterStatus Rasterizer::DoDraw( persistent_cache->ResetStoredNewShaders(); RasterStatus raster_status = - DrawToSurface(frame_timings_recorder->GetBuildDuration(), *layer_tree); + DrawToSurface(*frame_timings_recorder, *layer_tree); if (raster_status == RasterStatus::kSuccess) { last_layer_tree_ = std::move(layer_tree); } else if (raster_status == RasterStatus::kResubmit || @@ -396,13 +397,13 @@ RasterStatus Rasterizer::DoDraw( // TODO(liyuqian): in Fuchsia, the rasterization doesn't finish when // Rasterizer::DoDraw finishes. Future work is needed to adapt the timestamp // for Fuchsia to capture SceneUpdateContext::ExecutePaintTasks. - const auto raster_finish_time = fml::TimePoint::Now(); - delegate_.OnFrameRasterized( - frame_timings_recorder->RecordRasterEnd(raster_finish_time)); + delegate_.OnFrameRasterized(frame_timings_recorder->GetRecordedTime()); // SceneDisplayLag events are disabled on Fuchsia. // see: https://github.com/flutter/flutter/issues/56598 #if !defined(OS_FUCHSIA) + const fml::TimePoint raster_finish_time = + frame_timings_recorder->GetRasterEndTime(); fml::TimePoint frame_target_time = frame_timings_recorder->GetVsyncTargetTime(); if (raster_finish_time > frame_target_time) { @@ -459,12 +460,13 @@ RasterStatus Rasterizer::DoDraw( } RasterStatus Rasterizer::DrawToSurface( - const fml::TimeDelta frame_build_duration, + FrameTimingsRecorder& frame_timings_recorder, flutter::LayerTree& layer_tree) { TRACE_EVENT0("flutter", "Rasterizer::DrawToSurface"); FML_DCHECK(surface_); - compositor_context_->ui_time().SetLapTime(frame_build_duration); + compositor_context_->ui_time().SetLapTime( + frame_timings_recorder.GetBuildDuration()); SkCanvas* embedder_root_canvas = nullptr; if (external_view_embedder_) { @@ -529,6 +531,7 @@ RasterStatus Rasterizer::DrawToSurface( frame->Submit(); } + frame_timings_recorder.RecordRasterEnd(fml::TimePoint::Now()); FireNextFrameCallbackIfPresent(); if (surface_->GetContext()) { diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index b4fb8bb02128b..c922a7f8befd6 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -485,7 +485,7 @@ class Rasterizer final : public SnapshotDelegate { std::unique_ptr frame_timings_recorder, std::unique_ptr layer_tree); - RasterStatus DrawToSurface(const fml::TimeDelta frame_build_duration, + RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, flutter::LayerTree& layer_tree); void FireNextFrameCallbackIfPresent();