1010#include < third_party/tonic/dart_binding_macros.h>
1111#include < third_party/tonic/logging/dart_invoke.h>
1212
13+ #include " dart/runtime/include/dart_api.h"
1314#include " flutter/flow/view_holder.h"
1415#include " flutter/fml/thread_local.h"
1516#include " flutter/lib/ui/ui_dart_state.h"
1617
1718namespace {
1819
19- using SceneHostBindings = std::unordered_map<zx_koid_t , flutter::SceneHost*>;
20+ struct SceneHostBindingKey {
21+ std::string isolate_service_id;
22+ zx_koid_t koid;
2023
21- FML_THREAD_LOCAL fml::ThreadLocalUniquePtr<SceneHostBindings>
22- tls_scene_host_bindings;
24+ SceneHostBindingKey (const zx_koid_t koid,
25+ const std::string isolate_service_id) {
26+ this ->koid = koid;
27+ this ->isolate_service_id = isolate_service_id;
28+ }
2329
24- void SceneHost_constructor (Dart_NativeArguments args) {
25- // This UI thread / Isolate contains at least 1 SceneHost. Initialize the
26- // per-Isolate bindings.
27- if (tls_scene_host_bindings.get () == nullptr ) {
28- tls_scene_host_bindings.reset (new SceneHostBindings ());
30+ bool operator ==(const SceneHostBindingKey& other) const {
31+ return isolate_service_id == other.isolate_service_id && koid == other.koid ;
32+ }
33+ };
34+
35+ struct SceneHostBindingKeyHasher {
36+ std::size_t operator ()(const SceneHostBindingKey& key) const {
37+ std::size_t koid_hash = std::hash<zx_koid_t >()(key.koid );
38+ std::size_t isolate_hash = std::hash<std::string>()(key.isolate_service_id );
39+ return koid_hash ^ isolate_hash;
2940 }
41+ };
42+
43+ using SceneHostBindings = std::unordered_map<SceneHostBindingKey,
44+ flutter::SceneHost*,
45+ SceneHostBindingKeyHasher>;
46+
47+ static SceneHostBindings scene_host_bindings;
3048
49+ void SceneHost_constructor (Dart_NativeArguments args) {
3150 tonic::DartCallConstructor (&flutter::SceneHost::Create, args);
3251}
3352
34- flutter::SceneHost* GetSceneHost (scenic::ResourceId id) {
35- auto * bindings = tls_scene_host_bindings.get ();
36- FML_DCHECK (bindings);
37-
38- auto binding = bindings->find (id);
39- if (binding != bindings->end ()) {
53+ flutter::SceneHost* GetSceneHost (scenic::ResourceId id,
54+ std::string isolate_service_id) {
55+ auto binding =
56+ scene_host_bindings.find (SceneHostBindingKey (id, isolate_service_id));
57+ if (binding == scene_host_bindings.end ()) {
58+ return nullptr ;
59+ } else {
4060 return binding->second ;
4161 }
62+ }
4263
43- return nullptr ;
64+ flutter::SceneHost* GetSceneHostForCurrentIsolate (scenic::ResourceId id) {
65+ auto isolate = Dart_CurrentIsolate ();
66+ if (!isolate) {
67+ return nullptr ;
68+ } else {
69+ std::string isolate_service_id = Dart_IsolateServiceId (isolate);
70+ return GetSceneHost (id, isolate_service_id);
71+ }
4472}
4573
4674void InvokeDartClosure (const tonic::DartPersistentValue& closure) {
@@ -107,23 +135,23 @@ fml::RefPtr<SceneHost> SceneHost::Create(
107135}
108136
109137void SceneHost::OnViewConnected (scenic::ResourceId id) {
110- auto * scene_host = GetSceneHost (id);
138+ auto * scene_host = GetSceneHostForCurrentIsolate (id);
111139
112140 if (scene_host && !scene_host->view_connected_callback_ .is_empty ()) {
113141 InvokeDartClosure (scene_host->view_connected_callback_ );
114142 }
115143}
116144
117145void SceneHost::OnViewDisconnected (scenic::ResourceId id) {
118- auto * scene_host = GetSceneHost (id);
146+ auto * scene_host = GetSceneHostForCurrentIsolate (id);
119147
120148 if (scene_host && !scene_host->view_disconnected_callback_ .is_empty ()) {
121149 InvokeDartClosure (scene_host->view_disconnected_callback_ );
122150 }
123151}
124152
125153void SceneHost::OnViewStateChanged (scenic::ResourceId id, bool state) {
126- auto * scene_host = GetSceneHost (id);
154+ auto * scene_host = GetSceneHostForCurrentIsolate (id);
127155
128156 if (scene_host && !scene_host->view_state_changed_callback_ .is_empty ()) {
129157 InvokeDartFunction (scene_host->view_state_changed_callback_ , state);
@@ -138,6 +166,7 @@ SceneHost::SceneHost(fml::RefPtr<zircon::dart::Handle> viewHolderToken,
138166 UIDartState::Current ()->GetTaskRunners().GetGPUTaskRunner()),
139167 koid_(GetKoid(viewHolderToken->handle ())) {
140168 auto dart_state = UIDartState::Current ();
169+ isolate_service_id_ = Dart_IsolateServiceId (Dart_CurrentIsolate ());
141170
142171 // Initialize callbacks it they are non-null in Dart.
143172 if (!Dart_IsNull (viewConnectedCallback)) {
@@ -152,12 +181,11 @@ SceneHost::SceneHost(fml::RefPtr<zircon::dart::Handle> viewHolderToken,
152181
153182 // This callback will be posted as a task when the |scenic::ViewHolder|
154183 // resource is created and given an id by the GPU thread.
155- auto bind_callback = [scene_host = this ](scenic::ResourceId id) {
156- auto * bindings = tls_scene_host_bindings.get ();
157- FML_DCHECK (bindings);
158- FML_DCHECK (bindings->find (id) == bindings->end ());
159-
160- bindings->emplace (std::make_pair (id, scene_host));
184+ auto bind_callback = [scene_host = this ,
185+ isolate_service_id =
186+ isolate_service_id_](scenic::ResourceId id) {
187+ const auto key = SceneHostBindingKey (id, isolate_service_id);
188+ scene_host_bindings.emplace (std::make_pair (key, scene_host));
161189 };
162190
163191 // Pass the raw handle to the GPU thead; destroying a |zircon::dart::Handle|
@@ -175,9 +203,7 @@ SceneHost::SceneHost(fml::RefPtr<zircon::dart::Handle> viewHolderToken,
175203}
176204
177205SceneHost::~SceneHost () {
178- auto * bindings = tls_scene_host_bindings.get ();
179- FML_DCHECK (bindings);
180- bindings->erase (koid_);
206+ scene_host_bindings.erase (SceneHostBindingKey (koid_, isolate_service_id_));
181207
182208 gpu_task_runner_->PostTask (
183209 [id = koid_]() { flutter::ViewHolder::Destroy (id); });
0 commit comments