Skip to content

Commit

Permalink
Resubmit frame when the surface is switched (flutter#19555)
Browse files Browse the repository at this point in the history
  • Loading branch information
Emmanuel Garcia authored and justinmc committed Jul 7, 2020
1 parent 8402d67 commit f1056b4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,19 @@ class SurfaceMock : public Surface {
(override));
};

fml::RefPtr<fml::RasterThreadMerger> GetThreadMergerFromPlatformThread() {
auto rasterizer_thread = new fml::Thread("rasterizer");
auto rasterizer_queue_id =
rasterizer_thread->GetTaskRunner()->GetTaskQueueId();

fml::RefPtr<fml::RasterThreadMerger> 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<fml::RasterThreadMerger>(platform_queue_id,
platform_queue_id);
}
auto rasterizer_thread = new fml::Thread("rasterizer");
auto rasterizer_queue_id =
rasterizer_thread->GetTaskRunner()->GetTaskQueueId();
return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
rasterizer_queue_id);
}
Expand Down Expand Up @@ -291,7 +295,9 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) {
};
auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
android_context, jni_mock, surface_factory);
auto raster_thread_merger = GetThreadMergerFromPlatformThread();

auto raster_thread_merger =
GetThreadMergerFromPlatformThread(/*merged=*/true);

// ------------------ First frame ------------------ //
{
Expand All @@ -309,6 +315,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);
Expand Down Expand Up @@ -373,6 +382,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);
Expand Down Expand Up @@ -434,6 +446,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);
Expand Down

0 comments on commit f1056b4

Please sign in to comment.