diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 7cc45fa1f5b5a..7464a5cc51fa0 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -195,8 +195,7 @@ void Rasterizer::DrawLastLayerTree( } RasterStatus Rasterizer::Draw( - const std::shared_ptr& pipeline, - LayerTreeDiscardCallback discard_callback) { + const std::shared_ptr& pipeline) { TRACE_EVENT0("flutter", "GPURasterizer::Draw"); if (raster_thread_merger_ && !raster_thread_merger_->IsOnRasterizingThread()) { @@ -209,7 +208,8 @@ RasterStatus Rasterizer::Draw( RasterStatus raster_status = RasterStatus::kFailed; LayerTreePipeline::Consumer consumer = - [&](std::unique_ptr item) { + [&raster_status, this, + &delegate = delegate_](std::unique_ptr item) { // TODO(dkwingsmt): Use a proper view ID when Rasterizer supports // multi-view. int64_t view_id = kFlutterImplicitViewId; @@ -217,7 +217,7 @@ RasterStatus Rasterizer::Draw( std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); float device_pixel_ratio = item->device_pixel_ratio; - if (discard_callback(view_id, *layer_tree.get())) { + if (delegate.ShouldDiscardLayerTree(view_id, *layer_tree.get())) { raster_status = RasterStatus::kDiscarded; } else { raster_status = DoDraw(std::move(frame_timings_recorder), @@ -259,13 +259,11 @@ RasterStatus Rasterizer::Draw( switch (consume_result) { case PipelineConsumeResult::MoreAvailable: { delegate_.GetTaskRunners().GetRasterTaskRunner()->PostTask( - fml::MakeCopyable( - [weak_this = weak_factory_.GetWeakPtr(), pipeline, - discard_callback = std::move(discard_callback)]() mutable { - if (weak_this) { - weak_this->Draw(pipeline, std::move(discard_callback)); - } - })); + [weak_this = weak_factory_.GetWeakPtr(), pipeline]() { + if (weak_this) { + weak_this->Draw(pipeline); + } + }); break; } default: diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index d413edf6ac2cb..9abe2a7b02f69 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -119,6 +119,9 @@ class Rasterizer final : public SnapshotDelegate, const = 0; virtual const Settings& GetSettings() const = 0; + + virtual bool ShouldDiscardLayerTree(int64_t view_id, + const flutter::LayerTree& tree) = 0; }; //---------------------------------------------------------------------------- @@ -254,9 +257,6 @@ class Rasterizer final : public SnapshotDelegate, std::shared_ptr GetTextureRegistry() override; - using LayerTreeDiscardCallback = - std::function; - //---------------------------------------------------------------------------- /// @brief Takes the next item from the layer tree pipeline and executes /// the raster thread frame workload for that pipeline item to @@ -285,11 +285,8 @@ class Rasterizer final : public SnapshotDelegate, /// /// @param[in] pipeline The layer tree pipeline to take the next layer tree /// to render from. - /// @param[in] discard_callback if specified and returns true, the layer tree - /// is discarded instead of being rendered /// - RasterStatus Draw(const std::shared_ptr& pipeline, - LayerTreeDiscardCallback discard_callback = NoDiscard); + RasterStatus Draw(const std::shared_ptr& pipeline); //---------------------------------------------------------------------------- /// @brief The type of the screenshot to obtain of the previously @@ -585,9 +582,6 @@ class Rasterizer final : public SnapshotDelegate, void FireNextFrameCallbackIfPresent(); - static bool NoDiscard(int64_t view_id, const flutter::LayerTree& layer_tree) { - return false; - } static bool ShouldResubmitFrame(const RasterStatus& raster_status); Delegate& delegate_; diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 55694a4554278..5a527e49a2e4e 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -43,6 +43,8 @@ class MockDelegate : public Rasterizer::Delegate { MOCK_CONST_METHOD0(GetIsGpuDisabledSyncSwitch, std::shared_ptr()); MOCK_CONST_METHOD0(GetSettings, const Settings&()); + MOCK_METHOD2(ShouldDiscardLayerTree, + bool(int64_t, const flutter::LayerTree&)); }; class MockSurface : public Surface { @@ -129,7 +131,8 @@ TEST(RasterizerTest, drawEmptyPipeline) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - rasterizer->Draw(pipeline, nullptr); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); latch.Signal(); }); latch.Wait(); @@ -199,8 +202,8 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); latch.Signal(); }); latch.Wait(); @@ -265,8 +268,8 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); latch.Signal(); }); latch.Wait(); @@ -336,8 +339,8 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); } TEST(RasterizerTest, @@ -410,11 +413,11 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; // The Draw() will respectively call BeginFrame(), SubmitFrame() and // EndFrame() one time. - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); // The DrawLastLayerTree() will respectively call BeginFrame(), SubmitFrame() // and EndFrame() one more time, totally 2 times. @@ -460,8 +463,8 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); latch.Signal(); }); latch.Wait(); @@ -517,8 +520,8 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); // Always discard the layer tree. - auto discard_callback = [](int64_t, LayerTree&) { return true; }; - RasterStatus status = rasterizer->Draw(pipeline, discard_callback); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(true)); + RasterStatus status = rasterizer->Draw(pipeline); EXPECT_EQ(status, RasterStatus::kDiscarded); latch.Signal(); }); @@ -561,8 +564,8 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - RasterStatus status = rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + RasterStatus status = rasterizer->Draw(pipeline); EXPECT_EQ(status, RasterStatus::kFailed); latch.Signal(); }); @@ -619,8 +622,8 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); latch.Signal(); }); latch.Wait(); @@ -677,8 +680,8 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - RasterStatus status = rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + RasterStatus status = rasterizer->Draw(pipeline); EXPECT_EQ(status, RasterStatus::kSuccess); latch.Signal(); }); @@ -735,8 +738,8 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - RasterStatus status = rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + RasterStatus status = rasterizer->Draw(pipeline); EXPECT_EQ(status, RasterStatus::kSuccess); latch.Signal(); }); @@ -792,8 +795,8 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - RasterStatus status = rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + RasterStatus status = rasterizer->Draw(pipeline); EXPECT_EQ(status, RasterStatus::kDiscarded); latch.Signal(); }); @@ -848,8 +851,8 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - RasterStatus status = rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + RasterStatus status = rasterizer->Draw(pipeline); EXPECT_EQ(status, RasterStatus::kFailed); latch.Signal(); }); @@ -929,10 +932,10 @@ TEST(RasterizerTest, EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, i == 0); } - auto no_discard = [](int64_t, LayerTree&) { return false; }; // Although we only call 'Rasterizer::Draw' once, it will be called twice // finally because there are two items in the pipeline. - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); }); count_down_latch.Wait(); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -1100,10 +1103,10 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, i == 0); } - auto no_discard = [](int64_t, LayerTree&) { return false; }; // Although we only call 'Rasterizer::Draw' once, it will be called twice // finally because there are two items in the pipeline. - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); }); submit_latch.Wait(); @@ -1181,8 +1184,8 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, true); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - rasterizer->Draw(pipeline, no_discard); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); }); submit_latch.Wait(); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 3994674ba4301..128607232d7e9 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1218,23 +1218,15 @@ void Shell::OnAnimatorUpdateLatestFrameTargetTime( void Shell::OnAnimatorDraw(std::shared_ptr pipeline) { FML_DCHECK(is_set_up_); - auto discard_callback = [this](int64_t view_id, flutter::LayerTree& tree) { - std::scoped_lock lock(resize_mutex_); - auto expected_frame_size = ExpectedFrameSize(view_id); - return !expected_frame_size.isEmpty() && - tree.frame_size() != expected_frame_size; - }; - task_runners_.GetRasterTaskRunner()->PostTask(fml::MakeCopyable( [&waiting_for_first_frame = waiting_for_first_frame_, &waiting_for_first_frame_condition = waiting_for_first_frame_condition_, rasterizer = rasterizer_->GetWeakPtr(), - weak_pipeline = std::weak_ptr(pipeline), - discard_callback = std::move(discard_callback)]() mutable { + weak_pipeline = std::weak_ptr(pipeline)]() mutable { if (rasterizer) { std::shared_ptr pipeline = weak_pipeline.lock(); if (pipeline) { - rasterizer->Draw(pipeline, std::move(discard_callback)); + rasterizer->Draw(pipeline); } if (waiting_for_first_frame.load()) { @@ -1591,6 +1583,15 @@ fml::TimePoint Shell::GetLatestFrameTargetTime() const { return latest_frame_target_time_.value(); } +// |Rasterizer::Delegate| +bool Shell::ShouldDiscardLayerTree(int64_t view_id, + const flutter::LayerTree& tree) { + std::scoped_lock lock(resize_mutex_); + auto expected_frame_size = ExpectedFrameSize(view_id); + return !expected_frame_size.isEmpty() && + tree.frame_size() != expected_frame_size; +} + // |ServiceProtocol::Handler| fml::RefPtr Shell::GetServiceProtocolHandlerTaskRunner( std::string_view method) const { diff --git a/shell/common/shell.h b/shell/common/shell.h index 053dd834cd38f..e808caec0ef9e 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -693,6 +693,10 @@ class Shell final : public PlatformView::Delegate, // |Rasterizer::Delegate| fml::TimePoint GetLatestFrameTargetTime() const override; + // |Rasterizer::Delegate| + bool ShouldDiscardLayerTree(int64_t view_id, + const flutter::LayerTree& tree) override; + // |ServiceProtocol::Handler| fml::RefPtr GetServiceProtocolHandlerTaskRunner( std::string_view method) const override;