Flutter Linux Embedder
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. More...
 
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 }

References fl_renderer_dispose().

◆ 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 369 of file fl_renderer.cc.

369  {
370  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
371  fl_renderer_get_instance_private(self));
372 
373  g_return_if_fail(FL_IS_RENDERER(self));
374 
375  glDeleteProgram(priv->program);
376 }

References priv.

Referenced by unrealize_cb().

◆ 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 }

Referenced by fl_engine_gl_clear_current().

◆ 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 }

References fl_renderer_make_current(), and TRUE.

Referenced by compositor_collect_backing_store_callback().

◆ 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 =
170  fl_backing_store_provider_new(config->size.width, config->size.height);
171  if (!provider) {
172  g_warning("Failed to create backing store");
173  return FALSE;
174  }
175 
176  uint32_t name = fl_backing_store_provider_get_gl_framebuffer_id(provider);
177  uint32_t format = fl_backing_store_provider_get_gl_format(provider);
178 
179  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
180  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
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 }

References fl_backing_store_provider_get_gl_format(), fl_backing_store_provider_get_gl_framebuffer_id(), fl_backing_store_provider_new(), fl_renderer_make_current(), format, and TRUE.

Referenced by compositor_create_backing_store_callback().

◆ 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 }

References fl_renderer_unblock_main_thread(), and priv.

Referenced by fl_renderer_class_init().

◆ 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 }

Referenced by fl_engine_gl_get_fbo().

◆ 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 }

Referenced by fl_engine_gl_proc_resolver().

◆ 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 }

References priv.

◆ 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 }

Referenced by fl_engine_gl_make_current(), fl_renderer_collect_backing_store(), fl_renderer_create_backing_store(), realize_cb(), and unrealize_cb().

◆ 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 }

Referenced by fl_engine_gl_make_resource_current().

◆ 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) {
250  case kFlutterLayerContentTypeBackingStore: {
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;
257  case kFlutterLayerContentTypePlatformView: {
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 }

References fl_renderer_unblock_main_thread(), fl_view_redraw(), priv, and TRUE.

Referenced by compositor_present_layers_callback().

◆ 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  glClearColor(0.0, 0.0, 0.0, 1.0);
318  glClear(GL_COLOR_BUFFER_BIT);
319 
320  glUseProgram(priv->program);
321 
322  for (guint i = 0; i < priv->textures->len; i++) {
323  FlBackingStoreProvider* texture =
324  FL_BACKING_STORE_PROVIDER(g_ptr_array_index(priv->textures, i));
325 
327  glBindTexture(GL_TEXTURE_2D, texture_id);
328 
329  // Translate into OpenGL co-ordinates
330  GdkRectangle texture_geometry =
332  GLfloat texture_x = texture_geometry.x;
333  GLfloat texture_y = texture_geometry.y;
334  GLfloat texture_width = texture_geometry.width;
335  GLfloat texture_height = texture_geometry.height;
336  GLfloat x0 = pixels_to_gl_coords(texture_x, width);
337  GLfloat y0 =
338  pixels_to_gl_coords(height - (texture_y + texture_height), height);
339  GLfloat x1 = pixels_to_gl_coords(texture_x + texture_width, width);
340  GLfloat y1 = pixels_to_gl_coords(height - texture_y, height);
341  GLfloat vertex_data[] = {x0, y0, 0, 0, x1, y1, 1, 1, x0, y1, 0, 1,
342  x0, y0, 0, 0, x1, y0, 1, 0, x1, y1, 1, 1};
343 
344  GLuint vao, vertex_buffer;
345  glGenVertexArrays(1, &vao);
346  glBindVertexArray(vao);
347  glGenBuffers(1, &vertex_buffer);
348  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
349  glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
350  GL_STATIC_DRAW);
351  GLint position_index = glGetAttribLocation(priv->program, "position");
352  glEnableVertexAttribArray(position_index);
353  glVertexAttribPointer(position_index, 2, GL_FLOAT, GL_FALSE,
354  sizeof(GLfloat) * 4, 0);
355  GLint texcoord_index = glGetAttribLocation(priv->program, "in_texcoord");
356  glEnableVertexAttribArray(texcoord_index);
357  glVertexAttribPointer(texcoord_index, 2, GL_FLOAT, GL_FALSE,
358  sizeof(GLfloat) * 4, (void*)(sizeof(GLfloat) * 2));
359 
360  glDrawArrays(GL_TRIANGLES, 0, 6);
361 
362  glDeleteVertexArrays(1, &vao);
363  glDeleteBuffers(1, &vertex_buffer);
364  }
365 
366  glFlush();
367 }

