From 6fefd835486aa8b68b350d642ec58b26a87504b8 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Mon, 6 Jul 2020 16:19:15 -0700 Subject: [PATCH 1/3] Resubmit frame when the surface is switched --- .../external_view_embedder/external_view_embedder.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.cc b/shell/platform/android/external_view_embedder/external_view_embedder.cc index e94b70318c922..d564a8f434234 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -146,7 +146,8 @@ bool AndroidExternalViewEmbedder::SubmitFrame( // Submit the background canvas frame before switching the GL context to // the overlay surfaces. // - // Skip a frame if the embedding is switching surfaces. + // Skip a frame if the embedding is switching surfaces, and indicate in + // `PostPrerollAction` that this frame must be resubmitted. auto should_submit_current_frame = previous_frame_view_count_ > 0 || current_frame_view_count == 0; if (should_submit_current_frame) { @@ -233,6 +234,10 @@ PostPrerollResult AndroidExternalViewEmbedder::PostPrerollAction( CancelFrame(); return PostPrerollResult::kResubmitFrame; } + // Surface switch requires to resubmit the frame. + if (previous_frame_view_count_ == 0) { + return PostPrerollResult::kResubmitFrame; + } } return PostPrerollResult::kSuccess; } From 3d4a78c8d8d92fc4b2a3f3dcb5829f3524706bc4 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Mon, 6 Jul 2020 17:07:53 -0700 Subject: [PATCH 2/3] Test --- .../external_view_embedder_unittests.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc index 1ad2be5a077a7..fd880deb12ca4 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc @@ -291,7 +291,9 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }; auto embedder = std::make_unique( android_context, jni_mock, surface_factory); + auto raster_thread_merger = GetThreadMergerFromPlatformThread(); + raster_thread_merger->MergeWithLease(1); // ------------------ First frame ------------------ // { @@ -309,6 +311,9 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); // Submits frame if no Android view in the current frame. EXPECT_TRUE(did_submit_frame); + // Doesn't resubmit frame. + auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger); + ASSERT_EQ(PostPrerollResult::kSuccess, postpreroll_result); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -373,6 +378,9 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); // Doesn't submit frame if there aren't Android views in the previous frame. EXPECT_FALSE(did_submit_frame); + // Resubmits frame. + auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger); + ASSERT_EQ(PostPrerollResult::kResubmitFrame, postpreroll_result); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -434,6 +442,9 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); // Submits frame if there are Android views in the previous frame. EXPECT_TRUE(did_submit_frame); + // Doesn't resubmit frame. + auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger); + ASSERT_EQ(PostPrerollResult::kSuccess, postpreroll_result); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); From 2c43f9a2b27b2e9acca6cac02967701eb053dfb9 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Mon, 6 Jul 2020 20:38:02 -0700 Subject: [PATCH 3/3] Fix unit test --- .../external_view_embedder_unittests.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc index fd880deb12ca4..2f375ec92b398 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc @@ -43,15 +43,19 @@ class SurfaceMock : public Surface { (override)); }; -fml::RefPtr GetThreadMergerFromPlatformThread() { - auto rasterizer_thread = new fml::Thread("rasterizer"); - auto rasterizer_queue_id = - rasterizer_thread->GetTaskRunner()->GetTaskQueueId(); - +fml::RefPtr GetThreadMergerFromPlatformThread( + bool merged = false) { // Assume the current thread is the platform thread. fml::MessageLoop::EnsureInitializedForCurrentThread(); auto platform_queue_id = fml::MessageLoop::GetCurrentTaskQueueId(); + if (merged) { + return fml::MakeRefCounted(platform_queue_id, + platform_queue_id); + } + auto rasterizer_thread = new fml::Thread("rasterizer"); + auto rasterizer_queue_id = + rasterizer_thread->GetTaskRunner()->GetTaskQueueId(); return fml::MakeRefCounted(platform_queue_id, rasterizer_queue_id); } @@ -292,8 +296,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { auto embedder = std::make_unique( android_context, jni_mock, surface_factory); - auto raster_thread_merger = GetThreadMergerFromPlatformThread(); - raster_thread_merger->MergeWithLease(1); + auto raster_thread_merger = + GetThreadMergerFromPlatformThread(/*merged=*/true); // ------------------ First frame ------------------ // {