未验证 提交 5cea3a73 编写于 作者: D Dan Field 提交者: GitHub

Refactor GPU access switch (#24356)

上级 e2791be9
......@@ -9,7 +9,7 @@ namespace flutter {
void ExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch) {
frame->Submit();
};
......
......@@ -316,7 +316,7 @@ class ExternalViewEmbedder {
virtual void SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch);
const std::shared_ptr<const 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`
......
......@@ -18,11 +18,9 @@ SyncSwitch::Handlers& SyncSwitch::Handlers::SetIfFalse(
return *this;
}
SyncSwitch::SyncSwitch() : SyncSwitch(false) {}
SyncSwitch::SyncSwitch(bool value) : value_(value) {}
void SyncSwitch::Execute(const SyncSwitch::Handlers& handlers) {
void SyncSwitch::Execute(const SyncSwitch::Handlers& handlers) const {
std::scoped_lock guard(mutex_);
if (value_) {
handlers.true_handler();
......
......@@ -32,13 +32,10 @@ class SyncSwitch {
std::function<void()> false_handler = [] {};
};
/// Create a |SyncSwitch| with the false value.
SyncSwitch();
/// Create a |SyncSwitch| with the specified value.
///
/// @param[in] value Default value for the |SyncSwitch|.
SyncSwitch(bool value);
explicit SyncSwitch(bool value = false);
/// Diverge execution between true and false values of the SyncSwitch.
///
......@@ -46,7 +43,7 @@ class SyncSwitch {
/// |SetSwitch| inside of the handlers will result in a self deadlock.
///
/// @param[in] handlers Called for the correct value of the |SyncSwitch|.
void Execute(const Handlers& handlers);
void Execute(const Handlers& handlers) const;
/// Set the value of the SyncSwitch.
///
......@@ -56,7 +53,7 @@ class SyncSwitch {
void SetSwitch(bool value);
private:
std::mutex mutex_;
mutable std::mutex mutex_;
bool value_;
FML_DISALLOW_COPY_AND_ASSIGN(SyncSwitch);
......
......@@ -24,7 +24,8 @@ class IOManager {
virtual fml::RefPtr<flutter::SkiaUnrefQueue> GetSkiaUnrefQueue() const = 0;
virtual std::shared_ptr<fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() = 0;
virtual std::shared_ptr<const fml::SyncSwitch>
GetIsGpuDisabledSyncSwitch() = 0;
};
} // namespace flutter
......
......@@ -71,7 +71,7 @@ class TestIOManager final : public IOManager {
}
// |IOManager|
std::shared_ptr<fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() override {
std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() override {
did_access_is_gpu_disabled_sync_switch_ = true;
return is_gpu_disabled_sync_switch_;
}
......
......@@ -87,7 +87,7 @@ class Rasterizer final : public SnapshotDelegate {
///
/// For example, on some platforms when the application is backgrounded it
/// is critical that GPU operations are not processed.
virtual std::shared_ptr<fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
virtual std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
const = 0;
};
......
......@@ -24,7 +24,7 @@ class MockDelegate : public Rasterizer::Delegate {
MOCK_CONST_METHOD0(GetLatestFrameTargetTime, fml::TimePoint());
MOCK_CONST_METHOD0(GetTaskRunners, const TaskRunners&());
MOCK_CONST_METHOD0(GetIsGpuDisabledSyncSwitch,
std::shared_ptr<fml::SyncSwitch>());
std::shared_ptr<const fml::SyncSwitch>());
};
class MockSurface : public Surface {
......@@ -55,11 +55,11 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder {
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger));
MOCK_METHOD0(GetCurrentCanvases, std::vector<SkCanvas*>());
MOCK_METHOD1(CompositeEmbeddedView, SkCanvas*(int view_id));
MOCK_METHOD3(
SubmitFrame,
void(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch));
MOCK_METHOD3(SubmitFrame,
void(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<const fml::SyncSwitch>&
gpu_disable_sync_switch));
MOCK_METHOD2(EndFrame,
void(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger));
......
......@@ -1806,10 +1806,35 @@ bool Shell::ReloadSystemFonts() {
return true;
}
std::shared_ptr<fml::SyncSwitch> Shell::GetIsGpuDisabledSyncSwitch() const {
std::shared_ptr<const fml::SyncSwitch> Shell::GetIsGpuDisabledSyncSwitch()
const {
return is_gpu_disabled_sync_switch_;
}
void Shell::SetGpuAvailability(GpuAvailability availability) {
switch (availability) {
case GpuAvailability::kAvailable:
is_gpu_disabled_sync_switch_->SetSwitch(false);
return;
case GpuAvailability::kFlushAndMakeUnavailable: {
fml::AutoResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask(
task_runners_.GetIOTaskRunner(),
[io_manager = io_manager_.get(), &latch]() {
io_manager->GetSkiaUnrefQueue()->Drain();
latch.Signal();
});
latch.Wait();
}
// FALLTHROUGH
case GpuAvailability::kUnavailable:
is_gpu_disabled_sync_switch_->SetSwitch(true);
return;
default:
FML_DCHECK(false);
}
}
void Shell::OnDisplayUpdates(DisplayUpdateType update_type,
std::vector<Display> displays) {
display_manager_->HandleDisplayUpdates(update_type, displays);
......
......@@ -53,6 +53,18 @@ enum class DartErrorCode {
UnknownError = 255
};
/// Values for |Shell::SetGpuAvailability|.
enum class GpuAvailability {
/// Indicates that GPU operations should be permitted.
kAvailable = 0,
/// Indicates that the GPU is about to become unavailable, and to attempt to
/// flush any GPU related resources now.
kFlushAndMakeUnavailable = 1,
/// Indicates that the GPU is unavailable, and that no attempt should be made
/// to even flush GPU objects until it is available again.
kUnavailable = 2
};
//------------------------------------------------------------------------------
/// Perhaps the single most important class in the Flutter engine repository.
/// When embedders create a Flutter application, they are referring to the
......@@ -324,8 +336,13 @@ class Shell final : public PlatformView::Delegate,
bool EngineHasLivePorts() const;
//----------------------------------------------------------------------------
/// @brief Accessor for the disable GPU SyncSwitch
std::shared_ptr<fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() const override;
/// @brief Accessor for the disable GPU SyncSwitch.
std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
const override;
//----------------------------------------------------------------------------
/// @brief Marks the GPU as available or unavailable.
void SetGpuAvailability(GpuAvailability availability);
//----------------------------------------------------------------------------
/// @brief Get a pointer to the Dart VM used by this running shell
......
......@@ -53,7 +53,7 @@ sk_sp<GrDirectContext> ShellIOManager::CreateCompatibleResourceLoadingContext(
ShellIOManager::ShellIOManager(
sk_sp<GrDirectContext> resource_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
fml::RefPtr<fml::TaskRunner> unref_queue_task_runner)
: resource_context_(std::move(resource_context)),
resource_context_weak_factory_(
......@@ -125,7 +125,8 @@ fml::WeakPtr<IOManager> ShellIOManager::GetWeakIOManager() const {
}
// |IOManager|
std::shared_ptr<fml::SyncSwitch> ShellIOManager::GetIsGpuDisabledSyncSwitch() {
std::shared_ptr<const fml::SyncSwitch>
ShellIOManager::GetIsGpuDisabledSyncSwitch() {
return is_gpu_disabled_sync_switch_;
}
......
......@@ -24,9 +24,10 @@ class ShellIOManager final : public IOManager {
GrBackend backend,
sk_sp<const GrGLInterface> gl_interface);
ShellIOManager(sk_sp<GrDirectContext> resource_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch,
fml::RefPtr<fml::TaskRunner> unref_queue_task_runner);
ShellIOManager(
sk_sp<GrDirectContext> resource_context,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
fml::RefPtr<fml::TaskRunner> unref_queue_task_runner);
~ShellIOManager() override;
......@@ -53,7 +54,7 @@ class ShellIOManager final : public IOManager {
fml::RefPtr<flutter::SkiaUnrefQueue> GetSkiaUnrefQueue() const override;
// |IOManager|
std::shared_ptr<fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() override;
std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() override;
sk_sp<GrDirectContext> GetSharedResourceContext() const {
return resource_context_;
......@@ -68,7 +69,7 @@ class ShellIOManager final : public IOManager {
// Unref queue management.
fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue_;
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch_;
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch_;
fml::WeakPtrFactory<ShellIOManager> weak_factory_;
......
......@@ -64,7 +64,7 @@ SkCanvas* ShellTestExternalViewEmbedder::CompositeEmbeddedView(int view_id) {
void ShellTestExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch) {
frame->Submit();
if (frame && frame->SkiaSurface()) {
last_submitted_frame_size_ = SkISize::Make(frame->SkiaSurface()->width(),
......
......@@ -62,10 +62,10 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
SkCanvas* CompositeEmbeddedView(int view_id) override;
// |ExternalViewEmbedder|
void SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
void SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<const fml::SyncSwitch>&
gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
void EndFrame(
......
......@@ -76,7 +76,7 @@ SkRect AndroidExternalViewEmbedder::GetViewRect(int view_id) const {
void AndroidExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch) {
TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame");
if (!FrameHasPlatformLayers()) {
......
......@@ -46,10 +46,10 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
std::vector<SkCanvas*> GetCurrentCanvases() override;
// |ExternalViewEmbedder|
void SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
void SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<const fml::SyncSwitch>&
gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
PostPrerollResult PostPrerollAction(
......
......@@ -521,6 +521,8 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
_publisher.reset([[FlutterObservatoryPublisher alloc]
initWithEnableObservatoryPublication:doesObservatoryPublication]);
[self maybeSetupPlatformViewChannels];
_shell->SetGpuAvailability(_isGpuDisabled ? flutter::GpuAvailability::kUnavailable
: flutter::GpuAvailability::kAvailable);
}
+ (BOOL)isProfilerEnabled {
......@@ -897,7 +899,8 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
- (void)setIsGpuDisabled:(BOOL)value {
if (_shell) {
_shell->GetIsGpuDisabledSyncSwitch()->SetSwitch(value ? true : false);
_shell->SetGpuAvailability(value ? flutter::GpuAvailability::kUnavailable
: flutter::GpuAvailability::kAvailable);
}
_isGpuDisabled = value;
}
......
......@@ -466,7 +466,7 @@ 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) {
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch) {
bool result = false;
gpu_disable_sync_switch->Execute(
fml::SyncSwitch::Handlers().SetIfTrue([&] { result = false; }).SetIfFalse([&] {
......
......@@ -174,7 +174,7 @@ class FlutterPlatformViewsController {
bool 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);
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch);
void OnMethodCall(FlutterMethodCall* call, FlutterResult& result);
......
......@@ -53,10 +53,10 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder {
SkCanvas* CompositeEmbeddedView(int view_id) override;
// |ExternalViewEmbedder|
void SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
void SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<const fml::SyncSwitch>&
gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
void EndFrame(
......
......@@ -75,7 +75,7 @@ SkCanvas* IOSExternalViewEmbedder::CompositeEmbeddedView(int view_id) {
void IOSExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
const std::shared_ptr<const 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),
......
......@@ -136,7 +136,7 @@ static FlutterBackingStoreConfig MakeBackingStoreConfig(
void EmbedderExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch) {
auto [matched_render_targets, pending_keys] =
render_target_cache_.GetExistingTargetsInCache(pending_views_);
......
......@@ -97,10 +97,10 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder {
SkCanvas* CompositeEmbeddedView(int view_id) override;
// |ExternalViewEmbedder|
void SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
void SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<const fml::SyncSwitch>&
gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
SkCanvas* GetRootCanvas() override;
......
......@@ -200,7 +200,7 @@ void FuchsiaExternalViewEmbedder::EndFrame(
void FuchsiaExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<flutter::SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
const std::shared_ptr<const 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;
......
......@@ -74,10 +74,10 @@ class FuchsiaExternalViewEmbedder final : public flutter::ExternalViewEmbedder {
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;
// |ExternalViewEmbedder|
void SubmitFrame(
GrDirectContext* context,
std::unique_ptr<flutter::SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) override;
void SubmitFrame(GrDirectContext* context,
std::unique_ptr<flutter::SurfaceFrame> frame,
const std::shared_ptr<const fml::SyncSwitch>&
gpu_disable_sync_switch) override;
// |ExternalViewEmbedder|
void CancelFrame() override { Reset(); }
......
......@@ -46,7 +46,7 @@ class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder {
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override {}
void SubmitFrame(GrDirectContext* context,
std::unique_ptr<flutter::SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>&
const std::shared_ptr<const fml::SyncSwitch>&
gpu_disable_sync_switch) override {
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册