Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Functions | Variables
fl_renderer.cc File Reference
#include "fl_renderer.h"
#include <epoxy/egl.h>
#include <epoxy/gl.h>
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/fl_backing_store_provider.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_view_private.h"

Go to the source code of this file.

Classes

struct  FlRendererPrivate
 

Functions

static gchar * get_shader_log (GLuint shader)
 
static gchar * get_program_log (GLuint program)
 
static GLfloat pixels_to_gl_coords (GLfloat position, GLfloat pixels)
 Converts a pixel co-ordinate from 0..pixels to OpenGL -1..1.
 
static void fl_renderer_unblock_main_thread (FlRenderer *self)
 
static void fl_renderer_dispose (GObject *object)
 
static void fl_renderer_class_init (FlRendererClass *klass)
 
static void fl_renderer_init (FlRenderer *self)
 
gboolean fl_renderer_start (FlRenderer *self, FlView *view)
 
void * fl_renderer_get_proc_address (FlRenderer *self, const char *name)
 
void fl_renderer_make_current (FlRenderer *self)
 
void fl_renderer_make_resource_current (FlRenderer *self)
 
void fl_renderer_clear_current (FlRenderer *self)
 
guint32 fl_renderer_get_fbo (FlRenderer *self)
 
gboolean fl_renderer_create_backing_store (FlRenderer *renderer, const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
 
gboolean fl_renderer_collect_backing_store (FlRenderer *self, const FlutterBackingStore *backing_store)
 
void fl_renderer_wait_for_frame (FlRenderer *self, int target_width, int target_height)
 
gboolean fl_renderer_present_layers (FlRenderer *self, const FlutterLayer **layers, size_t layers_count)
 
void fl_renderer_setup (FlRenderer *self)
 
void fl_renderer_render (FlRenderer *self, int width, int height)
 
void fl_renderer_cleanup (FlRenderer *self)
 

Variables

static const char * vertex_shader_src
 
static const char * fragment_shader_src
 

Function Documentation

◆ fl_renderer_class_init()

static void fl_renderer_class_init ( FlRendererClass *  klass)
static

Definition at line 115 of file fl_renderer.cc.

115 {
116 G_OBJECT_CLASS(klass)->dispose = fl_renderer_dispose;
117}
static void fl_renderer_dispose(GObject *object)

◆ fl_renderer_cleanup()

void fl_renderer_cleanup ( FlRenderer *  renderer)

fl_renderer_cleanup:

Removes OpenGL resources used for rendering. Requires an active OpenGL context.

Definition at line 383 of file fl_renderer.cc.

383 {
384 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
385 fl_renderer_get_instance_private(self));
386
387 g_return_if_fail(FL_IS_RENDERER(self));
388
389 glDeleteProgram(priv->program);
390}
FlPixelBufferTexturePrivate * priv

◆ fl_renderer_clear_current()

void fl_renderer_clear_current ( FlRenderer *  renderer)

fl_renderer_clear_current: @renderer: an #FlRenderer.

Clears the current rendering context.

Definition at line 151 of file fl_renderer.cc.

151 {
152 g_return_if_fail(FL_IS_RENDERER(self));
153 FL_RENDERER_GET_CLASS(self)->clear_current(self);
154}

◆ fl_renderer_collect_backing_store()

gboolean fl_renderer_collect_backing_store ( FlRenderer *  renderer,
const FlutterBackingStore backing_store 
)

fl_renderer_collect_backing_store: @renderer: an #FlRenderer. @backing_store: backing store to be released.

A callback invoked by the engine to release the backing store. The embedder may collect any resources associated with the backing store.

Returns TRUE if successful.

Definition at line 192 of file fl_renderer.cc.

194 {
196
197 // OpenGL context is required when destroying #FlBackingStoreProvider.
198 g_object_unref(backing_store->open_gl.framebuffer.user_data);
199 return TRUE;
200}
void fl_renderer_make_current(FlRenderer *self)
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition embedder.h:1766
FlutterOpenGLFramebuffer framebuffer
Definition embedder.h:1614
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition embedder.h:397

◆ fl_renderer_create_backing_store()

