Flutter Linux Embedder
fl_renderer.h File Reference
#include <gtk/gtk.h>
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h"
#include "flutter/shell/platform/embedder/embedder.h"

Go to the source code of this file.

Classes

struct  _FlRendererClass
 

Enumerations

enum  FlRendererError { FL_RENDERER_ERROR_FAILED }
 

Functions

GQuark fl_renderer_error_quark (void) G_GNUC_CONST
 
gboolean fl_renderer_start (FlRenderer *renderer, FlView *view)
 
: a function name.

fl_renderer_get_proc_address: @renderer: an #FlRenderer.

Gets the rendering API function that matches the given name.

Returns: a function pointer.

void * fl_renderer_get_proc_address (FlRenderer *renderer, const char *name)
 
void fl_renderer_make_current (FlRenderer *renderer)
 
void fl_renderer_make_resource_current (FlRenderer *renderer)
 
void fl_renderer_clear_current (FlRenderer *renderer)
 
guint32 fl_renderer_get_fbo (FlRenderer *renderer)
 
gboolean fl_renderer_create_backing_store (FlRenderer *renderer, const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
 
gboolean fl_renderer_collect_backing_store (FlRenderer *renderer, const FlutterBackingStore *backing_store)
 
gboolean fl_renderer_present_layers (FlRenderer *renderer, const FlutterLayer **layers, size_t layers_count)
 
void fl_renderer_wait_for_frame (FlRenderer *renderer, int target_width, int target_height)
 
void fl_renderer_setup (FlRenderer *renderer)
 
void fl_renderer_render (FlRenderer *renderer, int width, int height)
 
void fl_renderer_cleanup (FlRenderer *renderer)
 
gdouble fl_renderer_get_refresh_rate (FlRenderer *renderer)
 

Enumeration Type Documentation

◆ FlRendererError

FlRendererError: Errors for #FlRenderer objects to set on failures.

Enumerator
FL_RENDERER_ERROR_FAILED 

Definition at line 22 of file fl_renderer.h.

22  {
23  // NOLINTBEGIN(readability-identifier-naming)
25  // NOLINTEND(readability-identifier-naming)

Function Documentation

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

392  {
393  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
394  fl_renderer_get_instance_private(self));
395 
396  g_return_if_fail(FL_IS_RENDERER(self));
397 
398  glDeleteProgram(priv->program);
399 }

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

155  {
156  g_return_if_fail(FL_IS_RENDERER(self));
157  FL_RENDERER_GET_CLASS(self)->clear_current(self);
158 }

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

203  {
205 
206  // OpenGL context is required when destroying #FlBackingStoreProvider.
207  g_object_unref(backing_store->open_gl.framebuffer.user_data);
208  return TRUE;
209 }

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

175  {
176  fl_renderer_make_current(renderer);
177 
178  FlBackingStoreProvider* provider =
179  fl_backing_store_provider_new(config->size.width, config->size.height);
180  if (!provider) {
181  g_warning("Failed to create backing store");
182  return FALSE;
183  }
184 
185  uint32_t name = fl_backing_store_provider_get_gl_framebuffer_id(provider);
186  uint32_t format = fl_backing_store_provider_get_gl_format(provider);
187 
188  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
189  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
190  backing_store_out->open_gl.framebuffer.user_data = provider;
191  backing_store_out->open_gl.framebuffer.name = name;
192  backing_store_out->open_gl.framebuffer.target = format;
193  backing_store_out->open_gl.framebuffer.destruction_callback = [](void* p) {
194  // Backing store destroyed in fl_renderer_collect_backing_store(), set
195  // on FlutterCompositor.collect_backing_store_callback during engine start.
196  };
197 
198  return TRUE;
199 }

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_error_quark()

GQuark fl_renderer_error_quark ( void  )

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

165  {
166  g_return_val_if_fail(FL_IS_RENDERER(self), 0);
167 
168  // There is only one frame buffer object - always return that.
169  return 0;
170 }

Referenced by fl_engine_gl_get_fbo().

◆ fl_renderer_get_proc_address()

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

Definition at line 139 of file fl_renderer.cc.

139  {
140  g_return_val_if_fail(FL_IS_RENDERER(self), NULL);
141 
142  return reinterpret_cast<void*>(eglGetProcAddress(name));
143 }

Referenced by fl_engine_gl_proc_resolver().

◆ fl_renderer_get_refresh_rate()

gdouble fl_renderer_get_refresh_rate ( FlRenderer *  renderer)

fl_renderer_get_refresh_rate: @renderer: an #FlRenderer.

Returns: The refresh rate of the display in Hz. If the refresh rate is not available, returns -1.0.

Definition at line 160 of file fl_renderer.cc.

160  {
161  g_return_val_if_fail(FL_IS_RENDERER(self), -1.0);
162  return FL_RENDERER_GET_CLASS(self)->get_refresh_rate(self);
163 }

Referenced by fl_engine_start(), and TEST().

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

145  {
146  g_return_if_fail(FL_IS_RENDERER(self));
147  FL_RENDERER_GET_CLASS(self)->make_current(self);
148 }

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

150  {
151  g_return_if_fail(FL_IS_RENDERER(self));
152  FL_RENDERER_GET_CLASS(self)->make_resource_current(self);
153 }

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

232  {
233  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
234  fl_renderer_get_instance_private(self));
235 
236  g_return_val_if_fail(FL_IS_RENDERER(self), FALSE);
237 
238  // ignore incoming frame with wrong dimensions in trivial case with just one
239  // layer
240  if (priv->blocking_main_thread && layers_count == 1 &&
241  layers[0]->offset.x == 0 && layers[0]->offset.y == 0 &&
242  (layers[0]->size.width != priv->target_width ||
243  layers[0]->size.height != priv->target_height)) {
244  return true;
245  }
246 
247  priv->had_first_frame = true;
248 
250 
251  if (!priv->view) {
252  return FALSE;
253  }
254 
255  g_ptr_array_set_size(priv->textures, 0);
256  for (size_t i = 0; i < layers_count; ++i) {
257  const FlutterLayer* layer = layers[i];
258  switch (layer->type) {
259  case kFlutterLayerContentTypeBackingStore: {
260  const FlutterBackingStore* backing_store = layer->backing_store;
261  auto framebuffer = &backing_store->open_gl.framebuffer;
262  FlBackingStoreProvider* provider =
263  FL_BACKING_STORE_PROVIDER(framebuffer->user_data);
264  g_ptr_array_add(priv->textures, g_object_ref(provider));
265  } break;
266  case kFlutterLayerContentTypePlatformView: {
267  // TODO(robert-ancell) Not implemented -
268  // https://github.com/flutter/flutter/issues/41724
269  } break;
270  }
271  }
272 
273  fl_view_redraw(priv->view);
274 
275  return TRUE;
276 }

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

