diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index df58e820a98be..904db93833453 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -189,6 +189,9 @@ RasterStatus Rasterizer::Draw( }; PipelineConsumeResult consume_result = pipeline->Consume(consumer); + if (consume_result == PipelineConsumeResult::NoneAvailable) { + return RasterStatus::kFailed; + } // if the raster status is to resubmit the frame, we push the frame to the // front of the queue and also change the consume status to more available. diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 7190b8cf448b9..26c16adcfc453 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -403,6 +403,10 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared>(/*depth=*/10); + auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); + bool result = pipeline->Produce().Complete(std::move(layer_tree)); + EXPECT_TRUE(result); auto no_discard = [](LayerTree&) { return false; }; rasterizer->Draw(CreateFinishedBuildRecorder(), pipeline, no_discard); latch.Signal(); @@ -410,6 +414,49 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { latch.Wait(); } +TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { + std::string test_name = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + ThreadHost thread_host("io.flutter.test." + test_name + ".", + ThreadHost::Type::Platform | ThreadHost::Type::RASTER | + ThreadHost::Type::IO | ThreadHost::Type::UI); + TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), + thread_host.raster_thread->GetTaskRunner(), + thread_host.ui_thread->GetTaskRunner(), + thread_host.io_thread->GetTaskRunner()); + MockDelegate delegate; + EXPECT_CALL(delegate, GetTaskRunners()) + .WillRepeatedly(ReturnRef(task_runners)); + + auto rasterizer = std::make_unique(delegate); + auto surface = std::make_unique(); + EXPECT_CALL(*surface, MakeRenderContextCurrent()) + .WillOnce(Return(ByMove(std::make_unique(true)))); + + std::shared_ptr external_view_embedder = + std::make_shared(); + rasterizer->SetExternalViewEmbedder(external_view_embedder); + rasterizer->Setup(std::move(surface)); + + EXPECT_CALL( + *external_view_embedder, + EndFrame(/*should_resubmit_frame=*/false, + /*raster_thread_merger=*/fml::RefPtr( + nullptr))) + .Times(0); + + fml::AutoResetWaitableEvent latch; + thread_host.raster_thread->GetTaskRunner()->PostTask([&] { + auto pipeline = std::make_shared>(/*depth=*/10); + auto no_discard = [](LayerTree&) { return false; }; + RasterStatus status = + rasterizer->Draw(CreateFinishedBuildRecorder(), pipeline, no_discard); + EXPECT_EQ(status, RasterStatus::kFailed); + latch.Signal(); + }); + latch.Wait(); +} + TEST(RasterizerTest, drawWithGpuEnabledAndSurfaceAllowsDrawingWhenGpuDisabledDoesAcquireFrame) { std::string test_name =