References fl_backing_store_provider_get_geometry(), fl_backing_store_provider_get_gl_texture_id(), height, pixels_to_gl_coords(), priv, texture_id, and width.

Referenced by render_cb().

◆ 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 }

References fragment_shader_src, get_program_log(), get_shader_log(), priv, and vertex_shader_src.

Referenced by realize_cb().

◆ 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 }

References priv, and TRUE.

Referenced by realize_cb().

◆ 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 }

References fl_engine_get_task_runner(), fl_task_runner_release_main_thread(), fl_view_get_engine(), and priv.

Referenced by fl_renderer_dispose(), and fl_renderer_present_layers().

◆ 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 }

References fl_engine_get_task_runner(), fl_task_runner_block_main_thread(), fl_view_get_engine(), and priv.

Referenced by handle_geometry_changed().

◆ 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 }

Referenced by fl_renderer_setup().

◆ 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 }

Referenced by fl_renderer_setup().

◆ 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 }

Referenced by fl_renderer_render().

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.

Referenced by fl_renderer_setup().

◆ 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.

Referenced by fl_renderer_setup().

fl_backing_store_provider_get_gl_format
uint32_t fl_backing_store_provider_get_gl_format(FlBackingStoreProvider *self)
Definition: fl_backing_store_provider.cc:80
vertex_shader_src
static const char * vertex_shader_src
Definition: fl_renderer.cc:16
priv
FlPixelBufferTexturePrivate * priv
Definition: fl_pixel_buffer_texture.cc:30
fl_backing_store_provider_new
FlBackingStoreProvider * fl_backing_store_provider_new(int width, int height)
Definition: fl_backing_store_provider.cc:35
height
G_BEGIN_DECLS int height
Definition: fl_backing_store_provider.h:37
fl_backing_store_provider_get_gl_texture_id
uint32_t fl_backing_store_provider_get_gl_texture_id(FlBackingStoreProvider *self)
Definition: fl_backing_store_provider.cc:71
fragment_shader_src
static const char * fragment_shader_src
Definition: fl_renderer.cc:27
fl_renderer_dispose
static void fl_renderer_dispose(GObject *object)
Definition: fl_renderer.cc:103
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_view_get_engine
G_MODULE_EXPORT FlEngine * fl_view_get_engine(FlView *self)
Definition: fl_view.cc:800
fl_view_redraw
void fl_view_redraw(FlView *self)
Definition: fl_view.cc:805
get_shader_log
static gchar * get_shader_log(GLuint shader)
Definition: fl_renderer.cc:61
fl_renderer_unblock_main_thread
static void fl_renderer_unblock_main_thread(FlRenderer *self)
Definition: fl_renderer.cc:91
fl_task_runner_release_main_thread
void fl_task_runner_release_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:205
fl_backing_store_provider_get_geometry
GdkRectangle fl_backing_store_provider_get_geometry(FlBackingStoreProvider *self)
Definition: fl_backing_store_provider.cc:105
get_program_log
static gchar * get_program_log(GLuint program)
Definition: fl_renderer.cc:74
fl_engine_get_task_runner
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:900
fl_renderer_make_current
void fl_renderer_make_current(FlRenderer *self)
Definition: fl_renderer.cc:141
pixels_to_gl_coords
static GLfloat pixels_to_gl_coords(GLfloat position, GLfloat pixels)
Converts a pixel co-ordinate from 0..pixels to OpenGL -1..1.
Definition: fl_renderer.cc:87
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24
width
const uint8_t uint32_t * width
Definition: fl_pixel_buffer_texture_test.cc:38
FlRendererPrivate
Definition: fl_renderer.cc:37
format
uint32_t uint32_t * format
Definition: fl_texture_registrar_test.cc:41
fl_task_runner_block_main_thread
void fl_task_runner_block_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:184
fl_backing_store_provider_get_gl_framebuffer_id
uint32_t fl_backing_store_provider_get_gl_framebuffer_id(FlBackingStoreProvider *self)
Definition: fl_backing_store_provider.cc:66