Referenced by compositor_present_layers_callback(), and TEST().

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

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

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

Referenced by render_cb(), and TEST().

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

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

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

129  {
130  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
131  fl_renderer_get_instance_private(self));
132 
133  g_return_val_if_fail(FL_IS_RENDERER(self), FALSE);
134 
135  priv->view = view;
136  return TRUE;
137 }

References priv, and TRUE.

Referenced by realize_cb(), and TEST().

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

213  {
214  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
215  fl_renderer_get_instance_private(self));
216 
217  g_return_if_fail(FL_IS_RENDERER(self));
218 
219  priv->target_width = target_width;
220  priv->target_height = target_height;
221 
222  if (priv->had_first_frame && !priv->blocking_main_thread) {
223  priv->blocking_main_thread = true;
224  FlTaskRunner* runner =
227  }
228 }

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

Referenced by handle_geometry_changed(), and TEST().

FL_RENDERER_ERROR_FAILED
@ FL_RENDERER_ERROR_FAILED
Definition: fl_renderer.h:24
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
i
int i
Definition: fl_socket_accessible.cc:18
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
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:842
fl_view_redraw
void fl_view_redraw(FlView *self)
Definition: fl_view.cc:847
get_shader_log
static gchar * get_shader_log(GLuint shader)
Definition: fl_renderer.cc:65
fl_renderer_unblock_main_thread
static void fl_renderer_unblock_main_thread(FlRenderer *self)
Definition: fl_renderer.cc:95
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:78
fl_engine_get_task_runner
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:924
fl_renderer_make_current
void fl_renderer_make_current(FlRenderer *self)
Definition: fl_renderer.cc:145
FlRendererError
FlRendererError
Definition: fl_renderer.h:22
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:91
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:41
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:176
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