gboolean fl_renderer_create_backing_store ( FlRenderer *  renderer,
const FlutterBackingStoreConfig config,
FlutterBackingStore backing_store_out 
)

fl_renderer_create_backing_store: @renderer: an #FlRenderer. @config: backing store config. @backing_store_out: saves created backing store.

Obtain a backing store for a specific FlutterLayer.

Returns TRUE if successful.

Definition at line 163 of file fl_renderer.cc.

166 {
167 fl_renderer_make_current(renderer);
168
169 FlBackingStoreProvider* provider =
171 if (!provider) {
172 g_warning("Failed to create backing store");
173 return FALSE;
174 }
175
178
179 backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
181 backing_store_out->open_gl.framebuffer.user_data = provider;
182 backing_store_out->open_gl.framebuffer.name = name;
183 backing_store_out->open_gl.framebuffer.target = format;
184 backing_store_out->open_gl.framebuffer.destruction_callback = [](void* p) {
185 // Backing store destroyed in fl_renderer_collect_backing_store(), set
186 // on FlutterCompositor.collect_backing_store_callback during engine start.
187 };
188
189 return TRUE;
190}
@ kFlutterOpenGLTargetTypeFramebuffer
Definition embedder.h:304
@ kFlutterBackingStoreTypeOpenGL
Definition embedder.h:1740
uint32_t fl_backing_store_provider_get_gl_framebuffer_id(FlBackingStoreProvider *self)
uint32_t fl_backing_store_provider_get_gl_format(FlBackingStoreProvider *self)
FlBackingStoreProvider * fl_backing_store_provider_new(int width, int height)
uint32_t uint32_t * format
const char * name
Definition fuchsia.cc:50
return FALSE
FlutterSize size
The size of the render target the engine expects to render into.
Definition embedder.h:1782
FlutterBackingStoreType type
Specifies the type of backing store.
Definition embedder.h:1760
FlutterOpenGLTargetType type
Definition embedder.h:1608
uint32_t name
The name of the framebuffer.
Definition embedder.h:394
VoidCallback destruction_callback
Definition embedder.h:401
double height
Definition embedder.h:423
double width
Definition embedder.h:422

◆ fl_renderer_dispose()

static void fl_renderer_dispose ( GObject *  object)
static

Definition at line 103 of file fl_renderer.cc.

103 {
104 FlRenderer* self = FL_RENDERER(object);
105 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
106 fl_renderer_get_instance_private(self));
107
109
110 g_clear_pointer(&priv->textures, g_ptr_array_unref);
111
112 G_OBJECT_CLASS(fl_renderer_parent_class)->dispose(object);
113}
static void fl_renderer_unblock_main_thread(FlRenderer *self)

◆ fl_renderer_get_fbo()

guint32 fl_renderer_get_fbo ( FlRenderer *  renderer)

fl_renderer_get_fbo: @renderer: an #FlRenderer.

Gets the frame buffer object to render to.

Returns: a frame buffer object index.

Definition at line 156 of file fl_renderer.cc.

156 {
157 g_return_val_if_fail(FL_IS_RENDERER(self), 0);
158
159 // There is only one frame buffer object - always return that.
160 return 0;
161}

◆ fl_renderer_get_proc_address()

void * fl_renderer_get_proc_address ( FlRenderer *  self,
const char *  name 
)

Definition at line 135 of file fl_renderer.cc.

135 {
136 g_return_val_if_fail(FL_IS_RENDERER(self), NULL);
137
138 return reinterpret_cast<void*>(eglGetProcAddress(name));
139}

◆ fl_renderer_init()

static void fl_renderer_init ( FlRenderer *  self)
static

Definition at line 119 of file fl_renderer.cc.

119 {
120 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
121 fl_renderer_get_instance_private(self));
122 priv->textures = g_ptr_array_new_with_free_func(g_object_unref);
123}

◆ fl_renderer_make_current()

void fl_renderer_make_current ( FlRenderer *  renderer)

fl_renderer_make_current: @renderer: an #FlRenderer.

Makes the rendering context current.

Definition at line 141 of file fl_renderer.cc.

141 {
142 g_return_if_fail(FL_IS_RENDERER(self));
143 FL_RENDERER_GET_CLASS(self)->make_current(self);
144}

