Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
fl_compositor_opengl.cc File Reference

Go to the source code of this file.

Classes

struct  _FlCompositorOpenGL
 

Functions

static void fl_compositor_opengl_dispose (GObject *object)
 
static void fl_compositor_opengl_class_init (FlCompositorOpenGLClass *klass)
 
static void fl_compositor_opengl_init (FlCompositorOpenGL *self)
 
FlCompositorOpenGL * fl_compositor_opengl_new (FlOpenGLManager *opengl_manager, gboolean shareable)
 
static void composite_layer (FlCompositorOpenGL *self, FlFramebuffer *framebuffer, double x, double y, int width, int height)
 
gboolean fl_compositor_opengl_composite_layers (FlCompositorOpenGL *self, const FlutterLayer **layers, size_t layers_count)
 
void fl_compositor_opengl_get_frame_size (FlCompositorOpenGL *self, size_t *width, size_t *height)
 
gboolean fl_compositor_opengl_render (FlCompositorOpenGL *self, cairo_t *cr, GdkWindow *window)
 

Function Documentation

◆ composite_layer()

static void composite_layer ( FlCompositorOpenGL *  self,
FlFramebuffer *  framebuffer,
double  x,
double  y,
int  width,
int  height 
)
static

Definition at line 67 of file fl_compositor_opengl.cc.

72 {
73 size_t texture_width = fl_framebuffer_get_width(framebuffer);
74 size_t texture_height = fl_framebuffer_get_height(framebuffer);
76 (2 * y / height) - 1.0);
77 fl_compositor_opengl_shader_set_scale(self->shader, texture_width / width,
78 texture_height / height);
79
80 GLuint texture_id = fl_framebuffer_get_texture_id(framebuffer);
81 glBindTexture(GL_TEXTURE_2D, texture_id);
82
83 glDrawArrays(GL_TRIANGLES, 0, 6);
84}
int32_t x
void fl_compositor_opengl_shader_set_offset(FlCompositorOpenGLShader *self, double x, double y)
void fl_compositor_opengl_shader_set_scale(FlCompositorOpenGLShader *self, double x, double y)
size_t fl_framebuffer_get_height(FlFramebuffer *self)
size_t fl_framebuffer_get_width(FlFramebuffer *self)
GLuint fl_framebuffer_get_texture_id(FlFramebuffer *self)
double y
int32_t height
int32_t width
int64_t texture_id

References fl_compositor_opengl_shader_set_offset(), fl_compositor_opengl_shader_set_scale(), fl_framebuffer_get_height(), fl_framebuffer_get_texture_id(), fl_framebuffer_get_width(), height, self, texture_id, width, x, and y.

Referenced by fl_compositor_opengl_composite_layers().

◆ fl_compositor_opengl_class_init()

static void fl_compositor_opengl_class_init ( FlCompositorOpenGLClass *  klass)
static

Definition at line 49 of file fl_compositor_opengl.cc.

49 {
50 G_OBJECT_CLASS(klass)->dispose = fl_compositor_opengl_dispose;
51}
static void fl_compositor_opengl_dispose(GObject *object)

References fl_compositor_opengl_dispose().

◆ fl_compositor_opengl_composite_layers()

gboolean fl_compositor_opengl_composite_layers ( FlCompositorOpenGL *  compositor,
const FlutterLayer **  layers,
size_t  layers_count 
)

fl_compositor_opengl_composite_layers: @compositor: an #FlCompositorOpenGL. @layers: layers to be composited. @layers_count: number of layers.

Composite layers into the stored frame using the current OpenGL context.

Returns TRUE if successful.

Definition at line 86 of file fl_compositor_opengl.cc.

