| 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
5 #include "flutter/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h"
6
7 #include <gmodule.h>
8
9 #include "flutter/shell/platform/embedder/embedder.h"
10 #include "flutter/shell/platform/linux/fl_engine_private.h"
11 #include "flutter/shell/platform/linux/fl_pixel_buffer_texture_private.h"
12 #include "flutter/shell/platform/linux/fl_texture_gl_private.h"
13 #include "flutter/shell/platform/linux/fl_texture_private.h"
14 #include "flutter/shell/platform/linux/fl_texture_registrar_private.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 FlEngine* 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
42 static void fl_texture_registrar_impl_iface_init(
43 FlTextureRegistrarInterface* iface);
44
45 G_DEFINE_INTERFACE(FlTextureRegistrar, fl_texture_registrar, G_TYPE_OBJECT)
46
47 G_DEFINE_TYPE_WITH_CODE(
48 FlTextureRegistrarImpl,
49 fl_texture_registrar_impl,
50 G_TYPE_OBJECT,
51 G_IMPLEMENT_INTERFACE(fl_texture_registrar_get_type(),
52 fl_texture_registrar_impl_iface_init))
53
54 static void fl_texture_registrar_default_init(
55 FlTextureRegistrarInterface* iface) {}
56
57 static void engine_weak_notify_cb(gpointer user_data,
58 GObject* where_the_object_was) {
59 FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(user_data);
60 self->engine = nullptr;
61
62 // Unregister any textures.
63 g_mutex_lock(&self->textures_mutex);
64 g_autoptr(GHashTable) textures = self->textures;
65 self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
66 g_object_unref);
67 g_hash_table_remove_all(textures);
68 g_mutex_unlock(&self->textures_mutex);
69 }
70
71 static void fl_texture_registrar_impl_dispose(GObject* object) {
72 FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(object);
73
74 g_mutex_lock(&self->textures_mutex);
75 g_clear_pointer(&self->textures, g_hash_table_unref);
76 g_mutex_unlock(&self->textures_mutex);
77
78 if (self->engine != nullptr) {
79 g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self);
80 self->engine = nullptr;
81 }
82 g_mutex_clear(&self->textures_mutex);
83
84 G_OBJECT_CLASS(fl_texture_registrar_impl_parent_class)->dispose(object);
85 }
86
87 static void fl_texture_registrar_impl_class_init(
88 FlTextureRegistrarImplClass* klass) {
89 G_OBJECT_CLASS(klass)->dispose = fl_texture_registrar_impl_dispose;
90 }
91
92 static gboolean register_texture(FlTextureRegistrar* registrar,
93 FlTexture* texture) {
94 FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
95
96 if (FL_IS_TEXTURE_GL(texture) || FL_IS_PIXEL_BUFFER_TEXTURE(texture)) {
97 if (self->engine == nullptr) {
98 return FALSE;
99 }
100
101 // We ideally would use numeric IDs, but for backwards compatibility with
102 // existing code use the address of the texture. Once all code uses
103 // fl_texture_get_id we can re-enable this method. See
104 // https://github.com/flutter/flutter/issues/124009 int64_t id =
105 // self->next_id++;
106 int64_t id = reinterpret_cast<int64_t>(texture);
107 if (fl_engine_register_external_texture(self->engine, id)) {
108 fl_texture_set_id(texture, id);
109 g_mutex_lock(&self->textures_mutex);
110 g_hash_table_insert(self->textures, GINT_TO_POINTER(id),
111 g_object_ref(texture));
112 g_mutex_unlock(&self->textures_mutex);
113 return TRUE;
114 } else {
115 return FALSE;
116 }
117 } else {
118 // We currently only support #FlTextureGL and #FlPixelBufferTexture.
119 return FALSE;
120 }
121 }
122
123 static FlTexture* lookup_texture(FlTextureRegistrar* registrar,
124 int64_t texture_id) {
125 FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
126 g_mutex_lock(&self->textures_mutex);
127 FlTexture* texture = reinterpret_cast<FlTexture*>(
128 g_hash_table_lookup(self->textures, GINT_TO_POINTER(texture_id)));
129 g_mutex_unlock(&self->textures_mutex);
130 return texture;
131 }
132
133 static gboolean mark_texture_frame_available(FlTextureRegistrar* registrar,
134 FlTexture* texture) {
135 FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
136
137 if (self->engine == nullptr) {
138 return FALSE;
139 }
140
141 return fl_engine_mark_texture_frame_available(self->engine,
142 fl_texture_get_id(texture));
143 }
144
145 static gboolean unregister_texture(FlTextureRegistrar* registrar,
146 FlTexture* texture) {
147 FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar);
148
149 if (self->engine == nullptr) {
150 return FALSE;
151 }
152
153 gboolean result = fl_engine_unregister_external_texture(
154 self->engine, fl_texture_get_id(texture));
155
156 g_mutex_lock(&self->textures_mutex);
157 if (!g_hash_table_remove(self->textures,
158 GINT_TO_POINTER(fl_texture_get_id(texture)))) {
159 g_warning("Unregistering a non-existent texture %p", texture);
160 }
161 g_mutex_unlock(&self->textures_mutex);
162
163 return result;
164 }
165
166 static void fl_texture_registrar_impl_iface_init(
167 FlTextureRegistrarInterface* iface) {
168 iface->register_texture = register_texture;
169 iface->lookup_texture = lookup_texture;
170 iface->mark_texture_frame_available = mark_texture_frame_available;
171 iface->unregister_texture = unregister_texture;
172 }
173
174 static void fl_texture_registrar_impl_init(FlTextureRegistrarImpl* self) {
175 self->next_id = 1;
176 self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
177 g_object_unref);
178 // Initialize the mutex for textures.
179 g_mutex_init(&self->textures_mutex);
180 }
181
182 G_MODULE_EXPORT gboolean
183 fl_texture_registrar_register_texture(FlTextureRegistrar* self,
184 FlTexture* texture) {
185 g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), FALSE);
186 g_return_val_if_fail(FL_IS_TEXTURE(texture), FALSE);
187
188 return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->register_texture(self, texture);
189 }
190
191 FlTexture* fl_texture_registrar_lookup_texture(FlTextureRegistrar* self,
192 int64_t texture_id) {
193 g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), NULL);
194
195 return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->lookup_texture(self, texture_id);
196 }
197
198 G_MODULE_EXPORT gboolean
199 fl_texture_registrar_mark_texture_frame_available(FlTextureRegistrar* self,
200 FlTexture* texture) {
201 g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), FALSE);
202
203 return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->mark_texture_frame_available(
204 self, texture);
205 }
206
207 G_MODULE_EXPORT gboolean
208 fl_texture_registrar_unregister_texture(FlTextureRegistrar* self,
209 FlTexture* texture) {
210 g_return_val_if_fail(FL_IS_TEXTURE_REGISTRAR(self), FALSE);
211
212 return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->unregister_texture(self,
213 texture);
214 }
215
216 FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) {
217 FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(
218 g_object_new(fl_texture_registrar_impl_get_type(), nullptr));
219
220 // Added to stop compiler complaining about an unused function.
221 FL_IS_TEXTURE_REGISTRAR_IMPL(self);
222
223 self->engine = engine;
224 g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self);
225
226 return FL_TEXTURE_REGISTRAR(self);
227 }
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:191
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:881
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
mark_texture_frame_available
static gboolean mark_texture_frame_available(FlTextureRegistrar *registrar, FlTexture *texture)
Definition: fl_texture_registrar.cc:133
fl_texture_registrar_new
FlTextureRegistrar * fl_texture_registrar_new(FlEngine *engine)
Definition: fl_texture_registrar.cc:216
unregister_texture
static gboolean unregister_texture(FlTextureRegistrar *registrar, FlTexture *texture)
Definition: fl_texture_registrar.cc:145
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:208
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:183
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_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:123
FL
FL
Definition: fl_binary_messenger.cc:27
engine_weak_notify_cb
static void engine_weak_notify_cb(gpointer user_data, GObject *where_the_object_was)
Definition: fl_texture_registrar.cc:57
self
GdkEvent FlView * self
Definition: fl_view.cc:100
fl_texture_registrar_impl_class_init
static void fl_texture_registrar_impl_class_init(FlTextureRegistrarImplClass *klass)
Definition: fl_texture_registrar.cc:87
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
fl_pixel_buffer_texture_private.h
register_texture
static gboolean register_texture(FlTextureRegistrar *registrar, FlTexture *texture)
Definition: fl_texture_registrar.cc:92
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:174
fl_texture_registrar_impl_dispose
static void fl_texture_registrar_impl_dispose(GObject *object)
Definition: fl_texture_registrar.cc:71
fl_engine_register_external_texture
gboolean fl_engine_register_external_texture(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:888
engine
FlEngine * engine
Definition: fl_view_accessible.cc:29
fl_texture_registrar_impl_iface_init
static void fl_texture_registrar_impl_iface_init(FlTextureRegistrarInterface *iface)
Definition: fl_texture_registrar.cc:166
fl_engine_unregister_external_texture
gboolean fl_engine_unregister_external_texture(FlEngine *self, int64_t texture_id)
Definition: fl_engine.cc:895
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24
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:199