started providing the GPU sync switch to external view embedders (#22302) (#22760)
Co-authored-by: gaaclarke <30870216+gaaclarke@users.noreply.github.com>
diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc
index 9441c8d..273006c 100644
--- a/flow/embedded_views.cc
+++ b/flow/embedded_views.cc
@@ -6,8 +6,10 @@
namespace flutter {
-void ExternalViewEmbedder::SubmitFrame(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) {
+void ExternalViewEmbedder::SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
frame->Submit();
};
diff --git a/flow/embedded_views.h b/flow/embedded_views.h
index e82d9e8..4d6853a 100644
--- a/flow/embedded_views.h
+++ b/flow/embedded_views.h
@@ -10,6 +10,7 @@
#include "flutter/flow/surface_frame.h"
#include "flutter/fml/memory/ref_counted.h"
#include "flutter/fml/raster_thread_merger.h"
+#include "flutter/fml/synchronization/sync_switch.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPoint.h"
@@ -309,8 +310,10 @@
// This method can mutate the root Skia canvas before submitting the frame.
//
// It can also allocate frames for overlay surfaces to compose hybrid views.
- virtual void SubmitFrame(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame);
+ virtual void SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch);
// This method provides the embedder a way to do additional tasks after
// |SubmitFrame|. For example, merge task runners if `should_resubmit_frame`
diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc
index 1d326a7..3733e95 100644
--- a/shell/common/rasterizer.cc
+++ b/shell/common/rasterizer.cc
@@ -469,8 +469,9 @@
if (external_view_embedder_ &&
(!raster_thread_merger_ || raster_thread_merger_->IsMerged())) {
FML_DCHECK(!frame->IsSubmitted());
- external_view_embedder_->SubmitFrame(surface_->GetContext(),
- std::move(frame));
+ external_view_embedder_->SubmitFrame(
+ surface_->GetContext(), std::move(frame),
+ delegate_.GetIsGpuDisabledSyncSwitch());
} else {
frame->Submit();
}
diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc
index 38611b0..357a0f3 100644
--- a/shell/common/rasterizer_unittests.cc
+++ b/shell/common/rasterizer_unittests.cc
@@ -55,9 +55,11 @@
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger));
MOCK_METHOD0(GetCurrentCanvases, std::vector<SkCanvas*>());
MOCK_METHOD1(CompositeEmbeddedView, SkCanvas*(int view_id));
- MOCK_METHOD2(SubmitFrame,
- void(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame));
+ MOCK_METHOD3(
+ SubmitFrame,
+ void(GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch));
MOCK_METHOD2(EndFrame,
void(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger));
diff --git a/shell/common/shell_test_external_view_embedder.cc b/shell/common/shell_test_external_view_embedder.cc
index 5a8edc1..80e8210 100644
--- a/shell/common/shell_test_external_view_embedder.cc
+++ b/shell/common/shell_test_external_view_embedder.cc
@@ -63,7 +63,8 @@
// |ExternalViewEmbedder|
void ShellTestExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) {
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
frame->Submit();
if (frame && frame->SkiaSurface()) {
last_submitted_frame_size_ = SkISize::Make(frame->SkiaSurface()->width(),
diff --git a/shell/common/shell_test_external_view_embedder.h b/shell/common/shell_test_external_view_embedder.h
index 72c101e..1782a03 100644
--- a/shell/common/shell_test_external_view_embedder.h
+++ b/shell/common/shell_test_external_view_embedder.h
@@ -62,8 +62,10 @@
SkCanvas* CompositeEmbeddedView(int view_id) override;
// |ExternalViewEmbedder|
- void SubmitFrame(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) override;
+ void SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
void EndFrame(
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 9e544d6..69370e7 100644
--- a/shell/platform/android/external_view_embedder/external_view_embedder.cc
+++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc
@@ -75,7 +75,8 @@
// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) {
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame");
if (!FrameHasPlatformLayers()) {
diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.h b/shell/platform/android/external_view_embedder/external_view_embedder.h
index 7398ce4..71d7e7c 100644
--- a/shell/platform/android/external_view_embedder/external_view_embedder.h
+++ b/shell/platform/android/external_view_embedder/external_view_embedder.h
@@ -46,8 +46,10 @@
std::vector<SkCanvas*> GetCurrentCanvases() override;
// |ExternalViewEmbedder|
- void SubmitFrame(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) override;
+ void SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
PostPrerollResult PostPrerollAction(
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 1c161cc..3ea187c 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
@@ -331,7 +331,7 @@
return true;
});
- embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
+ embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), nullptr);
// Submits frame if no Android view in the current frame.
EXPECT_TRUE(did_submit_frame);
// Doesn't resubmit frame.
@@ -398,7 +398,7 @@
return true;
});
- embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
+ embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), nullptr);
// Doesn't submit frame if there aren't Android views in the previous frame.
EXPECT_FALSE(did_submit_frame);
// Resubmits frame.
@@ -462,7 +462,7 @@
}
return true;
});
- embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
+ embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), nullptr);
// Submits frame if there are Android views in the previous frame.
EXPECT_TRUE(did_submit_frame);
// Doesn't resubmit frame.
@@ -560,7 +560,7 @@
std::make_unique<SurfaceFrame>(SkSurface::MakeNull(1000, 1000), false,
[](const SurfaceFrame& surface_frame,
SkCanvas* canvas) { return true; });
- embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
+ embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), nullptr);
EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
@@ -640,7 +640,7 @@
std::make_unique<SurfaceFrame>(SkSurface::MakeNull(1000, 1000), false,
[](const SurfaceFrame& surface_frame,
SkCanvas* canvas) { return true; });
- embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
+ embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), nullptr);
EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
index 3fc52d9..feb58fb 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
@@ -462,9 +462,22 @@
);
}
-bool FlutterPlatformViewsController::SubmitFrame(GrDirectContext* gr_context,
- std::shared_ptr<IOSContext> ios_context,
- std::unique_ptr<SurfaceFrame> frame) {
+bool FlutterPlatformViewsController::SubmitFrame(
+ GrDirectContext* gr_context,
+ std::shared_ptr<IOSContext> ios_context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
+ bool result = false;
+ gpu_disable_sync_switch->Execute(
+ fml::SyncSwitch::Handlers().SetIfTrue([&] { result = false; }).SetIfFalse([&] {
+ result = SubmitFrameGpuSafe(gr_context, ios_context, std::move(frame));
+ }));
+ return result;
+}
+
+bool FlutterPlatformViewsController::SubmitFrameGpuSafe(GrDirectContext* gr_context,
+ std::shared_ptr<IOSContext> ios_context,
+ std::unique_ptr<SurfaceFrame> frame) {
// Any UIKit related code has to run on main thread.
FML_DCHECK([[NSThread currentThread] isMainThread]);
if (flutter_view_ == nullptr) {
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm
index 0334720..31a19b2 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm
@@ -800,8 +800,10 @@
auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
nullptr, true,
[](const flutter::SurfaceFrame& surface_frame, SkCanvas* canvas) { return false; });
- XCTAssertFalse(
- flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface)));
+ auto is_gpu_disabled = std::make_shared<fml::SyncSwitch>();
+ is_gpu_disabled->SetSwitch(false);
+ XCTAssertFalse(flutterPlatformViewsController->SubmitFrame(
+ nullptr, nullptr, std::move(mock_surface), is_gpu_disabled));
auto embeddedViewParams_2 =
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
@@ -810,8 +812,10 @@
auto mock_surface_submit_false = std::make_unique<flutter::SurfaceFrame>(
nullptr, true,
[](const flutter::SurfaceFrame& surface_frame, SkCanvas* canvas) { return true; });
- XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr,
- std::move(mock_surface_submit_false)));
+ auto gpu_is_disabled = std::make_shared<fml::SyncSwitch>();
+ gpu_is_disabled->SetSwitch(false);
+ XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(
+ nullptr, nullptr, std::move(mock_surface_submit_false), gpu_is_disabled));
flutterPlatformViewsController->Reset();
}
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h
index 36f69c7..4192562 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h
+++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h
@@ -172,7 +172,8 @@
bool SubmitFrame(GrDirectContext* gr_context,
std::shared_ptr<IOSContext> ios_context,
- std::unique_ptr<SurfaceFrame> frame);
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch);
// Invoked at the very end of a frame.
// After invoking this method, nothing should happen on the current TaskRunner during the same
@@ -304,6 +305,10 @@
// Commit a CATransaction if |BeginCATransaction| has been called during the frame.
void CommitCATransactionIfNeeded();
+ bool SubmitFrameGpuSafe(GrDirectContext* gr_context,
+ std::shared_ptr<IOSContext> ios_context,
+ std::unique_ptr<SurfaceFrame> frame);
+
FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewsController);
};
diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.h b/shell/platform/darwin/ios/ios_external_view_embedder.h
index 6c023d1..84d3041 100644
--- a/shell/platform/darwin/ios/ios_external_view_embedder.h
+++ b/shell/platform/darwin/ios/ios_external_view_embedder.h
@@ -53,8 +53,10 @@
SkCanvas* CompositeEmbeddedView(int view_id) override;
// |ExternalViewEmbedder|
- void SubmitFrame(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) override;
+ void SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
void EndFrame(
diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm
index 46cb301..cfb3424 100644
--- a/shell/platform/darwin/ios/ios_external_view_embedder.mm
+++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm
@@ -72,11 +72,14 @@
}
// |ExternalViewEmbedder|
-void IOSExternalViewEmbedder::SubmitFrame(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) {
+void IOSExternalViewEmbedder::SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame");
FML_CHECK(platform_views_controller_);
- platform_views_controller_->SubmitFrame(std::move(context), ios_context_, std::move(frame));
+ platform_views_controller_->SubmitFrame(std::move(context), ios_context_, std::move(frame),
+ gpu_disable_sync_switch);
TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::DidSubmitFrame");
}
diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc
index b69907a..fc6c290 100644
--- a/shell/platform/embedder/embedder_external_view_embedder.cc
+++ b/shell/platform/embedder/embedder_external_view_embedder.cc
@@ -133,7 +133,8 @@
// |ExternalViewEmbedder|
void EmbedderExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) {
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
auto [matched_render_targets, pending_keys] =
render_target_cache_.GetExistingTargetsInCache(pending_views_);
diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h
index ffc6411..e668e6e 100644
--- a/shell/platform/embedder/embedder_external_view_embedder.h
+++ b/shell/platform/embedder/embedder_external_view_embedder.h
@@ -91,8 +91,10 @@
SkCanvas* CompositeEmbeddedView(int view_id) override;
// |ExternalViewEmbedder|
- void SubmitFrame(GrDirectContext* context,
- std::unique_ptr<SurfaceFrame> frame) override;
+ void SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
SkCanvas* GetRootCanvas() override;
diff --git a/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc b/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc
index 987db13..4faf062 100644
--- a/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc
+++ b/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc
@@ -141,7 +141,8 @@
void FuchsiaExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
- std::unique_ptr<flutter::SurfaceFrame> frame) {
+ std::unique_ptr<flutter::SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
TRACE_EVENT0("flutter", "FuchsiaExternalViewEmbedder::SubmitFrame");
std::vector<std::unique_ptr<SurfaceProducerSurface>> frame_surfaces;
std::unordered_map<EmbedderLayerId, size_t> frame_surface_indices;
diff --git a/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h b/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h
index c2aa386..d20225c 100644
--- a/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h
+++ b/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h
@@ -74,8 +74,10 @@
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;
// |ExternalViewEmbedder|
- void SubmitFrame(GrDirectContext* context,
- std::unique_ptr<flutter::SurfaceFrame> frame) override;
+ void SubmitFrame(
+ GrDirectContext* context,
+ std::unique_ptr<flutter::SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
void CancelFrame() override { Reset(); }
diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc
index eb3a16b..559d2b8 100644
--- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc
+++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc
@@ -45,7 +45,9 @@
double device_pixel_ratio,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override {}
void SubmitFrame(GrDirectContext* context,
- std::unique_ptr<flutter::SurfaceFrame> frame) override {
+ std::unique_ptr<flutter::SurfaceFrame> frame,
+ const std::shared_ptr<fml::SyncSwitch>&
+ gpu_disable_sync_switch) override {
return;
}