EndFrame should be always called by rasterizer (flutter/engine#19257)

This commit is contained in:
Emmanuel Garcia 2020-06-24 14:02:48 -07:00 committed by GitHub
parent c467c00208
commit 910b7ed0df
12 changed files with 30 additions and 23 deletions

View File

@ -287,16 +287,16 @@ class ExternalViewEmbedder {
virtual bool SubmitFrame(GrContext* context,
std::unique_ptr<SurfaceFrame> frame);
// This should only be called after |SubmitFrame|.
// This method provides the embedder a way to do additional tasks after
// |SubmitFrame|. After invoking this method, the current task on the
// TaskRunner should end immediately.
// |SubmitFrame|. For example, merge task runners if `should_resubmit_frame`
// is true.
//
// For example on the iOS embedder, threads are merged in this call.
// A new frame on the platform thread starts immediately. If the GPU thread
// still has some task running, there could be two frames being rendered
// concurrently, which causes undefined behaviors.
virtual void EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {}
FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder);

View File

@ -151,12 +151,10 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
// Merging the thread as we know the next `Draw` should be run on the platform
// thread.
if (raster_status == RasterStatus::kResubmit) {
auto* external_view_embedder = surface_->GetExternalViewEmbedder();
// We know only the `external_view_embedder` can
// causes|RasterStatus::kResubmit|. Check to make sure.
FML_DCHECK(external_view_embedder != nullptr);
external_view_embedder->EndFrame(raster_thread_merger_);
if (surface_ != nullptr && surface_->GetExternalViewEmbedder() != nullptr) {
auto should_resubmit_frame = raster_status == RasterStatus::kResubmit;
surface_->GetExternalViewEmbedder()->EndFrame(should_resubmit_frame,
raster_thread_merger_);
}
// Consume as many pipeline items as possible. But yield the event loop

View File

@ -43,8 +43,9 @@ bool ShellTestExternalViewEmbedder::SubmitFrame(
// |ExternalViewEmbedder|
void ShellTestExternalViewEmbedder::EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
end_frame_call_back_();
end_frame_call_back_(should_resubmit_frame);
}
// |ExternalViewEmbedder|

View File

@ -15,7 +15,7 @@ namespace flutter {
///
class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
public:
using EndFrameCallBack = std::function<void(void)>;
using EndFrameCallBack = std::function<void(bool)>;
ShellTestExternalViewEmbedder(const EndFrameCallBack& end_frame_call_back,
PostPrerollResult post_preroll_result)
@ -56,6 +56,7 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
// |ExternalViewEmbedder|
void EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;
// |ExternalViewEmbedder|

View File

@ -474,7 +474,8 @@ TEST_F(ShellTest,
auto settings = CreateSettingsForFixture();
fml::AutoResetWaitableEvent endFrameLatch;
bool end_frame_called = false;
auto end_frame_callback = [&] {
auto end_frame_callback = [&](bool should_resubmit_frame) {
ASSERT_TRUE(should_resubmit_frame);
end_frame_called = true;
endFrameLatch.Signal();
};

View File

@ -254,8 +254,9 @@ void AndroidExternalViewEmbedder::CancelFrame() {
// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
if (should_run_rasterizer_on_platform_thread_) {
if (should_resubmit_frame && should_run_rasterizer_on_platform_thread_) {
raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
should_run_rasterizer_on_platform_thread_ = false;
}

View File

@ -65,6 +65,7 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
// |ExternalViewEmbedder|
void EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;
// Gets the rect based on the device pixel ratio of a platform view displayed

View File

@ -158,7 +158,7 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) {
ASSERT_TRUE(embedder->SubmitFrame(nullptr, nullptr));
EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
embedder->EndFrame(raster_thread_merger);
embedder->EndFrame(/*should_resubmit_frame=*/true, raster_thread_merger);
ASSERT_TRUE(raster_thread_merger->IsMerged());
@ -182,7 +182,7 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnRasterizerThread) {
ASSERT_EQ(PostPrerollResult::kSuccess, result);
EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
embedder->EndFrame(raster_thread_merger);
embedder->EndFrame(/*should_resubmit_frame=*/true, raster_thread_merger);
ASSERT_FALSE(raster_thread_merger->IsMerged());
}
@ -332,7 +332,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame__RecycleSurfaces) {
embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
embedder->EndFrame(raster_thread_merger);
embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
}
// ------------------ Second frame ------------------ //
@ -380,7 +380,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame__RecycleSurfaces) {
embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
embedder->EndFrame(raster_thread_merger);
embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
}
}
@ -399,7 +399,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotCallJNIPlatformThreadOnlyMethods) {
raster_thread_merger);
EXPECT_CALL(*jni_mock, FlutterViewEndFrame()).Times(0);
embedder->EndFrame(raster_thread_merger);
embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
}
} // namespace testing

View File

@ -604,8 +604,9 @@ void FlutterPlatformViewsController::BringLayersIntoView(LayersMap layer_map) {
}
void FlutterPlatformViewsController::EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
if (merge_threads_) {
if (should_resubmit_frame && merge_threads_) {
raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
merge_threads_ = false;
}

View File

@ -168,7 +168,8 @@ class FlutterPlatformViewsController {
// Invoked at the very end of a frame.
// After invoking this method, nothing should happen on the current TaskRunner during the same
// frame.
void EndFrame(fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger);
void EndFrame(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger);
void OnMethodCall(FlutterMethodCall* call, FlutterResult& result);

View File

@ -85,7 +85,8 @@ class IOSSurface : public ExternalViewEmbedder {
bool SubmitFrame(GrContext* context, std::unique_ptr<SurfaceFrame> frame) override;
// |ExternalViewEmbedder|
void EndFrame(fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;
void EndFrame(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;
public:
FML_DISALLOW_COPY_AND_ASSIGN(IOSSurface);

View File

@ -149,10 +149,11 @@ bool IOSSurface::SubmitFrame(GrContext* context, std::unique_ptr<SurfaceFrame> f
}
// |ExternalViewEmbedder|
void IOSSurface::EndFrame(fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
void IOSSurface::EndFrame(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
TRACE_EVENT0("flutter", "IOSSurface::EndFrame");
FML_CHECK(platform_views_controller_ != nullptr);
return platform_views_controller_->EndFrame(raster_thread_merger);
return platform_views_controller_->EndFrame(should_resubmit_frame, raster_thread_merger);
}
} // namespace flutter