◆ fl_renderer_make_resource_current()

void fl_renderer_make_resource_current ( FlRenderer *  renderer)

fl_renderer_make_resource_current: @renderer: an #FlRenderer.

Makes the resource rendering context current.

Definition at line 146 of file fl_renderer.cc.

146 {
147 g_return_if_fail(FL_IS_RENDERER(self));
148 FL_RENDERER_GET_CLASS(self)->make_resource_current(self);
149}

◆ fl_renderer_present_layers()

gboolean fl_renderer_present_layers ( FlRenderer *  renderer,
const FlutterLayer **  layers,
size_t  layers_count 
)

fl_renderer_present_layers: @renderer: an #FlRenderer. @layers: layers to be composited. @layers_count: number of layers.

Callback invoked by the engine to composite the contents of each layer onto the screen.

Returns TRUE if successful.

Definition at line 221 of file fl_renderer.cc.

223 {
224 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
225 fl_renderer_get_instance_private(self));
226
227 g_return_val_if_fail(FL_IS_RENDERER(self), FALSE);
228
229 // ignore incoming frame with wrong dimensions in trivial case with just one
230 // layer
231 if (priv->blocking_main_thread && layers_count == 1 &&
232 layers[0]->offset.x == 0 && layers[0]->offset.y == 0 &&
233 (layers[0]->size.width != priv->target_width ||
234 layers[0]->size.height != priv->target_height)) {
235 return true;
236 }
237
238 priv->had_first_frame = true;
239
241
242 if (!priv->view) {
243 return FALSE;
244 }
245
246 g_ptr_array_set_size(priv->textures, 0);
247 for (size_t i = 0; i < layers_count; ++i) {
248 const FlutterLayer* layer = layers[i];
249 switch (layer->type) {
251 const FlutterBackingStore* backing_store = layer->backing_store;
252 auto framebuffer = &backing_store->open_gl.framebuffer;
253 FlBackingStoreProvider* provider =
254 FL_BACKING_STORE_PROVIDER(framebuffer->user_data);
255 g_ptr_array_add(priv->textures, g_object_ref(provider));
256 } break;
258 // TODO(robert-ancell) Not implemented -
259 // https://github.com/flutter/flutter/issues/41724
260 } break;
261 }
262 }
263
264 fl_view_redraw(priv->view);
265
266 return TRUE;
267}
@ kFlutterLayerContentTypePlatformView
Indicates that the contents of this layer are determined by the embedder.
Definition embedder.h:1793
@ kFlutterLayerContentTypeBackingStore
Definition embedder.h:1791
void fl_view_redraw(FlView *self)
Definition fl_view.cc:805
FlutterLayerContentType type
Definition embedder.h:1822
const FlutterBackingStore * backing_store
Definition embedder.h:1826

◆ fl_renderer_render()

void fl_renderer_render ( FlRenderer *  renderer,
int  width,
int  height 
)

fl_renderer_render: @renderer: an #FlRenderer. @width: width of the window in pixels. @height: height of the window in pixels.

Performs OpenGL commands to render current Flutter view.

Definition at line 311 of file fl_renderer.cc.

