diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 2c874019e29ae..cc17ce762339c 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -151,7 +151,7 @@ void Rasterizer::DrawLastLayerTree( RasterStatus Rasterizer::Draw( std::unique_ptr frame_timings_recorder, std::shared_ptr> pipeline, - LayerTreeDiscardCallback discardCallback) { + LayerTreeDiscardCallback discard_callback) { TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder, "flutter", "GPURasterizer::Draw"); if (raster_thread_merger_ && @@ -170,7 +170,7 @@ RasterStatus Rasterizer::Draw( RasterStatus raster_status = RasterStatus::kFailed; Pipeline::Consumer consumer = [&](std::unique_ptr layer_tree) { - if (discardCallback(*layer_tree.get())) { + if (discard_callback(*layer_tree.get())) { raster_status = RasterStatus::kDiscarded; } else { raster_status = @@ -208,9 +208,11 @@ RasterStatus Rasterizer::Draw( delegate_.GetTaskRunners().GetRasterTaskRunner()->PostTask( fml::MakeCopyable( [weak_this = weak_factory_.GetWeakPtr(), pipeline, - resubmit_recorder = std::move(resubmit_recorder)]() mutable { + resubmit_recorder = std::move(resubmit_recorder), + discard_callback = std::move(discard_callback)]() mutable { if (weak_this) { - weak_this->Draw(std::move(resubmit_recorder), pipeline); + weak_this->Draw(std::move(resubmit_recorder), pipeline, + std::move(discard_callback)); } })); break; diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 2829f0c8dc487..b05cabc5c11a8 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -230,13 +230,13 @@ class Rasterizer final : public SnapshotDelegate { /// /// @param[in] pipeline The layer tree pipeline to take the next layer tree /// to render from. - /// @param[in] discardCallback if specified and returns true, the layer tree + /// @param[in] discard_callback if specified and returns true, the layer tree /// is discarded instead of being rendered /// RasterStatus Draw( std::unique_ptr frame_timings_recorder, std::shared_ptr> pipeline, - LayerTreeDiscardCallback discardCallback = NoDiscard); + LayerTreeDiscardCallback discard_callback = NoDiscard); //---------------------------------------------------------------------------- /// @brief The type of the screenshot to obtain of the previously diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index fb3e58a1b8bab..ee3313e647fc4 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -2277,6 +2277,92 @@ TEST_F(ShellTest, DiscardLayerTreeOnResize) { DestroyShell(std::move(shell)); } +TEST_F(ShellTest, DiscardResubmittedLayerTreeOnResize) { + auto settings = CreateSettingsForFixture(); + + SkISize origin_size = SkISize::Make(400, 100); + SkISize new_size = SkISize::Make(400, 200); + + fml::AutoResetWaitableEvent end_frame_latch; + + fml::AutoResetWaitableEvent resize_latch; + + std::shared_ptr external_view_embedder; + fml::RefPtr raster_thread_merger_ref; + auto end_frame_callback = + [&](bool should_merge_thread, + fml::RefPtr raster_thread_merger) { + if (!raster_thread_merger_ref) { + raster_thread_merger_ref = raster_thread_merger; + } + if (should_merge_thread) { + raster_thread_merger->MergeWithLease(10); + external_view_embedder->UpdatePostPrerollResult( + PostPrerollResult::kSuccess); + } + end_frame_latch.Signal(); + + if (should_merge_thread) { + resize_latch.Wait(); + } + }; + + external_view_embedder = std::make_shared( + std::move(end_frame_callback), PostPrerollResult::kResubmitFrame, true); + + std::unique_ptr shell = CreateShell( + settings, GetTaskRunnersForFixture(), false, external_view_embedder); + + // Create the surface needed by rasterizer + PlatformViewNotifyCreated(shell.get()); + + fml::TaskRunner::RunNowOrPostTask( + shell->GetTaskRunners().GetPlatformTaskRunner(), + [&shell, &origin_size]() { + shell->GetPlatformView()->SetViewportMetrics( + {1.0, static_cast(origin_size.width()), + static_cast(origin_size.height()), 22}); + }); + + auto configuration = RunConfiguration::InferFromSettings(settings); + configuration.SetEntrypoint("emptyMain"); + + RunEngine(shell.get(), std::move(configuration)); + + PumpOneFrame(shell.get(), static_cast(origin_size.width()), + static_cast(origin_size.height())); + + end_frame_latch.Wait(); + ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount()); + + fml::TaskRunner::RunNowOrPostTask( + shell->GetTaskRunners().GetPlatformTaskRunner(), + [&shell, &new_size, &resize_latch]() { + shell->GetPlatformView()->SetViewportMetrics( + {1.0, static_cast(new_size.width()), + static_cast(new_size.height()), 22}); + resize_latch.Signal(); + }); + + end_frame_latch.Wait(); + + // The frame resubmitted with origin size should be discarded after the + // viewport metrics changed. + ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount()); + + // Threads will be merged at the end of this frame. + PumpOneFrame(shell.get(), static_cast(new_size.width()), + static_cast(new_size.height())); + + end_frame_latch.Wait(); + ASSERT_TRUE(raster_thread_merger_ref->IsMerged()); + ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount()); + ASSERT_EQ(new_size, external_view_embedder->GetLastSubmittedFrameSize()); + + PlatformViewNotifyDestroyed(shell.get()); + DestroyShell(std::move(shell)); +} + TEST_F(ShellTest, IgnoresInvalidMetrics) { fml::AutoResetWaitableEvent latch; double last_device_pixel_ratio;