diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index dce9a455e9a7a..3e4cf271b9815 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -280,6 +280,7 @@ FILE: ../../../flutter/lib/ui/plugins.dart FILE: ../../../flutter/lib/ui/plugins/callback_cache.cc FILE: ../../../flutter/lib/ui/plugins/callback_cache.h FILE: ../../../flutter/lib/ui/pointer.dart +FILE: ../../../flutter/lib/ui/resource_context_manager.h FILE: ../../../flutter/lib/ui/semantics.dart FILE: ../../../flutter/lib/ui/semantics/custom_accessibility_action.cc FILE: ../../../flutter/lib/ui/semantics/custom_accessibility_action.h diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index dcfd483638eca..e880e96fb5f42 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -57,6 +57,7 @@ source_set("ui") { "painting/vertices.h", "plugins/callback_cache.cc", "plugins/callback_cache.h", + "resource_context_manager.h", "semantics/custom_accessibility_action.cc", "semantics/custom_accessibility_action.h", "semantics/semantics_node.cc", diff --git a/lib/ui/resource_context_manager.h b/lib/ui/resource_context_manager.h new file mode 100644 index 0000000000000..5583f5644d583 --- /dev/null +++ b/lib/ui/resource_context_manager.h @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_LIB_UI_RESOURCE_CONTEXT_MANAGER_H_ +#define FLUTTER_LIB_UI_RESOURCE_CONTEXT_MANAGER_H_ + +#include "flutter/fml/memory/weak_ptr.h" +#include "third_party/skia/include/gpu/GrContext.h" + +namespace blink { +// Interface for methods that manage the GrContext creation, access, and +// release. Meant to be implemented by the owner of the GLContext, e.g. the +// PlatformView. These methods may be called from a non-platform task runner. +class ResourceContextManager { + public: + virtual sk_sp CreateResourceContext() = 0; + + // In almost all situations, this should be prefered to + // `CreateResourceContext`. This will get the currently applicable GrContext + // on the calling thread for the current GrContext, if one is available. + // Calling this will ensure that, in the event the GLContext has changed, the + // correct GrContext for the current GLContext will be used. Unlike all other + // methods on the platform view, this one may be called on a non-platform task + // runner. + virtual sk_sp GetOrCreateResourceContext() = 0; + + virtual fml::WeakPtr GetOrCreateWeakResourceContext() = 0; + + virtual void ReleaseResourceContext() const = 0; +}; + +} // namespace blink + +#endif // FLUTTER_LIB_UI_RESOURCE_CONTEXT_MANAGER_H_ diff --git a/lib/ui/ui_dart_state.cc b/lib/ui/ui_dart_state.cc index 5d0f0d73c72ec..4e59d08553b89 100644 --- a/lib/ui/ui_dart_state.cc +++ b/lib/ui/ui_dart_state.cc @@ -13,21 +13,22 @@ using tonic::ToDart; namespace blink { -UIDartState::UIDartState(TaskRunners task_runners, - TaskObserverAdd add_callback, - TaskObserverRemove remove_callback, - fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr skia_unref_queue, - std::string advisory_script_uri, - std::string advisory_script_entrypoint, - std::string logger_prefix, - IsolateNameServer* isolate_name_server) +UIDartState::UIDartState( + TaskRunners task_runners, + TaskObserverAdd add_callback, + TaskObserverRemove remove_callback, + fml::WeakPtr snapshot_delegate, + fml::WeakPtr resource_context_manager, + fml::RefPtr skia_unref_queue, + std::string advisory_script_uri, + std::string advisory_script_entrypoint, + std::string logger_prefix, + IsolateNameServer* isolate_name_server) : task_runners_(std::move(task_runners)), add_callback_(std::move(add_callback)), remove_callback_(std::move(remove_callback)), snapshot_delegate_(std::move(snapshot_delegate)), - resource_context_(std::move(resource_context)), + resource_context_manager_(std::move(resource_context_manager)), advisory_script_uri_(std::move(advisory_script_uri)), advisory_script_entrypoint_(std::move(advisory_script_entrypoint)), logger_prefix_(std::move(logger_prefix)), @@ -114,7 +115,7 @@ fml::WeakPtr UIDartState::GetSnapshotDelegate() const { } fml::WeakPtr UIDartState::GetResourceContext() const { - return resource_context_; + return resource_context_manager_->GetOrCreateWeakResourceContext(); } IsolateNameServer* UIDartState::GetIsolateNameServer() { diff --git a/lib/ui/ui_dart_state.h b/lib/ui/ui_dart_state.h index ce81804937f63..53e25692c36de 100644 --- a/lib/ui/ui_dart_state.h +++ b/lib/ui/ui_dart_state.h @@ -15,6 +15,7 @@ #include "flutter/fml/build_config.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/lib/ui/isolate_name_server/isolate_name_server.h" +#include "flutter/lib/ui/resource_context_manager.h" #include "flutter/lib/ui/snapshot_delegate.h" #include "third_party/dart/runtime/include/dart_api.h" #include "third_party/skia/include/gpu/GrContext.h" @@ -72,7 +73,7 @@ class UIDartState : public tonic::DartState { TaskObserverAdd add_callback, TaskObserverRemove remove_callback, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, + fml::WeakPtr resource_context_manager, fml::RefPtr skia_unref_queue, std::string advisory_script_uri, std::string advisory_script_entrypoint, @@ -94,7 +95,7 @@ class UIDartState : public tonic::DartState { const TaskObserverAdd add_callback_; const TaskObserverRemove remove_callback_; fml::WeakPtr snapshot_delegate_; - fml::WeakPtr resource_context_; + fml::WeakPtr resource_context_manager_; const std::string advisory_script_uri_; const std::string advisory_script_entrypoint_; const std::string logger_prefix_; diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index 094746b26d0ed..305b05ddd941d 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -35,7 +35,7 @@ std::weak_ptr DartIsolate::CreateRootIsolate( TaskRunners task_runners, std::unique_ptr window, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, + fml::WeakPtr resource_context_manager, fml::RefPtr unref_queue, std::string advisory_script_uri, std::string advisory_script_entrypoint, @@ -51,15 +51,15 @@ std::weak_ptr DartIsolate::CreateRootIsolate( // isolate lifecycle is entirely managed by the VM). auto root_embedder_data = std::make_unique>( std::make_shared( - vm, // VM - std::move(isolate_snapshot), // isolate snapshot - std::move(shared_snapshot), // shared snapshot - task_runners, // task runners - std::move(snapshot_delegate), // snapshot delegate - std::move(resource_context), // resource context - std::move(unref_queue), // skia unref queue - advisory_script_uri, // advisory URI - advisory_script_entrypoint, // advisory entrypoint + vm, // VM + std::move(isolate_snapshot), // isolate snapshot + std::move(shared_snapshot), // shared snapshot + task_runners, // task runners + std::move(snapshot_delegate), // snapshot delegate + std::move(resource_context_manager), // resource context_manager + std::move(unref_queue), // skia unref queue + advisory_script_uri, // advisory URI + advisory_script_entrypoint, // advisory entrypoint nullptr // child isolate preparer will be set when this isolate is // prepared to run )); @@ -95,21 +95,22 @@ std::weak_ptr DartIsolate::CreateRootIsolate( return embedder_isolate; } -DartIsolate::DartIsolate(DartVM* vm, - fml::RefPtr isolate_snapshot, - fml::RefPtr shared_snapshot, - TaskRunners task_runners, - fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, - std::string advisory_script_uri, - std::string advisory_script_entrypoint, - ChildIsolatePreparer child_isolate_preparer) +DartIsolate::DartIsolate( + DartVM* vm, + fml::RefPtr isolate_snapshot, + fml::RefPtr shared_snapshot, + TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, + fml::WeakPtr resource_context_manager, + fml::RefPtr unref_queue, + std::string advisory_script_uri, + std::string advisory_script_entrypoint, + ChildIsolatePreparer child_isolate_preparer) : UIDartState(std::move(task_runners), vm->GetSettings().task_observer_add, vm->GetSettings().task_observer_remove, std::move(snapshot_delegate), - std::move(resource_context), + std::move(resource_context_manager), std::move(unref_queue), advisory_script_uri, advisory_script_entrypoint, @@ -645,9 +646,9 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair( (*raw_embedder_isolate)->GetSharedSnapshot(), // shared_snapshot null_task_runners, // task_runners fml::WeakPtr{}, // snapshot_delegate - fml::WeakPtr{}, // resource_context - nullptr, // unref_queue - advisory_script_uri, // advisory_script_uri + fml::WeakPtr{}, // resource_context_manager + nullptr, // unref_queue + advisory_script_uri, // advisory_script_uri advisory_script_entrypoint, // advisory_script_entrypoint (*raw_embedder_isolate)->child_isolate_preparer_)); } diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h index d79cc6c6b6803..65a05632151a5 100644 --- a/runtime/dart_isolate.h +++ b/runtime/dart_isolate.h @@ -12,6 +12,7 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" #include "flutter/fml/mapping.h" +#include "flutter/lib/ui/resource_context_manager.h" #include "flutter/lib/ui/snapshot_delegate.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/window.h" @@ -46,7 +47,7 @@ class DartIsolate : public UIDartState { TaskRunners task_runners, std::unique_ptr window, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, + fml::WeakPtr resource_context_manager, fml::RefPtr unref_queue, std::string advisory_script_uri, std::string advisory_script_entrypoint, @@ -57,7 +58,7 @@ class DartIsolate : public UIDartState { fml::RefPtr shared_snapshot, TaskRunners task_runners, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, + fml::WeakPtr resource_context_manager, fml::RefPtr unref_queue, std::string advisory_script_uri, std::string advisory_script_entrypoint, diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index ac99aa5f99ac5..3afbf9aa542ac 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -21,7 +21,7 @@ RuntimeController::RuntimeController( fml::RefPtr p_shared_snapshot, TaskRunners p_task_runners, fml::WeakPtr p_snapshot_delegate, - fml::WeakPtr p_resource_context, + fml::WeakPtr p_resource_context_manager, fml::RefPtr p_unref_queue, std::string p_advisory_script_uri, std::string p_advisory_script_entrypoint) @@ -31,7 +31,7 @@ RuntimeController::RuntimeController( std::move(p_shared_snapshot), std::move(p_task_runners), std::move(p_snapshot_delegate), - std::move(p_resource_context), + std::move(p_resource_context_manager), std::move(p_unref_queue), std::move(p_advisory_script_uri), std::move(p_advisory_script_entrypoint), @@ -44,7 +44,7 @@ RuntimeController::RuntimeController( fml::RefPtr p_shared_snapshot, TaskRunners p_task_runners, fml::WeakPtr p_snapshot_delegate, - fml::WeakPtr p_resource_context, + fml::WeakPtr p_resource_context_manager, fml::RefPtr p_unref_queue, std::string p_advisory_script_uri, std::string p_advisory_script_entrypoint, @@ -55,7 +55,7 @@ RuntimeController::RuntimeController( shared_snapshot_(std::move(p_shared_snapshot)), task_runners_(p_task_runners), snapshot_delegate_(p_snapshot_delegate), - resource_context_(p_resource_context), + resource_context_manager_(p_resource_context_manager), unref_queue_(p_unref_queue), advisory_script_uri_(p_advisory_script_uri), advisory_script_entrypoint_(p_advisory_script_entrypoint), @@ -67,7 +67,7 @@ RuntimeController::RuntimeController( task_runners_, std::make_unique(this), snapshot_delegate_, - resource_context_, + resource_context_manager_, unref_queue_, p_advisory_script_uri, p_advisory_script_entrypoint)) { @@ -116,7 +116,7 @@ std::unique_ptr RuntimeController::Clone() const { shared_snapshot_, // task_runners_, // snapshot_delegate_, // - resource_context_, // + resource_context_manager_, // unref_queue_, // advisory_script_uri_, // advisory_script_entrypoint_, // diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 05278740735de..2cc727fec85ed 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -11,6 +11,7 @@ #include "flutter/common/task_runners.h" #include "flutter/flow/layers/layer_tree.h" #include "flutter/fml/macros.h" +#include "flutter/lib/ui/resource_context_manager.h" #include "flutter/lib/ui/text/font_collection.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/pointer_data_packet.h" @@ -27,16 +28,17 @@ class Window; class RuntimeController final : public WindowClient { public: - RuntimeController(RuntimeDelegate& client, - DartVM* vm, - fml::RefPtr isolate_snapshot, - fml::RefPtr shared_snapshot, - TaskRunners task_runners, - fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, - std::string advisory_script_uri, - std::string advisory_script_entrypoint); + RuntimeController( + RuntimeDelegate& client, + DartVM* vm, + fml::RefPtr isolate_snapshot, + fml::RefPtr shared_snapshot, + TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, + fml::WeakPtr resource_context_manager, + fml::RefPtr unref_queue, + std::string advisory_script_uri, + std::string advisory_script_entrypoint); ~RuntimeController() override; @@ -121,7 +123,7 @@ class RuntimeController final : public WindowClient { fml::RefPtr shared_snapshot_; TaskRunners task_runners_; fml::WeakPtr snapshot_delegate_; - fml::WeakPtr resource_context_; + fml::WeakPtr resource_context_manager_; fml::RefPtr unref_queue_; std::string advisory_script_uri_; std::string advisory_script_entrypoint_; @@ -129,17 +131,18 @@ class RuntimeController final : public WindowClient { std::weak_ptr root_isolate_; std::pair root_isolate_return_code_ = {false, 0}; - RuntimeController(RuntimeDelegate& client, - DartVM* vm, - fml::RefPtr isolate_snapshot, - fml::RefPtr shared_snapshot, - TaskRunners task_runners, - fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, - std::string advisory_script_uri, - std::string advisory_script_entrypoint, - WindowData data); + RuntimeController( + RuntimeDelegate& client, + DartVM* vm, + fml::RefPtr isolate_snapshot, + fml::RefPtr shared_snapshot, + TaskRunners task_runners, + fml::WeakPtr snapshot_delegate, + fml::WeakPtr resource_context_manager, + fml::RefPtr unref_queue, + std::string advisory_script_uri, + std::string advisory_script_entrypoint, + WindowData data); Window* GetWindowIfAvailable(); diff --git a/shell/common/engine.cc b/shell/common/engine.cc index ef3369347e055..0d65df8a5fe47 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -34,16 +34,17 @@ static constexpr char kNavigationChannel[] = "flutter/navigation"; static constexpr char kLocalizationChannel[] = "flutter/localization"; static constexpr char kSettingsChannel[] = "flutter/settings"; -Engine::Engine(Delegate& delegate, - blink::DartVM& vm, - fml::RefPtr isolate_snapshot, - fml::RefPtr shared_snapshot, - blink::TaskRunners task_runners, - blink::Settings settings, - std::unique_ptr animator, - fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue) +Engine::Engine( + Delegate& delegate, + blink::DartVM& vm, + fml::RefPtr isolate_snapshot, + fml::RefPtr shared_snapshot, + blink::TaskRunners task_runners, + blink::Settings settings, + std::unique_ptr animator, + fml::WeakPtr snapshot_delegate, + fml::WeakPtr resource_context_manager, + fml::RefPtr unref_queue) : delegate_(delegate), settings_(std::move(settings)), animator_(std::move(animator)), @@ -60,7 +61,7 @@ Engine::Engine(Delegate& delegate, std::move(shared_snapshot), // shared snapshot std::move(task_runners), // task runners std::move(snapshot_delegate), // snapshot delegate - std::move(resource_context), // resource context + std::move(resource_context_manager), // resource context std::move(unref_queue), // skia unref queue settings_.advisory_script_uri, // advisory script uri settings_.advisory_script_entrypoint // advisory script entrypoint diff --git a/shell/common/engine.h b/shell/common/engine.h index 2b72592575526..595c5d47cb844 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -12,6 +12,7 @@ #include "flutter/common/task_runners.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" +#include "flutter/lib/ui/resource_context_manager.h" #include "flutter/lib/ui/semantics/custom_accessibility_action.h" #include "flutter/lib/ui/semantics/semantics_node.h" #include "flutter/lib/ui/snapshot_delegate.h" @@ -61,7 +62,7 @@ class Engine final : public blink::RuntimeDelegate { blink::Settings settings, std::unique_ptr animator, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, + fml::WeakPtr resource_context_manager, fml::RefPtr unref_queue); ~Engine() override; diff --git a/shell/common/io_manager.cc b/shell/common/io_manager.cc index c6ff79b644f30..2a0babf426d40 100644 --- a/shell/common/io_manager.cc +++ b/shell/common/io_manager.cc @@ -5,6 +5,7 @@ #include "flutter/shell/common/io_manager.h" #include "flutter/fml/message_loop.h" +#include "flutter/lib/ui/resource_context_manager.h" #include "flutter/shell/common/persistent_cache.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" @@ -12,6 +13,7 @@ namespace shell { sk_sp IOManager::CreateCompatibleResourceLoadingContext( GrBackend backend) { + FML_DLOG(ERROR) << "Creating resource context for iomanager"; if (backend != GrBackend::kOpenGL_GrBackend) { return nullptr; } @@ -41,23 +43,14 @@ sk_sp IOManager::CreateCompatibleResourceLoadingContext( return nullptr; } -IOManager::IOManager(sk_sp resource_context, - fml::RefPtr unref_queue_task_runner) - : resource_context_(std::move(resource_context)), - resource_context_weak_factory_( - resource_context_ ? std::make_unique>( - resource_context_.get()) - : nullptr), +IOManager::IOManager( + fml::WeakPtr resource_context_manager, + fml::RefPtr unref_queue_task_runner) + : resource_context_manager_(std::move(resource_context_manager)), unref_queue_(fml::MakeRefCounted( std::move(unref_queue_task_runner), fml::TimeDelta::FromMilliseconds(250))), - weak_factory_(this) { - if (!resource_context_) { - FML_DLOG(WARNING) << "The IO manager was initialized without a resource " - "context. Async texture uploads will be disabled. " - "Expect performance degradation."; - } -} + weak_factory_(this) {} IOManager::~IOManager() { // Last chance to drain the IO queue as the platform side reference to the @@ -66,9 +59,14 @@ IOManager::~IOManager() { } fml::WeakPtr IOManager::GetResourceContext() const { - return resource_context_weak_factory_ - ? resource_context_weak_factory_->GetWeakPtr() - : fml::WeakPtr(); + auto resource_context = + resource_context_manager_->GetOrCreateWeakResourceContext(); + if (!resource_context) { + FML_DLOG(WARNING) << "The IO manager was unable to get a resource " + "context. Async texture uploads will be disabled. " + "Expect performance degradation."; + } + return resource_context; } fml::RefPtr IOManager::GetSkiaUnrefQueue() const { diff --git a/shell/common/io_manager.h b/shell/common/io_manager.h index 2d6ec241d886d..e43c38e9e70ee 100644 --- a/shell/common/io_manager.h +++ b/shell/common/io_manager.h @@ -10,6 +10,7 @@ #include "flutter/flow/skia_gpu_object.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" +#include "flutter/lib/ui/resource_context_manager.h" #include "third_party/skia/include/gpu/GrContext.h" namespace shell { @@ -22,8 +23,9 @@ class IOManager { static sk_sp CreateCompatibleResourceLoadingContext( GrBackend backend); - IOManager(sk_sp resource_context, - fml::RefPtr unref_queue_task_runner); + IOManager( + fml::WeakPtr resource_context_manager, + fml::RefPtr unref_queue_task_runner); ~IOManager(); @@ -33,9 +35,7 @@ class IOManager { private: // Resource context management. - sk_sp resource_context_; - std::unique_ptr> - resource_context_weak_factory_; + fml::WeakPtr resource_context_manager_; // Unref queue management. fml::RefPtr unref_queue_; diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 4a4e7df074248..ea284e1300ac2 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -67,12 +67,26 @@ void PlatformView::NotifyDestroyed() { delegate_.OnPlatformViewDestroyed(); } -sk_sp PlatformView::CreateResourceContext() const { +sk_sp PlatformView::CreateResourceContext() { FML_DLOG(WARNING) << "This platform does not setup the resource " "context on the IO thread for async texture uploads."; return nullptr; } +sk_sp PlatformView::GetOrCreateResourceContext() { + FML_DLOG(WARNING) << "This platform does not setup the resource " + "context on the IO thread for async texture uploads."; + return nullptr; +} + +fml::WeakPtr PlatformView::GetOrCreateWeakResourceContext() { + auto context = GetOrCreateResourceContext(); + if (context) { + return fml::WeakPtrFactory(context.get()).GetWeakPtr(); + } + return fml::WeakPtr(); +} + void PlatformView::ReleaseResourceContext() const {} fml::WeakPtr PlatformView::GetWeakPtr() const { diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index ed3b6e999a3ea..4d896924efaec 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -11,6 +11,7 @@ #include "flutter/flow/texture.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" +#include "flutter/lib/ui/resource_context_manager.h" #include "flutter/lib/ui/semantics/custom_accessibility_action.h" #include "flutter/lib/ui/semantics/semantics_node.h" #include "flutter/lib/ui/window/platform_message.h" @@ -25,7 +26,7 @@ namespace shell { class Shell; -class PlatformView { +class PlatformView : public blink::ResourceContextManager { public: class Delegate { public: @@ -84,14 +85,6 @@ class PlatformView { virtual void NotifyDestroyed(); - // Unlike all other methods on the platform view, this one may be called on a - // non-platform task runner. - virtual sk_sp CreateResourceContext() const; - - // Unlike all other methods on the platform view, this one may be called on a - // non-platform task runner. - virtual void ReleaseResourceContext() const; - fml::WeakPtr GetWeakPtr() const; virtual void UpdateSemantics(blink::SemanticsNodeUpdates updates, @@ -116,6 +109,14 @@ class PlatformView { // Called once per texture update (e.g. video frame), on the platform thread. void MarkTextureFrameAvailable(int64_t texture_id); + virtual sk_sp CreateResourceContext() override; + + virtual sk_sp GetOrCreateResourceContext() override; + + virtual fml::WeakPtr GetOrCreateWeakResourceContext() override; + + virtual void ReleaseResourceContext() const override; + protected: PlatformView::Delegate& delegate_; const blink::TaskRunners task_runners_; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 1847c115f51bb..c58a576151521 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -65,21 +65,18 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // other subsystems. fml::AutoResetWaitableEvent io_latch; std::unique_ptr io_manager; - fml::WeakPtr resource_context; fml::RefPtr unref_queue; auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner(); fml::TaskRunner::RunNowOrPostTask( io_task_runner, - [&io_latch, // - &io_manager, // - &resource_context, // - &unref_queue, // - &platform_view, // - io_task_runner // + [&io_latch, // + &io_manager, // + &unref_queue, // + &platform_view, // + io_task_runner // ]() { - io_manager = std::make_unique( - platform_view->CreateResourceContext(), io_task_runner); - resource_context = io_manager->GetResourceContext(); + io_manager = std::make_unique(platform_view->GetWeakPtr(), + io_task_runner); unref_queue = io_manager->GetSkiaUnrefQueue(); io_latch.Signal(); }); @@ -117,7 +114,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( shared_snapshot = std::move(shared_snapshot), // vsync_waiter = std::move(vsync_waiter), // snapshot_delegate = std::move(snapshot_delegate), // - resource_context = std::move(resource_context), // + platform_view = platform_view->GetWeakPtr(), // unref_queue = std::move(unref_queue) // ]() mutable { const auto& task_runners = shell->GetTaskRunners(); @@ -135,7 +132,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( shell->GetSettings(), // std::move(animator), // std::move(snapshot_delegate), // - std::move(resource_context), // + std::move(platform_view), // std::move(unref_queue) // ); ui_latch.Signal(); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 034c059695014..e8869948c6876 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -369,22 +369,30 @@ std::unique_ptr PlatformViewAndroid::CreateRenderingSurface() { } // |shell::PlatformView| -sk_sp PlatformViewAndroid::CreateResourceContext() const { +sk_sp PlatformViewAndroid::CreateResourceContext() { if (!android_surface_) { return nullptr; } - sk_sp resource_context; if (android_surface_->ResourceContextMakeCurrent()) { // TODO(chinmaygarde): Currently, this code depends on the fact that only // the OpenGL surface will be able to make a resource context current. If // this changes, this assumption breaks. Handle the same. - resource_context = IOManager::CreateCompatibleResourceLoadingContext( + resource_context_ = IOManager::CreateCompatibleResourceLoadingContext( GrBackend::kOpenGL_GrBackend); } else { FML_DLOG(ERROR) << "Could not make the resource context current."; } - return resource_context; + return resource_context_; +} + +// |shell::PlatformView| +sk_sp PlatformViewAndroid::GetOrCreateResourceContext() { + if (!resource_context_ || resource_context_->abandoned()) { + return CreateResourceContext(); + } + + return resource_context_; } // |shell::PlatformView| diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index c162ac5a2e8f3..99613d6571512 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -80,6 +80,7 @@ class PlatformViewAndroid final : public PlatformView { int next_response_id_ = 1; std::unordered_map> pending_responses_; + sk_sp resource_context_; // |shell::PlatformView| void UpdateSemantics( @@ -100,7 +101,10 @@ class PlatformViewAndroid final : public PlatformView { std::unique_ptr CreateRenderingSurface() override; // |shell::PlatformView| - sk_sp CreateResourceContext() const override; + sk_sp CreateResourceContext() override; + + // |shell::PlatformView| + sk_sp GetOrCreateResourceContext() override; // |shell::PlatformView| void ReleaseResourceContext() const override; diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index a0d85a7ffd0f9..fe7da8470bc72 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -47,6 +47,7 @@ class PlatformViewIOS final : public PlatformView { std::unique_ptr accessibility_bridge_; fml::scoped_nsprotocol text_input_plugin_; fml::closure firstFrameCallback_; + sk_sp resource_context_; // |shell::PlatformView| void HandlePlatformMessage(fml::RefPtr message) override; @@ -55,7 +56,10 @@ class PlatformViewIOS final : public PlatformView { std::unique_ptr CreateRenderingSurface() override; // |shell::PlatformView| - sk_sp CreateResourceContext() const override; + sk_sp CreateResourceContext() override; + + // |shell::PlatformView| + sk_sp GetOrCreateResourceContext() override; // |shell::PlatformView| void SetSemanticsEnabled(bool enabled) override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index f3371a9834a53..785313b028b0d 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -39,6 +39,7 @@ void PlatformViewIOS::SetOwnerViewController(fml::WeakPtr owner_controller) { if (ios_surface_ || !owner_controller) { NotifyDestroyed(); + resource_context_->releaseResourcesAndAbandonContext(); ios_surface_.reset(); accessibility_bridge_.reset(); } @@ -74,7 +75,7 @@ } // |shell::PlatformView| -sk_sp PlatformViewIOS::CreateResourceContext() const { +sk_sp PlatformViewIOS::CreateResourceContext() { if (!ios_surface_ || !ios_surface_->ResourceContextMakeCurrent()) { FML_DLOG(INFO) << "Could not make resource context current on IO thread. " "Async texture uploads " @@ -82,7 +83,18 @@ return nullptr; } - return IOManager::CreateCompatibleResourceLoadingContext(GrBackend::kOpenGL_GrBackend); + resource_context_ = + IOManager::CreateCompatibleResourceLoadingContext(GrBackend::kOpenGL_GrBackend); + return resource_context_; +} + +// |shell::PlatformView| +sk_sp PlatformViewIOS::GetOrCreateResourceContext() { + if (!resource_context_ || resource_context_->abandoned()) { + return CreateResourceContext(); + } + + return resource_context_; } // |shell::PlatformView| diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index 5a5551b751729..6bef46bed0207 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -59,12 +59,21 @@ std::unique_ptr PlatformViewEmbedder::CreateRenderingSurface() { } // |shell::PlatformView| -sk_sp PlatformViewEmbedder::CreateResourceContext() const { +sk_sp PlatformViewEmbedder::CreateResourceContext() { if (embedder_surface_ == nullptr) { FML_LOG(ERROR) << "Embedder surface was null."; return nullptr; } - return embedder_surface_->CreateResourceContext(); + resource_context_ = embedder_surface_->CreateResourceContext(); + return resource_context_; +} + +sk_sp PlatformViewEmbedder::GetOrCreateResourceContext() { + if (!resource_context_ || resource_context_->abandoned()) { + return CreateResourceContext(); + } + + return resource_context_; } } // namespace shell diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index bea840387e7e1..f6be78328095d 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -49,12 +49,16 @@ class PlatformViewEmbedder final : public PlatformView { private: std::unique_ptr embedder_surface_; PlatformDispatchTable platform_dispatch_table_; + sk_sp resource_context_; // |shell::PlatformView| std::unique_ptr CreateRenderingSurface() override; // |shell::PlatformView| - sk_sp CreateResourceContext() const override; + sk_sp CreateResourceContext() override; + + // |shell::PlatformView| + sk_sp GetOrCreateResourceContext() override; FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewEmbedder); };