From 0df44e9e0736b6f21be32d103d2443c3c0e1fc3e Mon Sep 17 00:00:00 2001 From: David Worsham Date: Thu, 13 Jun 2019 10:16:21 -0700 Subject: [PATCH] [scene_host] Expose Opacity and remove ExportNode (#9297) SCN-947 #comment SCN-1291 #comment --- ci/licenses_golden/licenses_flutter | 2 - flow/BUILD.gn | 2 - flow/export_node.cc | 80 ---------------- flow/export_node.h | 50 ---------- flow/layers/child_scene_layer.cc | 18 +--- flow/layers/child_scene_layer.h | 2 - flow/view_holder.cc | 43 ++++++--- flow/view_holder.h | 22 +++-- lib/stub_ui/lib/src/ui/compositing.dart | 36 ++++--- lib/ui/compositing.dart | 44 ++++----- lib/ui/compositing/scene_builder.cc | 4 +- lib/ui/compositing/scene_host.cc | 122 ++++++++++-------------- lib/ui/compositing/scene_host.h | 23 ++--- 13 files changed, 151 insertions(+), 297 deletions(-) delete mode 100644 flow/export_node.cc delete mode 100644 flow/export_node.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index db42ac8f387e0..873841def76fa 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -30,8 +30,6 @@ FILE: ../../../flutter/flow/debug_print.cc FILE: ../../../flutter/flow/debug_print.h FILE: ../../../flutter/flow/embedded_views.cc FILE: ../../../flutter/flow/embedded_views.h -FILE: ../../../flutter/flow/export_node.cc -FILE: ../../../flutter/flow/export_node.h FILE: ../../../flutter/flow/instrumentation.cc FILE: ../../../flutter/flow/instrumentation.h FILE: ../../../flutter/flow/layers/backdrop_filter_layer.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 589b0103f0ef2..c578a95bd6a18 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -76,8 +76,6 @@ source_set("flow") { if (is_fuchsia) { sources += [ - "export_node.cc", - "export_node.h", "layers/child_scene_layer.cc", "layers/child_scene_layer.h", "scene_update_context.cc", diff --git a/flow/export_node.cc b/flow/export_node.cc deleted file mode 100644 index 318b52ff3cc27..0000000000000 --- a/flow/export_node.cc +++ /dev/null @@ -1,80 +0,0 @@ -// 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. - -#include "flutter/flow/export_node.h" - -#include "flutter/fml/thread_local.h" - -namespace { - -using ExportNodeBindings = - std::unordered_map>; - -FML_THREAD_LOCAL fml::ThreadLocalUniquePtr - tls_export_node_bindings; - -} // namespace - -namespace flutter { - -ExportNode::ExportNode(zx::eventpair export_token) - : pending_export_token_(std::move(export_token)) { - FML_DCHECK(pending_export_token_); -} - -void ExportNode::Create(zx_koid_t id, zx::eventpair export_token) { - // This GPU thread contains at least 1 ViewHolder. Initialize the per-thread - // bindings. - if (tls_export_node_bindings.get() == nullptr) { - tls_export_node_bindings.reset(new ExportNodeBindings()); - } - - auto* bindings = tls_export_node_bindings.get(); - FML_DCHECK(bindings); - FML_DCHECK(bindings->find(id) == bindings->end()); - - auto export_node = - std::unique_ptr(new ExportNode(std::move(export_token))); - bindings->emplace(id, std::move(export_node)); -} - -void ExportNode::Destroy(zx_koid_t id) { - auto* bindings = tls_export_node_bindings.get(); - FML_DCHECK(bindings); - - bindings->erase(id); -} - -ExportNode* ExportNode::FromId(zx_koid_t id) { - auto* bindings = tls_export_node_bindings.get(); - if (!bindings) { - return nullptr; - } - - auto binding = bindings->find(id); - if (binding == bindings->end()) { - return nullptr; - } - - return binding->second.get(); -} - -void ExportNode::UpdateScene(SceneUpdateContext& context, - const SkPoint& offset, - const SkSize& size, - bool hit_testable) { - if (pending_export_token_) { - export_node_ = std::make_unique(context.session()); - export_node_->Export(std::move(pending_export_token_)); - } - FML_DCHECK(export_node_); - - context.top_entity()->entity_node().AddChild(*export_node_); - export_node_->SetTranslation(offset.x(), offset.y(), -0.1f); - export_node_->SetHitTestBehavior( - hit_testable ? fuchsia::ui::gfx::HitTestBehavior::kDefault - : fuchsia::ui::gfx::HitTestBehavior::kSuppress); -} - -} // namespace flutter diff --git a/flow/export_node.h b/flow/export_node.h deleted file mode 100644 index dfc72052d65fd..0000000000000 --- a/flow/export_node.h +++ /dev/null @@ -1,50 +0,0 @@ -// 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_FLOW_EXPORT_NODE_H_ -#define FLUTTER_FLOW_EXPORT_NODE_H_ - -#include -#include -#include -#include -#include -#include - -#include - -#include "flutter/flow/scene_update_context.h" -#include "flutter/fml/macros.h" - -namespace flutter { - -// Represents a Scenic |ExportNode| resource that exports an |EntityNode| to -// another session. -// -// This object is created and destroyed on the |Rasterizer|'s' thread. -class ExportNode { - public: - static void Create(zx_koid_t id, zx::eventpair export_token); - static void Destroy(zx_koid_t id); - static ExportNode* FromId(zx_koid_t id); - - // Creates or updates the contained EntityNode resource using the specified - // |SceneUpdateContext|. - void UpdateScene(SceneUpdateContext& context, - const SkPoint& offset, - const SkSize& size, - bool hit_testable); - - private: - ExportNode(zx::eventpair export_token); - - zx::eventpair pending_export_token_; - std::unique_ptr export_node_; - - FML_DISALLOW_COPY_AND_ASSIGN(ExportNode); -}; - -} // namespace flutter - -#endif // FLUTTER_FLOW_EXPORT_NODE_H_ diff --git a/flow/layers/child_scene_layer.cc b/flow/layers/child_scene_layer.cc index 37937f1af71b3..f4100be2fee69 100644 --- a/flow/layers/child_scene_layer.cc +++ b/flow/layers/child_scene_layer.cc @@ -4,21 +4,18 @@ #include "flutter/flow/layers/child_scene_layer.h" -#include "flutter/flow/export_node.h" #include "flutter/flow/view_holder.h" namespace flutter { ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id, - bool use_view_holder, const SkPoint& offset, const SkSize& size, bool hit_testable) : layer_id_(layer_id), offset_(offset), size_(size), - hit_testable_(hit_testable), - use_view_holder_(use_view_holder) {} + hit_testable_(hit_testable) {} void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { set_needs_system_composite(true); @@ -31,17 +28,10 @@ void ChildSceneLayer::Paint(PaintContext& context) const { void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) { FML_DCHECK(needs_system_composite()); - if (use_view_holder_) { - auto* view_holder = ViewHolder::FromId(layer_id_); - FML_DCHECK(view_holder); + auto* view_holder = ViewHolder::FromId(layer_id_); + FML_DCHECK(view_holder); - view_holder->UpdateScene(context, offset_, size_, hit_testable_); - } else { - auto* export_node = ExportNode::FromId(layer_id_); - FML_DCHECK(export_node); - - export_node->UpdateScene(context, offset_, size_, hit_testable_); - } + view_holder->UpdateScene(context, offset_, size_, hit_testable_); } } // namespace flutter diff --git a/flow/layers/child_scene_layer.h b/flow/layers/child_scene_layer.h index d3639850da4f6..b5e26315899e5 100644 --- a/flow/layers/child_scene_layer.h +++ b/flow/layers/child_scene_layer.h @@ -18,7 +18,6 @@ namespace flutter { class ChildSceneLayer : public Layer { public: ChildSceneLayer(zx_koid_t layer_id, - bool use_view_holder, const SkPoint& offset, const SkSize& size, bool hit_testable); @@ -35,7 +34,6 @@ class ChildSceneLayer : public Layer { SkPoint offset_; SkSize size_; bool hit_testable_ = true; - bool use_view_holder_ = true; FML_DISALLOW_COPY_AND_ASSIGN(ChildSceneLayer); }; diff --git a/flow/view_holder.cc b/flow/view_holder.cc index 2baba58f67f60..688f56d0987a7 100644 --- a/flow/view_holder.cc +++ b/flow/view_holder.cc @@ -48,16 +48,6 @@ fuchsia::ui::gfx::ViewProperties ToViewProperties(float width, namespace flutter { -ViewHolder::ViewHolder(fml::RefPtr ui_task_runner, - fuchsia::ui::views::ViewHolderToken view_holder_token, - BindCallback on_bind_callback) - : pending_view_holder_token_(std::move(view_holder_token)), - ui_task_runner_(std::move(ui_task_runner)), - pending_bind_callback_(std::move(on_bind_callback)) { - FML_DCHECK(pending_view_holder_token_.value); - FML_DCHECK(ui_task_runner_); -} - void ViewHolder::Create(zx_koid_t id, fml::RefPtr ui_task_runner, fuchsia::ui::views::ViewHolderToken view_holder_token, @@ -72,9 +62,9 @@ void ViewHolder::Create(zx_koid_t id, FML_DCHECK(bindings); FML_DCHECK(bindings->find(id) == bindings->end()); - auto view_holder = std::unique_ptr( - new ViewHolder(std::move(ui_task_runner), std::move(view_holder_token), - std::move(on_bind_callback))); + auto view_holder = std::make_unique(std::move(ui_task_runner), + std::move(view_holder_token), + std::move(on_bind_callback)); bindings->emplace(id, std::move(view_holder)); } @@ -99,16 +89,29 @@ ViewHolder* ViewHolder::FromId(zx_koid_t id) { return binding->second.get(); } +ViewHolder::ViewHolder(fml::RefPtr ui_task_runner, + fuchsia::ui::views::ViewHolderToken view_holder_token, + BindCallback on_bind_callback) + : ui_task_runner_(std::move(ui_task_runner)), + pending_view_holder_token_(std::move(view_holder_token)), + pending_bind_callback_(std::move(on_bind_callback)) { + FML_DCHECK(ui_task_runner_); + FML_DCHECK(pending_view_holder_token_.value); +} + void ViewHolder::UpdateScene(SceneUpdateContext& context, const SkPoint& offset, const SkSize& size, bool hit_testable) { if (pending_view_holder_token_.value) { + opacity_node_ = + std::make_unique(context.session()); entity_node_ = std::make_unique(context.session()); view_holder_ = std::make_unique( context.session(), std::move(pending_view_holder_token_), "Flutter SceneHost"); + opacity_node_->AddChild(*entity_node_); entity_node_->Attach(*view_holder_); ui_task_runner_->PostTask( [bind_callback = std::move(pending_bind_callback_), @@ -116,14 +119,19 @@ void ViewHolder::UpdateScene(SceneUpdateContext& context, bind_callback(view_holder_id); }); } - FML_DCHECK(entity_node_); + FML_DCHECK(opacity_node_); FML_DCHECK(view_holder_); - context.top_entity()->entity_node().AddChild(*entity_node_); + context.top_entity()->entity_node().AddChild(*opacity_node_); entity_node_->SetTranslation(offset.x(), offset.y(), -0.1f); entity_node_->SetHitTestBehavior( hit_testable ? fuchsia::ui::gfx::HitTestBehavior::kDefault : fuchsia::ui::gfx::HitTestBehavior::kSuppress); + if (has_pending_opacity_) { + opacity_node_->SetOpacity(pending_opacity_); + + has_pending_opacity_ = false; + } if (has_pending_properties_) { view_holder_->SetViewProperties(std::move(pending_properties_)); @@ -143,4 +151,9 @@ void ViewHolder::SetProperties(double width, has_pending_properties_ = true; } +void ViewHolder::SetOpacity(double opacity) { + pending_opacity_ = std::clamp(opacity, 0.0, 1.0); + has_pending_opacity_ = true; +} + } // namespace flutter diff --git a/flow/view_holder.h b/flow/view_holder.h index 2f0e216c47b77..9466f644aee23 100644 --- a/flow/view_holder.h +++ b/flow/view_holder.h @@ -38,7 +38,12 @@ class ViewHolder { static void Destroy(zx_koid_t id); static ViewHolder* FromId(zx_koid_t id); - // Sets the properties of the child view by issuing a Scenic command. + ViewHolder(fml::RefPtr ui_task_runner, + fuchsia::ui::views::ViewHolderToken view_holder_token, + BindCallback on_bind_callback); + ~ViewHolder() = default; + + // Sets the properties/opacity of the child view by issuing a Scenic command. void SetProperties(double width, double height, double insetTop, @@ -46,6 +51,7 @@ class ViewHolder { double insetBottom, double insetLeft, bool focusable); + void SetOpacity(double opacity); // Creates or updates the contained ViewHolder resource using the specified // |SceneUpdateContext|. @@ -55,17 +61,19 @@ class ViewHolder { bool hit_testable); private: - ViewHolder(fml::RefPtr ui_task_runner, - fuchsia::ui::views::ViewHolderToken view_holder_token, - BindCallback on_bind_callback); - - fuchsia::ui::gfx::ViewProperties pending_properties_; - fuchsia::ui::views::ViewHolderToken pending_view_holder_token_; fml::RefPtr ui_task_runner_; + + std::unique_ptr opacity_node_; std::unique_ptr entity_node_; std::unique_ptr view_holder_; + + fuchsia::ui::views::ViewHolderToken pending_view_holder_token_; BindCallback pending_bind_callback_; + + fuchsia::ui::gfx::ViewProperties pending_properties_; + double pending_opacity_; bool has_pending_properties_ = false; + bool has_pending_opacity_ = false; FML_DISALLOW_COPY_AND_ASSIGN(ViewHolder); }; diff --git a/lib/stub_ui/lib/src/ui/compositing.dart b/lib/stub_ui/lib/src/ui/compositing.dart index 92588fb940d72..f990c5bffbf1f 100644 --- a/lib/stub_ui/lib/src/ui/compositing.dart +++ b/lib/stub_ui/lib/src/ui/compositing.dart @@ -481,26 +481,33 @@ class EngineLayer {} /// (Fuchsia-only) Hosts content provided by another application. class SceneHost { - /// Creates a host for a child scene. + /// Creates a host for a child scene's content. /// - /// The export token is bound to a scene graph node which acts as a container - /// for the child's content. The creator of the scene host is responsible for - /// sending the corresponding import token (the other endpoint of the event - /// pair) to the child. + /// The ViewHolder token is bound to a ViewHolder scene graph node which acts + /// as a container for the child's content. The creator of the SceneHost is + /// responsible for sending the corresponding ViewToken to the child. /// - /// The export token is a dart:zircon Handle, but that type isn't + /// The ViewHolder token is a dart:zircon Handle, but that type isn't /// available here. This is called by ChildViewConnection in - /// //topaz/public/lib/ui/flutter/. + /// //topaz/public/dart/fuchsia_scenic_flutter/. /// - /// The scene host takes ownership of the provided export token handle. - SceneHost(dynamic exportTokenHandle); + /// The SceneHost takes ownership of the provided ViewHolder token. + SceneHost(dynamic viewHolderToken, + void Function() viewConnectedCallback, + void Function() viewDisconnectedCallback, + void Function(bool) viewStateChangedCallback); SceneHost.fromViewHolderToken( - dynamic viewHolderTokenHandle, + dynamic viewHolderToken, void Function() viewConnectedCallback, void Function() viewDisconnectedCallback, void Function(bool) viewStateChangedCallback); + /// Releases the resources associated with the SceneHost. + /// + /// After calling this function, the SceneHost cannot be used further. + void dispose() {} + /// Set properties on the linked scene. These properties include its bounds, /// as well as whether it can be the target of focus events or not. void setProperties( @@ -514,8 +521,9 @@ class SceneHost { throw UnimplementedError(); } - /// Releases the resources associated with the child scene host. - /// - /// After calling this function, the child scene host cannot be used further. - void dispose() {} + /// Set the opacity of the linked scene. This opacity value is applied only + /// once, when the child scene is composited into our own. + void setOpacity(double opacity) { + throw UnimplementedError(); + } } diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index 022e1ab333757..6cdd8e260cd28 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -358,42 +358,38 @@ class SceneBuilder extends NativeFieldWrapperClass2 { /// (Fuchsia-only) Hosts content provided by another application. class SceneHost extends NativeFieldWrapperClass2 { - /// Creates a host for a child scene. + /// Creates a host for a child scene's content. /// - /// The export token is bound to a scene graph node which acts as a container - /// for the child's content. The creator of the scene host is responsible for - /// sending the corresponding import token (the other endpoint of the event pair) - /// to the child. + /// The ViewHolder token is bound to a ViewHolder scene graph node which acts + /// as a container for the child's content. The creator of the SceneHost is + /// responsible for sending the corresponding ViewToken to the child. /// - /// The export token is a dart:zircon Handle, but that type isn't + /// The ViewHolder token is a dart:zircon Handle, but that type isn't /// available here. This is called by ChildViewConnection in /// //topaz/public/dart/fuchsia_scenic_flutter/. /// - /// The scene host takes ownership of the provided export token handle. - SceneHost(dynamic exportTokenHandle) { - _constructor(exportTokenHandle); + /// The SceneHost takes ownership of the provided ViewHolder token. + SceneHost( + dynamic viewHolderToken, + void Function() viewConnectedCallback, + void Function() viewDisconnectedCallback, + void Function(bool) viewStateChangedCallback) { + _constructor(viewHolderToken, viewConnectedCallback, viewDisconnectedCallback, viewStateChangedCallback); } SceneHost.fromViewHolderToken( - dynamic viewHolderTokenHandle, + dynamic viewHolderToken, void Function() viewConnectedCallback, void Function() viewDisconnectedCallback, void Function(bool) viewStateChangedCallback) { - _constructorViewHolderToken(viewHolderTokenHandle, viewConnectedCallback, - viewDisconnectedCallback, viewStateChangedCallback); + _constructor(viewHolderToken, viewConnectedCallback, viewDisconnectedCallback, viewStateChangedCallback); } - void _constructor(dynamic exportTokenHandle) native 'SceneHost_constructor'; - void - _constructorViewHolderToken( - dynamic viewHolderTokenHandle, - void Function() viewConnectedCallback, - void Function() viewDisconnectedCallback, - void Function(bool) viewStateChangedCallback) - native 'SceneHost_constructorViewHolderToken'; + void _constructor(dynamic viewHolderToken, void Function() viewConnectedCallback, void Function() viewDisconnectedCallback, void Function(bool) viewStateChangedCallback) + native 'SceneHost_constructor'; - /// Releases the resources associated with the child scene host. + /// Releases the resources associated with the SceneHost. /// - /// After calling this function, the child scene host cannot be used further. + /// After calling this function, the SceneHost cannot be used further. void dispose() native 'SceneHost_dispose'; /// Set properties on the linked scene. These properties include its bounds, @@ -406,4 +402,8 @@ class SceneHost extends NativeFieldWrapperClass2 { double insetBottom, double insetLeft, bool focusable) native 'SceneHost_setProperties'; + + /// Set the opacity of the linked scene. This opacity value is applied only + /// once, when the child scene is composited into our own. + void setOpacity(double opacity) native 'SceneHost_setOpacity'; } diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index b38c96e4df578..bdbd9218c10c2 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -256,8 +256,8 @@ void SceneBuilder::addChildScene(double dx, return; } auto layer = std::make_unique( - sceneHost->id(), sceneHost->use_view_holder(), SkPoint::Make(dx, dy), - SkSize::Make(width, height), hitTestable); + sceneHost->id(), SkPoint::Make(dx, dy), SkSize::Make(width, height), + hitTestable); current_layer_->Add(std::move(layer)); } #endif // defined(OS_FUCHSIA) diff --git a/lib/ui/compositing/scene_host.cc b/lib/ui/compositing/scene_host.cc index 9c7b9bd7671c8..889f5cb174351 100644 --- a/lib/ui/compositing/scene_host.cc +++ b/lib/ui/compositing/scene_host.cc @@ -10,7 +10,6 @@ #include #include -#include "flutter/flow/export_node.h" #include "flutter/flow/view_holder.h" #include "flutter/fml/thread_local.h" #include "flutter/lib/ui/ui_dart_state.h" @@ -23,17 +22,13 @@ FML_THREAD_LOCAL fml::ThreadLocalUniquePtr tls_scene_host_bindings; void SceneHost_constructor(Dart_NativeArguments args) { - tonic::DartCallConstructor(&flutter::SceneHost::Create, args); -} - -void SceneHost_constructorViewHolderToken(Dart_NativeArguments args) { // This UI thread / Isolate contains at least 1 SceneHost. Initialize the // per-Isolate bindings. if (tls_scene_host_bindings.get() == nullptr) { tls_scene_host_bindings.reset(new SceneHostBindings()); } - tonic::DartCallConstructor(&flutter::SceneHost::CreateViewHolder, args); + tonic::DartCallConstructor(&flutter::SceneHost::Create, args); } flutter::SceneHost* GetSceneHost(scenic::ResourceId id) { @@ -90,56 +85,59 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, SceneHost); -#define FOR_EACH_BINDING(V) \ - V(SceneHost, dispose) \ - V(SceneHost, setProperties) +#define FOR_EACH_BINDING(V) \ + V(SceneHost, dispose) \ + V(SceneHost, setProperties) \ + V(SceneHost, setOpacity) FOR_EACH_BINDING(DART_NATIVE_CALLBACK) void SceneHost::RegisterNatives(tonic::DartLibraryNatives* natives) { - natives->Register({{"SceneHost_constructor", SceneHost_constructor, 2, true}, - FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); - natives->Register({{"SceneHost_constructorViewHolderToken", - SceneHost_constructorViewHolderToken, 5, true}, + natives->Register({{"SceneHost_constructor", SceneHost_constructor, 5, true}, FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); } fml::RefPtr SceneHost::Create( - fml::RefPtr exportTokenHandle) { - return fml::MakeRefCounted(exportTokenHandle); -} - -fml::RefPtr SceneHost::CreateViewHolder( - fml::RefPtr viewHolderTokenHandle, + fml::RefPtr viewHolderToken, Dart_Handle viewConnectedCallback, Dart_Handle viewDisconnectedCallback, Dart_Handle viewStateChangedCallback) { - return fml::MakeRefCounted( - viewHolderTokenHandle, viewConnectedCallback, viewDisconnectedCallback, - viewStateChangedCallback); + return fml::MakeRefCounted(viewHolderToken, viewConnectedCallback, + viewDisconnectedCallback, + viewStateChangedCallback); } -SceneHost::SceneHost(fml::RefPtr exportTokenHandle) - : gpu_task_runner_( - UIDartState::Current()->GetTaskRunners().GetGPUTaskRunner()), - koid_(GetKoid(exportTokenHandle->handle())), - use_view_holder_(false) { - // Pass the raw handle to the GPU thead; destroying a |zircon::dart::Handle| - // on that thread can cause a race condition. - gpu_task_runner_->PostTask( - [id = koid_, raw_handle = exportTokenHandle->ReleaseHandle()]() { - flutter::ExportNode::Create(id, zx::eventpair(raw_handle)); - }); +void SceneHost::OnViewConnected(scenic::ResourceId id) { + auto* scene_host = GetSceneHost(id); + + if (scene_host && !scene_host->view_connected_callback_.is_empty()) { + InvokeDartClosure(scene_host->view_connected_callback_); + } +} + +void SceneHost::OnViewDisconnected(scenic::ResourceId id) { + auto* scene_host = GetSceneHost(id); + + if (scene_host && !scene_host->view_disconnected_callback_.is_empty()) { + InvokeDartClosure(scene_host->view_disconnected_callback_); + } } -SceneHost::SceneHost(fml::RefPtr viewHolderTokenHandle, +void SceneHost::OnViewStateChanged(scenic::ResourceId id, bool state) { + auto* scene_host = GetSceneHost(id); + + if (scene_host && !scene_host->view_state_changed_callback_.is_empty()) { + InvokeDartFunction(scene_host->view_state_changed_callback_, state); + } +} + +SceneHost::SceneHost(fml::RefPtr viewHolderToken, Dart_Handle viewConnectedCallback, Dart_Handle viewDisconnectedCallback, Dart_Handle viewStateChangedCallback) : gpu_task_runner_( UIDartState::Current()->GetTaskRunners().GetGPUTaskRunner()), - koid_(GetKoid(viewHolderTokenHandle->handle())), - use_view_holder_(true) { + koid_(GetKoid(viewHolderToken->handle())) { auto dart_state = UIDartState::Current(); // Initialize callbacks it they are non-null in Dart. @@ -169,7 +167,7 @@ SceneHost::SceneHost(fml::RefPtr viewHolderTokenHandle, [id = koid_, ui_task_runner = UIDartState::Current()->GetTaskRunners().GetUITaskRunner(), - raw_handle = viewHolderTokenHandle->ReleaseHandle(), bind_callback]() { + raw_handle = viewHolderToken->ReleaseHandle(), bind_callback]() { flutter::ViewHolder::Create( id, std::move(ui_task_runner), scenic::ToViewHolderToken(zx::eventpair(raw_handle)), @@ -178,41 +176,16 @@ SceneHost::SceneHost(fml::RefPtr viewHolderTokenHandle, } SceneHost::~SceneHost() { - if (use_view_holder_) { - auto* bindings = tls_scene_host_bindings.get(); - FML_DCHECK(bindings); - bindings->erase(koid_); - - gpu_task_runner_->PostTask( - [id = koid_]() { flutter::ViewHolder::Destroy(id); }); - } else { - gpu_task_runner_->PostTask( - [id = koid_]() { flutter::ExportNode::Destroy(id); }); - } -} - -void SceneHost::OnViewConnected(scenic::ResourceId id) { - auto* scene_host = GetSceneHost(id); - - if (scene_host && !scene_host->view_connected_callback_.is_empty()) { - InvokeDartClosure(scene_host->view_connected_callback_); - } -} - -void SceneHost::OnViewDisconnected(scenic::ResourceId id) { - auto* scene_host = GetSceneHost(id); + auto* bindings = tls_scene_host_bindings.get(); + FML_DCHECK(bindings); + bindings->erase(koid_); - if (scene_host && !scene_host->view_disconnected_callback_.is_empty()) { - InvokeDartClosure(scene_host->view_disconnected_callback_); - } + gpu_task_runner_->PostTask( + [id = koid_]() { flutter::ViewHolder::Destroy(id); }); } -void SceneHost::OnViewStateChanged(scenic::ResourceId id, bool state) { - auto* scene_host = GetSceneHost(id); - - if (scene_host && !scene_host->view_state_changed_callback_.is_empty()) { - InvokeDartFunction(scene_host->view_state_changed_callback_, state); - } +void SceneHost::dispose() { + ClearDartWrapper(); } void SceneHost::setProperties(double width, @@ -222,8 +195,6 @@ void SceneHost::setProperties(double width, double insetBottom, double insetLeft, bool focusable) { - FML_DCHECK(use_view_holder_); - gpu_task_runner_->PostTask([id = koid_, width, height, insetTop, insetRight, insetBottom, insetLeft, focusable]() { auto* view_holder = flutter::ViewHolder::FromId(id); @@ -234,8 +205,13 @@ void SceneHost::setProperties(double width, }); } -void SceneHost::dispose() { - ClearDartWrapper(); +void SceneHost::setOpacity(double opacity) { + gpu_task_runner_->PostTask([id = koid_, opacity]() { + auto* view_holder = flutter::ViewHolder::FromId(id); + FML_DCHECK(view_holder); + + view_holder->SetOpacity(opacity); + }); } } // namespace flutter diff --git a/lib/ui/compositing/scene_host.h b/lib/ui/compositing/scene_host.h index 2cba880ce4fa9..9e47cf49a3645 100644 --- a/lib/ui/compositing/scene_host.h +++ b/lib/ui/compositing/scene_host.h @@ -23,13 +23,9 @@ class SceneHost : public RefCountedDartWrappable { FML_FRIEND_MAKE_REF_COUNTED(SceneHost); public: - ~SceneHost() override; - static void RegisterNatives(tonic::DartLibraryNatives* natives); static fml::RefPtr Create( - fml::RefPtr exportTokenHandle); - static fml::RefPtr CreateViewHolder( - fml::RefPtr viewHolderTokenHandle, + fml::RefPtr viewHolderToken, Dart_Handle viewConnectedCallback, Dart_Handle viewDisconnectedCallback, Dart_Handle viewStateChangedCallback); @@ -37,9 +33,15 @@ class SceneHost : public RefCountedDartWrappable { static void OnViewDisconnected(scenic::ResourceId id); static void OnViewStateChanged(scenic::ResourceId id, bool state); + SceneHost(fml::RefPtr viewHolderToken, + Dart_Handle viewConnectedCallback, + Dart_Handle viewDisconnectedCallback, + Dart_Handle viewStateChangedCallback); + ~SceneHost() override; + zx_koid_t id() const { return koid_; } - bool use_view_holder() const { return use_view_holder_; } + void dispose(); void setProperties(double width, double height, double insetTop, @@ -47,21 +49,14 @@ class SceneHost : public RefCountedDartWrappable { double insetBottom, double insetLeft, bool focusable); - void dispose(); + void setOpacity(double opacity); private: - explicit SceneHost(fml::RefPtr exportTokenHandle); - SceneHost(fml::RefPtr viewHolderTokenHandle, - Dart_Handle viewConnectedCallback, - Dart_Handle viewDisconnectedCallback, - Dart_Handle viewStateChangedCallback); - fml::RefPtr gpu_task_runner_; tonic::DartPersistentValue view_connected_callback_; tonic::DartPersistentValue view_disconnected_callback_; tonic::DartPersistentValue view_state_changed_callback_; zx_koid_t koid_ = ZX_KOID_INVALID; - bool use_view_holder_ = false; }; } // namespace flutter