311 {
312 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
313 fl_renderer_get_instance_private(self));
314
315 g_return_if_fail(FL_IS_RENDERER(self));
316
317 // Save bindings that are set by this function. All bindings must be restored
318 // to their original values because Skia expects that its bindings have not
319 // been altered.
320 GLint saved_texture_binding;
321 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
322 GLint saved_vao_binding;
323 glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &saved_vao_binding);
324 GLint saved_array_buffer_binding;
325 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
326
327 glClearColor(0.0, 0.0, 0.0, 1.0);
328 glClear(GL_COLOR_BUFFER_BIT);
329
330 glUseProgram(priv->program);
331
332 for (guint i = 0; i < priv->textures->len; i++) {
333 FlBackingStoreProvider* texture =
334 FL_BACKING_STORE_PROVIDER(g_ptr_array_index(priv->textures, i));
335
337 glBindTexture(GL_TEXTURE_2D, texture_id);
338
339 // Translate into OpenGL co-ordinates
340 GdkRectangle texture_geometry =
342 GLfloat texture_x = texture_geometry.x;
343 GLfloat texture_y = texture_geometry.y;
344 GLfloat texture_width = texture_geometry.width;
345 GLfloat texture_height = texture_geometry.height;
346 GLfloat x0 = pixels_to_gl_coords(texture_x, width);
347 GLfloat y0 =
348 pixels_to_gl_coords(height - (texture_y + texture_height), height);
349 GLfloat x1 = pixels_to_gl_coords(texture_x + texture_width, width);
350 GLfloat y1 = pixels_to_gl_coords(height - texture_y, height);
351 GLfloat vertex_data[] = {x0, y0, 0, 0, x1, y1, 1, 1, x0, y1, 0, 1,
352 x0, y0, 0, 0, x1, y0, 1, 0, x1, y1, 1, 1};
353
354 GLuint vao, vertex_buffer;
355 glGenVertexArrays(1, &vao);
356 glBindVertexArray(vao);
357 glGenBuffers(1, &vertex_buffer);
358 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
359 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
360 GL_STATIC_DRAW);
361 GLint position_index = glGetAttribLocation(priv->program, "position");
362 glEnableVertexAttribArray(position_index);
363 glVertexAttribPointer(position_index, 2, GL_FLOAT, GL_FALSE,
364 sizeof(GLfloat) * 4, 0);
365 GLint texcoord_index = glGetAttribLocation(priv->program, "in_texcoord");
366 glEnableVertexAttribArray(texcoord_index);
367 glVertexAttribPointer(texcoord_index, 2, GL_FLOAT, GL_FALSE,
368 sizeof(GLfloat) * 4, (void*)(sizeof(GLfloat) * 2));
369
370 glDrawArrays(GL_TRIANGLES, 0, 6);
371
372 glDeleteVertexArrays(1, &vao);
373 glDeleteBuffers(1, &vertex_buffer);
374 }
375
376 glFlush();
377
378 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
379 glBindVertexArray(saved_vao_binding);
380 glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding);
381}
uint32_t fl_backing_store_provider_get_gl_texture_id(FlBackingStoreProvider *self)
GdkRectangle fl_backing_store_provider_get_geometry(FlBackingStoreProvider *self)
static GLfloat pixels_to_gl_coords(GLfloat position, GLfloat pixels)
Converts a pixel co-ordinate from 0..pixels to OpenGL -1..1.
FlTexture * texture
int32_t height
int32_t width
int64_t texture_id

◆ fl_renderer_setup()

void fl_renderer_setup ( FlRenderer *  renderer)

fl_renderer_setup: @renderer: an #FlRenderer.

Creates OpenGL resources required before rendering. Requires an active OpenGL context.

Definition at line 269 of file fl_renderer.cc.

269 {
270 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
271 fl_renderer_get_instance_private(self));
272
273 g_return_if_fail(FL_IS_RENDERER(self));
274
275 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
276 glShaderSource(vertex_shader, 1, &vertex_shader_src, nullptr);
277 glCompileShader(vertex_shader);
278 int vertex_compile_status;
279 glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status);
280 if (vertex_compile_status == GL_FALSE) {
281 g_autofree gchar* shader_log = get_shader_log(vertex_shader);
282 g_warning("Failed to compile vertex shader: %s", shader_log);
283 }
284
285 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
286 glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr);
287 glCompileShader(fragment_shader);
288 int fragment_compile_status;
289 glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status);
290 if (fragment_compile_status == GL_FALSE) {
291 g_autofree gchar* shader_log = get_shader_log(fragment_shader);
292 g_warning("Failed to compile fragment shader: %s", shader_log);
293 }
294
295 priv->program = glCreateProgram();
296 glAttachShader(priv->program, vertex_shader);
297 glAttachShader(priv->program, fragment_shader);
298 glLinkProgram(priv->program);
299
300 int link_status;
301 glGetProgramiv(priv->program, GL_LINK_STATUS, &link_status);
302 if (link_status == GL_FALSE) {
303 g_autofree gchar* program_log = get_program_log(priv->program);
304 g_warning("Failed to link program: %s", program_log);
305 }
306
307 glDeleteShader(vertex_shader);
308 glDeleteShader(fragment_shader);
309}
static gchar * get_shader_log(GLuint shader)
static const char * fragment_shader_src
static gchar * get_program_log(GLuint program)
static const char * vertex_shader_src