88 {
89 if (layers_count == 0) {
90 return TRUE;
91 }
92
93 GLint general_format = GL_RGBA;
94 if (epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) {
95 general_format = GL_BGRA_EXT;
96 }
97
98 // Save bindings that are set by this function. All bindings must be restored
99 // to their original values because Skia expects that its bindings have not
100 // been altered.
101 GLint saved_texture_binding;
102 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
103 GLint saved_vao_binding;
104 glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &saved_vao_binding);
105 GLint saved_array_buffer_binding;
106 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
107 GLint saved_draw_framebuffer_binding;
108 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &saved_draw_framebuffer_binding);
109 GLint saved_read_framebuffer_binding;
110 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &saved_read_framebuffer_binding);
111 GLint saved_current_program;
112 glGetIntegerv(GL_CURRENT_PROGRAM, &saved_current_program);
113 GLboolean saved_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
114 GLboolean saved_blend = glIsEnabled(GL_BLEND);
115 GLint saved_src_rgb;
116 glGetIntegerv(GL_BLEND_SRC_RGB, &saved_src_rgb);
117 GLint saved_src_alpha;
118 glGetIntegerv(GL_BLEND_SRC_ALPHA, &saved_src_alpha);
119 GLint saved_dst_rgb;
120 glGetIntegerv(GL_BLEND_DST_RGB, &saved_dst_rgb);
121 GLint saved_dst_alpha;
122 glGetIntegerv(GL_BLEND_DST_ALPHA, &saved_dst_alpha);
123
124 // Update framebuffer to write into.
125 size_t width = layers[0]->size.width;
126 size_t height = layers[0]->size.height;
127 if (self->framebuffer == nullptr ||
128 fl_framebuffer_get_width(self->framebuffer) != width ||
129 fl_framebuffer_get_height(self->framebuffer) != height) {
130 g_clear_object(&self->framebuffer);
131 self->framebuffer =
132 fl_framebuffer_new(general_format, width, height, self->shareable);
133
134 // If not shareable make buffer to copy frame pixels into.
135 if (!self->shareable) {
136 size_t data_length = width * height * 4;
137 self->pixels =
138 static_cast<uint8_t*>(g_realloc(self->pixels, data_length));
139 }
140 }
141
142 // FIXME(robert-ancell): The vertex array is the same for all views, but
143 // cannot be shared in OpenGL. Find a way to not generate this every time.
144 GLuint vao;
145 glGenVertexArrays(1, &vao);
146 glBindVertexArray(vao);
147
148 glEnable(GL_BLEND);
149 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
150
152
153 // Disable the scissor test as it can affect blit operations.
154 // Prevents regressions like: https://github.com/flutter/flutter/issues/140828
155 // See OpenGL specification version 4.6, section 18.3.1.
156 glDisable(GL_SCISSOR_TEST);
157
158 glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
159 fl_framebuffer_get_id(self->framebuffer));
160 gboolean first_layer = TRUE;
161 for (size_t i = 0; i < layers_count; ++i) {
162 const FlutterLayer* layer = layers[i];
163 switch (layer->type) {
165 const FlutterBackingStore* backing_store = layer->backing_store;
166 FlFramebuffer* framebuffer =
167 FL_FRAMEBUFFER(backing_store->open_gl.framebuffer.user_data);
168 glBindFramebuffer(GL_READ_FRAMEBUFFER,
169 fl_framebuffer_get_id(framebuffer));
170 // The first layer can be blitted, and following layers composited with
171 // this.
172 if (first_layer) {
173 glBlitFramebuffer(layer->offset.x, layer->offset.y, layer->size.width,
174 layer->size.height, layer->offset.x,
175 layer->offset.y, layer->size.width,
176 layer->size.height, GL_COLOR_BUFFER_BIT,
177 GL_NEAREST);
178 first_layer = FALSE;
179 } else {
180 composite_layer(self, framebuffer, layer->offset.x, layer->offset.y,
181 width, height);
182 }
183 } break;
185 // TODO(robert-ancell) Not implemented -
186 // https://github.com/flutter/flutter/issues/41724
187 } break;
188 }
189 }
190 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
191 glFlush();
192
193 glDeleteVertexArrays(1, &vao);
194
195 if (saved_blend) {
196 glEnable(GL_BLEND);
197 } else {
198 glDisable(GL_BLEND);
199 }
200 if (saved_scissor_test) {
201 glEnable(GL_SCISSOR_TEST);
202 } else {
203 glDisable(GL_SCISSOR_TEST);
204 }
205
206 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
207 glBindVertexArray(saved_vao_binding);
208 glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding);
209 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, saved_draw_framebuffer_binding);
210 glUseProgram(saved_current_program);
211 glBlendFuncSeparate(saved_src_rgb, saved_dst_rgb, saved_src_alpha,
212 saved_dst_alpha);
213
214 if (!self->shareable) {
215 glBindFramebuffer(GL_READ_FRAMEBUFFER,
216 fl_framebuffer_get_id(self->framebuffer));
217 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, self->pixels);
218 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
219 }
220 glBindFramebuffer(GL_READ_FRAMEBUFFER, saved_read_framebuffer_binding);
221
222 return TRUE;
223}
@ kFlutterLayerContentTypePlatformView
Indicates that the contents of this layer are determined by the embedder.
Definition embedder.h:2159
@ kFlutterLayerContentTypeBackingStore
Definition embedder.h:2157
static void composite_layer(FlCompositorOpenGL *self, FlFramebuffer *framebuffer, double x, double y, int width, int height)
void fl_compositor_opengl_shader_use(FlCompositorOpenGLShader *self)
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height, gboolean shareable)
GLuint fl_framebuffer_get_id(FlFramebuffer *self)
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
bool epoxy_has_gl_extension(const char *extension)
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition embedder.h:2132
FlutterPoint offset
Definition embedder.h:2200
FlutterLayerContentType type
Definition embedder.h:2189
const FlutterBackingStore * backing_store
Definition embedder.h:2193
FlutterSize size
The size of the layer (in physical pixels).
Definition embedder.h:2202
FlutterOpenGLFramebuffer framebuffer
Definition embedder.h:1975
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition embedder.h:554
double height
Definition embedder.h:636
double width
Definition embedder.h:635

