From cc602f1625d63489f1ff91e59eea9dd54e47041a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 19 Dec 2023 15:37:50 -0800 Subject: [PATCH] Impl --- shell/common/animator.cc | 13 +++++-------- shell/common/animator_unittests.cc | 30 ++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 3dd925cee6213..a16374651cc2b 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -143,15 +143,12 @@ void Animator::BeginFrame( void Animator::Render(std::unique_ptr layer_tree, float device_pixel_ratio) { - has_rendered_ = true; - - if (!frame_timings_recorder_) { - // Framework can directly call render with a built scene. - frame_timings_recorder_ = std::make_unique(); - const fml::TimePoint placeholder_time = fml::TimePoint::Now(); - frame_timings_recorder_->RecordVsync(placeholder_time, placeholder_time); - frame_timings_recorder_->RecordBuildStart(placeholder_time); + // Animator::Render should be called after BeginFrame, which is indicated by + // frame_timings_recorder_ being non-null. Otherwise, this call is ignored. + if (frame_timings_recorder_ == nullptr) { + return; } + has_rendered_ = true; TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder_, "flutter", "Animator::Render", /*flow_id_count=*/0, diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index 19a851a864c74..37cda29bb648f 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -158,20 +158,30 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyIdleBeforeRender) { latch.Wait(); ASSERT_FALSE(delegate.notify_idle_called_); + fml::AutoResetWaitableEvent render_latch; // Validate it has not notified idle and try to render. task_runners.GetUITaskRunner()->PostDelayedTask( [&] { ASSERT_FALSE(delegate.notify_idle_called_); - auto layer_tree = std::make_unique(LayerTree::Config(), - SkISize::Make(600, 800)); - animator->Render(std::move(layer_tree), 1.0); + EXPECT_CALL(delegate, OnAnimatorBeginFrame).WillOnce([&] { + auto layer_tree = std::make_unique( + LayerTree::Config(), SkISize::Make(600, 800)); + animator->Render(std::move(layer_tree), 1.0); + render_latch.Signal(); + }); + // Request a frame that builds a layer tree and renders a frame. + // When the frame is rendered, render_latch will be signaled. + animator->RequestFrame(true); task_runners.GetPlatformTaskRunner()->PostTask(flush_vsync_task); }, // See kNotifyIdleTaskWaitTime in animator.cc. fml::TimeDelta::FromMilliseconds(60)); latch.Wait(); + render_latch.Wait(); - // Still hasn't notified idle because there has been no frame request. + // A frame has been rendered, and the next frame request will notify idle. + // But at the moment there isn't another frame request, therefore it still + // hasn't notified idle. task_runners.GetUITaskRunner()->PostTask([&] { ASSERT_FALSE(delegate.notify_idle_called_); // False to avoid getting cals to BeginFrame that will request more frames @@ -239,16 +249,16 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyDelegateIfPipelineIsNotEmpty) { for (int i = 0; i < 2; i++) { task_runners.GetUITaskRunner()->PostTask([&] { + EXPECT_CALL(delegate, OnAnimatorBeginFrame).WillOnce([&] { + auto layer_tree = std::make_unique(LayerTree::Config(), + SkISize::Make(600, 800)); + animator->Render(std::move(layer_tree), 1.0); + begin_frame_latch.Signal(); + }); animator->RequestFrame(); task_runners.GetPlatformTaskRunner()->PostTask(flush_vsync_task); }); begin_frame_latch.Wait(); - - PostTaskSync(task_runners.GetUITaskRunner(), [&] { - auto layer_tree = std::make_unique(LayerTree::Config(), - SkISize::Make(600, 800)); - animator->Render(std::move(layer_tree), 1.0); - }); } PostTaskSync(task_runners.GetUITaskRunner(), [&] { animator.reset(); });