Flutter Linux Embedder
fl_texture_registrar.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <gmodule.h>
8 
9 #include "flutter/shell/platform/embedder/embedder.h"
15 
16 G_DECLARE_FINAL_TYPE(FlTextureRegistrarImpl,
17  fl_texture_registrar_impl,
18  FL,
19  TEXTURE_REGISTRAR_IMPL,
20  GObject)
21 
22 struct _FlTextureRegistrarImpl {
23  GObject parent_instance;
24 
25  // Weak reference to the engine this texture registrar is created for.
26  GWeakRef engine;
27 
28  // ID to assign to the next new texture.
29  int64_t next_id;
30 
31  // Internal record for registered textures.
32  //
33  // It is a map from Flutter texture ID to #FlTexture instance created by
34  // plugins. The keys are directly stored int64s. The values are stored
35  // pointer to #FlTexture. This table is freed by the responder.
36  GHashTable* textures;
37 
38  // The mutex guard to make `textures` thread-safe.
39  GMutex textures_mutex;
40 };
41 
43  FlTextureRegistrarInterface* iface);
44 
45 G_DEFINE_INTERFACE(FlTextureRegistrar, fl_texture_registrar, G_TYPE_OBJECT)
46 
48  FlTextureRegistrarImpl,
49  fl_texture_registrar_impl,
50  G_TYPE_OBJECT,
51  G_IMPLEMENT_INTERFACE(fl_texture_registrar_get_type(),
53 
54 static void fl_texture_registrar_default_init(
55  FlTextureRegistrarInterface* iface) {}
56 
57 static void fl_texture_registrar_impl_dispose(GObject* object) {
58  FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(object);
59 
60  g_mutex_lock(&self->textures_mutex);
61  g_clear_pointer(&self->textures, g_hash_table_unref);
62  g_mutex_unlock(&self->textures_mutex);
63 
64  g_weak_ref_clear(&self->engine);
65  g_mutex_clear(&self->textures_mutex);
66 
67  G_OBJECT_CLASS(fl_texture_registrar_impl_parent_class)->dispose(object);
68 }
69 
71  FlTextureRegistrarImplClass* klass) {
72  G_OBJECT_CLASS(klass)->dispose = fl_texture_registrar_impl_dispose;
73 }
74 
75 static gboolean register_texture(FlTextureRegistrar* registrar,
76  FlTexture* texture) {
77  FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
78 
79  if (FL_IS_TEXTURE_GL(texture) || FL_IS_PIXEL_BUFFER_TEXTURE(texture)) {
80  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
81  if (engine == nullptr) {
82  return FALSE;
83  }
84 
85  // We ideally would use numeric IDs, but for backwards compatibility with
86  // existing code use the address of the texture. Once all code uses
87  // fl_texture_get_id we can re-enable this method. See
88  // https://github.com/flutter/flutter/issues/124009 int64_t id =
89  // self->next_id++;
90  int64_t id = reinterpret_cast<int64_t>(texture);
91  if (fl_engine_register_external_texture(engine, id)) {
92  fl_texture_set_id(texture, id);
93  g_mutex_lock(&self->textures_mutex);
94  g_hash_table_insert(self->textures, GINT_TO_POINTER(id),
95  g_object_ref(texture));
96  g_mutex_unlock(&self->textures_mutex);
97  return TRUE;
98  } else {
99  return FALSE;
100  }
101  } else {
102  // We currently only support #FlTextureGL and #FlPixelBufferTexture.
103  return FALSE;
104  }
105 }
106 
107 static FlTexture* lookup_texture(FlTextureRegistrar* registrar,
108  int64_t texture_id) {
109  FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
110  g_mutex_lock(&self->textures_mutex);
111  FlTexture* texture = reinterpret_cast<FlTexture*>(
112  g_hash_table_lookup(self->textures, GINT_TO_POINTER(texture_id)));
113  g_mutex_unlock(&self->textures_mutex);
114  return texture;
115 }
116 
117 static gboolean mark_texture_frame_available(FlTextureRegistrar* registrar,
118  FlTexture* texture) {
119  FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
120 
121  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
122  if (engine == nullptr) {
123  return FALSE;
124  }
125 
127  fl_texture_get_id(texture));
128 }
129 
130 static gboolean unregister_texture(FlTextureRegistrar* registrar,
131  FlTexture* texture) {
132  FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
133 
134  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
135  if (engine == nullptr) {
136  return FALSE;
137  }
138 
139  gboolean result =
141 
142  g_mutex_lock(&self->textures_mutex);
143  if (!g_hash_table_remove(self->textures,
144  GINT_TO_POINTER(fl_texture_get_id(texture)))) {
145  g_warning("Unregistering a non-existent texture %p", texture);
146  }
147  g_mutex_unlock(&self->textures_mutex);
148 
149  return result;
150 }
151 
152 static void shutdown(FlTextureRegistrar* registrar) {
153  FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
154 
155  // Unregister any textures.
156  g_mutex_lock(&self->textures_mutex);
157  g_autoptr(GHashTable) textures = self->textures;
158  self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
159  g_object_unref);
160  g_hash_table_remove_all(textures);
161  g_mutex_unlock(&self->textures_mutex);
162 }
163 
165  FlTextureRegistrarInterface* iface) {
166  iface->register_texture = register_texture;
167  iface->lookup_texture = lookup_texture;
168  iface->mark_texture_frame_available = mark_texture_frame_available;
169  iface->unregister_texture = unregister_texture;
170  iface->shutdown = shutdown;
171 }
172 
173 static void fl_texture_registrar_impl_init(FlTextureRegistrarImpl* self) {
174  self->next_id = 1;
175  self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
176  g_object_unref);
177  // Initialize the mutex for textures.
178  g_mutex_init(&self->textures_mutex);
179 }
180 
181 G_MODULE_EXPORT gboolean fl_texture_registrar_register_texture(
182  FlTextureRegistrar* self,
183  FlTexture* texture) {
184  g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), FALSE);
185  g_return_val_if_fail(FL_IS_TEXTURE(texture), FALSE);
186 
187  return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->register_texture(self, texture);
188 }
189 
190 FlTexture* fl_texture_registrar_lookup_texture(FlTextureRegistrar* self,
191  int64_t texture_id) {
192  g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), NULL);
193 
194  return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->lookup_texture(self, texture_id);
195 }
196 
198  FlTextureRegistrar* self,
199  FlTexture* texture) {
200  g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), FALSE);
201 
202  return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->mark_texture_frame_available(
203  self, texture);
204 }
205 
207  FlTextureRegistrar* self,
208  FlTexture* texture) {
209  g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), FALSE);
210 
211  return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->unregister_texture(self,
212  texture);
213 }
214 
215 void fl_texture_registrar_shutdown(FlTextureRegistrar* self) {
216  g_return_if_fail(FL_IS_TEXTURE_REGISTRAR(self));
217 
218  return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->shutdown(self);
219 }
220 
221 FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) {
222  FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(
223  g_object_new(fl_texture_registrar_impl_get_type(), nullptr));
224 
225  // Added to stop compiler complaining about an unused function.
226  FL_IS_TEXTURE_REGISTRAR_IMPL(self);
227 
228  g_weak_ref_init(&self->engine, G_OBJECT(engine));
229 
230  return FL_TEXTURE_REGISTRAR(self);
231 }
fl_texture_gl_private.h
fl_texture_registrar_lookup_texture
FlTexture * fl_texture_registrar_lookup_texture(FlTextureRegistrar *self, int64_t texture_id)
Definition: fl_texture_registrar.cc:190
G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE(FlTextureRegistrarImpl, fl_texture_registrar_impl, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(fl_texture_registrar_get_type(), fl_texture_registrar_impl_iface_init)) static void fl_texture_registrar_default_init(FlTextureRegistrarInterface *iface)
Definition: fl_texture_registrar.cc:47
fl_engine_mark_texture_frame_available
gboolean fl_engine_mark_texture_frame_available(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:974
mark_texture_frame_available
static gboolean mark_texture_frame_available(FlTextureRegistrar *registrar, FlTexture *texture)
Definition: fl_texture_registrar.cc:117
fl_texture_registrar_new
FlTextureRegistrar * fl_texture_registrar_new(FlEngine *engine)
Definition: fl_texture_registrar.cc:221
unregister_texture
static gboolean unregister_texture(FlTextureRegistrar *registrar, FlTexture *texture)
Definition: fl_texture_registrar.cc:130
fl_texture_set_id
void fl_texture_set_id(FlTexture *self, int64_t id)
Definition: fl_texture.cc:15
fl_texture_registrar_unregister_texture
G_MODULE_EXPORT gboolean fl_texture_registrar_unregister_texture(FlTextureRegistrar *self, FlTexture *texture)
Definition: fl_texture_registrar.cc:206
G_DEFINE_INTERFACE
G_DEFINE_INTERFACE(FlKeyboardViewDelegate, fl_keyboard_view_delegate, G_TYPE_OBJECT) static void fl_keyboard_view_delegate_default_init(FlKeyboardViewDelegateInterface *iface)
Definition: fl_keyboard_view_delegate.cc:7
fl_texture_registrar_register_texture
G_MODULE_EXPORT gboolean fl_texture_registrar_register_texture(FlTextureRegistrar *self, FlTexture *texture)
Definition: fl_texture_registrar.cc:181
G_DECLARE_FINAL_TYPE
G_DECLARE_FINAL_TYPE(FlTextureRegistrarImpl, fl_texture_registrar_impl, FL, TEXTURE_REGISTRAR_IMPL, GObject) struct _FlTextureRegistrarImpl
Definition: fl_texture_registrar.cc:16
fl_texture_registrar_shutdown
void fl_texture_registrar_shutdown(FlTextureRegistrar *self)
Definition: fl_texture_registrar.cc:215
fl_engine_private.h
fl_texture_registrar.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_texture_get_id
G_MODULE_EXPORT int64_t fl_texture_get_id(FlTexture *self)
Definition: fl_texture.cc:20
lookup_texture
static FlTexture * lookup_texture(FlTextureRegistrar *registrar, int64_t texture_id)
Definition: fl_texture_registrar.cc:107
FL
FL
Definition: fl_binary_messenger.cc:27
result
GAsyncResult * result
Definition: fl_text_input_handler.cc:106
fl_texture_registrar_impl_class_init
static void fl_texture_registrar_impl_class_init(FlTextureRegistrarImplClass *klass)
Definition: fl_texture_registrar.cc:70
fl_pixel_buffer_texture_private.h
register_texture
static gboolean register_texture(FlTextureRegistrar *registrar, FlTexture *texture)
Definition: fl_texture_registrar.cc:75
fl_texture_private.h
fl_texture_registrar_private.h
fl_texture_registrar_impl_init
static void fl_texture_registrar_impl_init(FlTextureRegistrarImpl *self)
Definition: fl_texture_registrar.cc:173
fl_texture_registrar_impl_dispose
static void fl_texture_registrar_impl_dispose(GObject *object)
Definition: fl_texture_registrar.cc:57
fl_engine_register_external_texture
gboolean fl_engine_register_external_texture(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:981
fl_texture_registrar_impl_iface_init
static void fl_texture_registrar_impl_iface_init(FlTextureRegistrarInterface *iface)
Definition: fl_texture_registrar.cc:164
fl_engine_unregister_external_texture
gboolean fl_engine_unregister_external_texture(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:988
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24
shutdown
static void shutdown(FlTextureRegistrar *registrar)
Definition: fl_texture_registrar.cc:152
fl_texture_registrar_mark_texture_frame_available
G_MODULE_EXPORT gboolean fl_texture_registrar_mark_texture_frame_available(FlTextureRegistrar *self, FlTexture *texture)
Definition: fl_texture_registrar.cc:197