References FlutterLayer::backing_store, composite_layer(), epoxy_has_gl_extension(), fl_compositor_opengl_shader_use(), fl_framebuffer_get_height(), fl_framebuffer_get_id(), fl_framebuffer_get_width(), fl_framebuffer_new(), FlutterOpenGLBackingStore::framebuffer, height, FlutterSize::height, i, kFlutterLayerContentTypeBackingStore, kFlutterLayerContentTypePlatformView, layers, layers_count, FlutterLayer::offset, FlutterBackingStore::open_gl, self, FlutterLayer::size, TRUE, FlutterLayer::type, FlutterOpenGLFramebuffer::user_data, width, FlutterSize::width, FlutterPoint::x, and FlutterPoint::y.

Referenced by fl_view_renderer_opengl_present_layers(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ fl_compositor_opengl_dispose()

static void fl_compositor_opengl_dispose ( GObject *  object)
static

Definition at line 37 of file fl_compositor_opengl.cc.

37 {
38 FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(object);
39
40 g_clear_object(&self->shader);
41
42 g_clear_object(&self->opengl_manager);
43 g_clear_object(&self->framebuffer);
44 g_clear_pointer(&self->pixels, g_free);
45
46 G_OBJECT_CLASS(fl_compositor_opengl_parent_class)->dispose(object);
47}

References self.

Referenced by fl_compositor_opengl_class_init().

◆ fl_compositor_opengl_get_frame_size()

void fl_compositor_opengl_get_frame_size ( FlCompositorOpenGL *  compositor,
size_t *  width,
size_t *  height 
)

fl_compositor_opengl_get_frame_size: @compositor: an #FlCompositorOpenGL. @width: location to write frame width in pixels. @height: location to write frame height in pixels.

Get the size of the layer ready for rendering.

Definition at line 225 of file fl_compositor_opengl.cc.

227 {
228 if (width != nullptr) {
229 *width = self->framebuffer != nullptr
230 ? fl_framebuffer_get_width(self->framebuffer)
231 : 0;
232 }
233 if (height != nullptr) {
234 *height = self->framebuffer != nullptr
235 ? fl_framebuffer_get_height(self->framebuffer)
236 : 0;
237 }
238}

References fl_framebuffer_get_height(), fl_framebuffer_get_width(), height, self, and width.

Referenced by G_DEFINE_TYPE(), TEST_F(), TEST_F(), and wait_for_frame().

◆ fl_compositor_opengl_init()

static void fl_compositor_opengl_init ( FlCompositorOpenGL *  self)
static

Definition at line 53 of file fl_compositor_opengl.cc.

53{}

◆ fl_compositor_opengl_new()

FlCompositorOpenGL * fl_compositor_opengl_new ( FlOpenGLManager *  opengl_manager,
gboolean  shareable 
)

Definition at line 55 of file fl_compositor_opengl.cc.

56 {
57 FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(
58 g_object_new(fl_compositor_opengl_get_type(), nullptr));
59
60 self->shareable = shareable;
61 self->opengl_manager = FL_OPENGL_MANAGER(g_object_ref(opengl_manager));
62 self->shader = fl_compositor_opengl_shader_new(opengl_manager);
63
64 return self;
65}
G_BEGIN_DECLS gboolean shareable
FlCompositorOpenGLShader * fl_compositor_opengl_shader_new(FlOpenGLManager *opengl_manager)

References fl_compositor_opengl_shader_new(), self, and shareable.

Referenced by fl_view_renderer_opengl_realize(), and FlCompositorOpenGLTest::SetUp().

◆ fl_compositor_opengl_render()

gboolean fl_compositor_opengl_render ( FlCompositorOpenGL *  compositor,
cairo_t *  cr,
GdkWindow *  window 
)

fl_compositor_opengl_render: @compositor: an #FlCompositorOpenGL. @cr: a Cairo rendering context. @window: window being rendered into.

Renders the current frame using the current OpenGL context.

Returns TRUE if successful.

Definition at line 240 of file fl_compositor_opengl.cc.

242 {
243 if (self->framebuffer == nullptr) {
244 return FALSE;
245 }
246
247 gint scale_factor = gdk_window_get_scale_factor(window);
248 size_t width = gdk_window_get_width(window) * scale_factor;
249 size_t height = gdk_window_get_height(window) * scale_factor;
250
251 if (fl_framebuffer_get_shareable(self->framebuffer)) {
252 g_autoptr(FlFramebuffer) sibling =
255 GL_TEXTURE, scale_factor, 0, 0, width, height);
256 } else {
257 GLint saved_texture_binding;
258 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
259
260 GLuint texture_id;
261 glGenTextures(1, &texture_id);
262 glBindTexture(GL_TEXTURE_2D, texture_id);
263 GLsizei fb_width = 0;
264 GLsizei fb_height = 0;
265 if (self->framebuffer != nullptr) {
266 fb_width =
267 static_cast<GLsizei>(fl_framebuffer_get_width(self->framebuffer));
268 fb_height =
269 static_cast<GLsizei>(fl_framebuffer_get_height(self->framebuffer));
270 }
271 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fb_width, fb_height, 0, GL_RGBA,
272 GL_UNSIGNED_BYTE, self->pixels);
273
274 gdk_cairo_draw_from_gl(cr, window, texture_id, GL_TEXTURE, scale_factor, 0,
275 0, width, height);
276
277 glDeleteTextures(1, &texture_id);
278
279 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
280 }
281
282 glFlush();
283
284 return TRUE;
285}
GLFWwindow * window
Definition main.cc:60
g_autoptr(FlEngine) engine
FlFramebuffer * fl_framebuffer_create_sibling(FlFramebuffer *self)
gboolean fl_framebuffer_get_shareable(FlFramebuffer *self)
void gdk_cairo_draw_from_gl(cairo_t *cr, GdkWindow *window, int source, int source_type, int buffer_scale, int x, int y, int width, int height)
Definition mock_gtk.cc:170
int gdk_window_get_width(GdkWindow *window)
Definition mock_gtk.cc:79
gint gdk_window_get_scale_factor(GdkWindow *window)
Definition mock_gtk.cc:95
int gdk_window_get_height(GdkWindow *window)
Definition mock_gtk.cc:87

References fl_framebuffer_create_sibling(), fl_framebuffer_get_height(), fl_framebuffer_get_shareable(), fl_framebuffer_get_texture_id(), fl_framebuffer_get_width(), g_autoptr(), gdk_cairo_draw_from_gl(), gdk_window_get_height(), gdk_window_get_scale_factor(), gdk_window_get_width(), height, self, texture_id, TRUE, width, and window.

Referenced by fl_view_renderer_opengl_draw(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().