◆ fl_renderer_start()

gboolean fl_renderer_start ( FlRenderer *  renderer,
FlView *  view 
)

fl_renderer_start: @renderer: an #FlRenderer. @view: the view Flutter is renderering to.

Start the renderer.

Returns: TRUE if successfully started.

Definition at line 125 of file fl_renderer.cc.

125 {
126 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
127 fl_renderer_get_instance_private(self));
128
129 g_return_val_if_fail(FL_IS_RENDERER(self), FALSE);
130
131 priv->view = view;
132 return TRUE;
133}

◆ fl_renderer_unblock_main_thread()

static void fl_renderer_unblock_main_thread ( FlRenderer *  self)
static

Definition at line 91 of file fl_renderer.cc.

91 {
92 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
93 fl_renderer_get_instance_private(self));
94 if (priv->blocking_main_thread) {
95 priv->blocking_main_thread = false;
96
97 FlTaskRunner* runner =
100 }
101}
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition fl_engine.cc:900
void fl_task_runner_release_main_thread(FlTaskRunner *self)
G_MODULE_EXPORT FlEngine * fl_view_get_engine(FlView *self)
Definition fl_view.cc:800

◆ fl_renderer_wait_for_frame()

void fl_renderer_wait_for_frame ( FlRenderer *  renderer,
int  target_width,
int  target_height 
)

fl_renderer_wait_for_frame: @renderer: an #FlRenderer. @target_width: width of frame being waited for @target_height: height of frame being waited for

Holds the thread until frame with requested dimensions is presented. While waiting for frame Flutter platform and raster tasks are being processed.

Definition at line 202 of file fl_renderer.cc.

204 {
205 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
206 fl_renderer_get_instance_private(self));
207
208 g_return_if_fail(FL_IS_RENDERER(self));
209
210 priv->target_width = target_width;
211 priv->target_height = target_height;
212
213 if (priv->had_first_frame && !priv->blocking_main_thread) {
214 priv->blocking_main_thread = true;
215 FlTaskRunner* runner =
218 }
219}
void fl_task_runner_block_main_thread(FlTaskRunner *self)

◆ get_program_log()

static gchar * get_program_log ( GLuint  program)
static

Definition at line 74 of file fl_renderer.cc.

74 {
75 int log_length;
76 gchar* log;
77
78 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
79
80 log = static_cast<gchar*>(g_malloc(log_length + 1));
81 glGetProgramInfoLog(program, log_length, nullptr, log);
82
83 return log;
84}

◆ get_shader_log()

static gchar * get_shader_log ( GLuint  shader)
static

Definition at line 61 of file fl_renderer.cc.

61 {
62 int log_length;
63 gchar* log;
64
65 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
66
67 log = static_cast<gchar*>(g_malloc(log_length + 1));
68 glGetShaderInfoLog(shader, log_length, nullptr, log);
69
70 return log;
71}

◆ pixels_to_gl_coords()

static GLfloat pixels_to_gl_coords ( GLfloat  position,
GLfloat  pixels 
)
static

Converts a pixel co-ordinate from 0..pixels to OpenGL -1..1.

Definition at line 87 of file fl_renderer.cc.

87 {
88 return (2.0 * position / pixels) - 1.0;
89}

Variable Documentation

◆ fragment_shader_src

const char* fragment_shader_src
static
Initial value:
=
"uniform sampler2D texture;\n"
"varying vec2 texcoord;\n"
"\n"
"void main() {\n"
" gl_FragColor = texture2D(texture, texcoord);\n"
"}\n"

Definition at line 27 of file fl_renderer.cc.

◆ vertex_shader_src

const char* vertex_shader_src
static
Initial value:
=
"attribute vec2 position;\n"
"attribute vec2 in_texcoord;\n"
"varying vec2 texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(position, 0, 1);\n"
" texcoord = in_texcoord;\n"
"}\n"

Definition at line 16 of file fl_renderer.cc.