Flutter Engine
 
Loading...
Searching...
No Matches
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
15
16G_DECLARE_FINAL_TYPE(FlTextureRegistrarImpl,
17 fl_texture_registrar_impl,
18 FL,
19 TEXTURE_REGISTRAR_IMPL,
20 GObject)
21
22struct _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
45G_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
54static void fl_texture_registrar_default_init(
55 FlTextureRegistrarInterface* iface) {}
56
57static 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
75static 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);
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
107static 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
117static 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
128}
129
130static 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
152static 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
173static 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
181G_MODULE_EXPORT gboolean
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
190FlTexture* 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
197G_MODULE_EXPORT gboolean
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
206G_MODULE_EXPORT gboolean
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
215void 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
221FlTextureRegistrar* 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}
FlutterEngine engine
Definition main.cc:84
g_autoptr(GMutexLocker) locker
return TRUE
gboolean fl_engine_mark_texture_frame_available(FlEngine *self, int64_t texture_id)
gboolean fl_engine_unregister_external_texture(FlEngine *self, int64_t texture_id)
gboolean fl_engine_register_external_texture(FlEngine *self, int64_t texture_id)
g_hash_table_insert(self->handlers, g_strdup(channel), handler_new(handler, user_data, destroy_notify))
G_MODULE_EXPORT int64_t fl_texture_get_id(FlTexture *self)
Definition fl_texture.cc:20
void fl_texture_set_id(FlTexture *self, int64_t id)
Definition fl_texture.cc:15
static gboolean register_texture(FlTextureRegistrar *registrar, FlTexture *texture)
static gboolean mark_texture_frame_available(FlTextureRegistrar *registrar, FlTexture *texture)
G_MODULE_EXPORT gboolean fl_texture_registrar_register_texture(FlTextureRegistrar *self, FlTexture *texture)
void fl_texture_registrar_shutdown(FlTextureRegistrar *self)
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)
static void fl_texture_registrar_impl_init(FlTextureRegistrarImpl *self)
G_DECLARE_FINAL_TYPE(FlTextureRegistrarImpl, fl_texture_registrar_impl, FL, TEXTURE_REGISTRAR_IMPL, GObject) struct _FlTextureRegistrarImpl
G_MODULE_EXPORT gboolean fl_texture_registrar_unregister_texture(FlTextureRegistrar *self, FlTexture *texture)
G_MODULE_EXPORT gboolean fl_texture_registrar_mark_texture_frame_available(FlTextureRegistrar *self, FlTexture *texture)
static void shutdown(FlTextureRegistrar *registrar)
FlTexture * fl_texture_registrar_lookup_texture(FlTextureRegistrar *self, int64_t texture_id)
static FlTexture * lookup_texture(FlTextureRegistrar *registrar, int64_t texture_id)
static void fl_texture_registrar_impl_dispose(GObject *object)
static gboolean unregister_texture(FlTextureRegistrar *registrar, FlTexture *texture)
FlTextureRegistrar * fl_texture_registrar_new(FlEngine *engine)
static void fl_texture_registrar_impl_class_init(FlTextureRegistrarImplClass *klass)
static void fl_texture_registrar_impl_iface_init(FlTextureRegistrarInterface *iface)
FlTexture * texture
int64_t texture_id