Flutter Linux Embedder
fl_renderer.h File Reference
#include <gtk/gtk.h>
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/fl_renderable.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.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
 
void fl_renderer_set_engine (FlRenderer *renderer, FlEngine *engine)
 
void fl_renderer_add_renderable (FlRenderer *renderer, FlutterViewId view_id, FlRenderable *renderable)
 
void fl_renderer_remove_view (FlRenderer *renderer, FlutterViewId view_id)
 
: 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, FlutterViewId view_id, 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, FlutterViewId view_id, int width, int height, const GdkRGBA *background_color)
 
void fl_renderer_cleanup (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.

Function Documentation

◆ fl_renderer_add_renderable()

void fl_renderer_add_renderable ( FlRenderer *  renderer,
FlutterViewId  view_id,
FlRenderable *  renderable 
)

fl_renderer_add_renderable: @renderer: an #FlRenderer. @view_id: the ID of the view. @renderable: object that is to be rendered on.

Add a view to render on.

Definition at line 341 of file fl_renderer.cc.

343  {
344  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
345  fl_renderer_get_instance_private(self));
346 
347  g_return_if_fail(FL_IS_RENDERER(self));
348 
349  GWeakRef* ref = g_new(GWeakRef, 1);
350  g_weak_ref_init(ref, G_OBJECT(renderable));
351  g_hash_table_insert(priv->views, GINT_TO_POINTER(view_id), ref);
352 }

References priv.

Referenced by fl_view_new_for_engine(), realize_cb(), and TEST().

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

608  {
609  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
610  fl_renderer_get_instance_private(self));
611 
612  g_return_if_fail(FL_IS_RENDERER(self));
613 
614  if (priv->program != 0) {
615  glDeleteProgram(priv->program);
616  }
617 }

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

379  {
380  g_return_if_fail(FL_IS_RENDERER(self));
381  FL_RENDERER_GET_CLASS(self)->clear_current(self);
382 }

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

425  {
427 
428  // OpenGL context is required when destroying #FlFramebuffer.
429  g_object_unref(backing_store->open_gl.framebuffer.user_data);
430  return TRUE;
431 }

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

394  {
395  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
396  fl_renderer_get_instance_private(self));
397 
399 
400  initialize(self);
401 
402  FlFramebuffer* framebuffer = fl_framebuffer_new(
403  priv->general_format, config->size.width, config->size.height);
404  if (!framebuffer) {
405  g_warning("Failed to create backing store");
406  return FALSE;
407  }
408 
409  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
410  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
411  backing_store_out->open_gl.framebuffer.user_data = framebuffer;
412  backing_store_out->open_gl.framebuffer.name =
413  fl_framebuffer_get_id(framebuffer);
414  backing_store_out->open_gl.framebuffer.target = priv->sized_format;
415  backing_store_out->open_gl.framebuffer.destruction_callback = [](void* p) {
416  // Backing store destroyed in fl_renderer_collect_backing_store(), set
417  // on FlutterCompositor.collect_backing_store_callback during engine start.
418  };
419 
420  return TRUE;
421 }

References fl_framebuffer_get_id(), fl_framebuffer_new(), fl_renderer_make_current(), initialize(), priv, and TRUE.

Referenced by compositor_create_backing_store_callback(), and TEST().

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

384  {
385  g_return_val_if_fail(FL_IS_RENDERER(self), 0);
386 
387  // There is only one frame buffer object - always return that.
388  return 0;
389 }

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

363  {
364  g_return_val_if_fail(FL_IS_RENDERER(self), NULL);
365 
366  return reinterpret_cast<void*>(eglGetProcAddress(name));
367 }

Referenced by fl_engine_gl_proc_resolver().

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

369  {
370  g_return_if_fail(FL_IS_RENDERER(self));
371  FL_RENDERER_GET_CLASS(self)->make_current(self);
372 }

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

374  {
375  g_return_if_fail(FL_IS_RENDERER(self));
376  FL_RENDERER_GET_CLASS(self)->make_resource_current(self);
377 }

Referenced by fl_engine_gl_make_resource_current().

◆ fl_renderer_present_layers()

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

fl_renderer_present_layers: @renderer: an #FlRenderer. @view_id: view to present. @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 453 of file fl_renderer.cc.

456  {
457  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
458  fl_renderer_get_instance_private(self));
459 
460  g_return_val_if_fail(FL_IS_RENDERER(self), FALSE);
461 
462  // ignore incoming frame with wrong dimensions in trivial case with just one
463  // layer
464  if (priv->blocking_main_thread && layers_count == 1 &&
465  layers[0]->offset.x == 0 && layers[0]->offset.y == 0 &&
466  (layers[0]->size.width != priv->target_width ||
467  layers[0]->size.height != priv->target_height)) {
468  return TRUE;
469  }
470 
471  priv->had_first_frame = true;
472 
474 
475  g_autoptr(GPtrArray) framebuffers =
476  g_ptr_array_new_with_free_func(g_object_unref);
477  for (size_t i = 0; i < layers_count; ++i) {
478  const FlutterLayer* layer = layers[i];
479  switch (layer->type) {
480  case kFlutterLayerContentTypeBackingStore: {
481  const FlutterBackingStore* backing_store = layer->backing_store;
482  FlFramebuffer* framebuffer =
483  FL_FRAMEBUFFER(backing_store->open_gl.framebuffer.user_data);
484  g_ptr_array_add(framebuffers, g_object_ref(framebuffer));
485  } break;
486  case kFlutterLayerContentTypePlatformView: {
487  // TODO(robert-ancell) Not implemented -
488  // https://github.com/flutter/flutter/issues/41724
489  } break;
490  }
491  }
492 
493  GWeakRef* ref = static_cast<GWeakRef*>(
494  g_hash_table_lookup(priv->views, GINT_TO_POINTER(view_id)));
495  g_autoptr(FlRenderable) renderable =
496  ref != nullptr ? FL_RENDERABLE(g_weak_ref_get(ref)) : nullptr;
497  if (renderable == nullptr) {
498  return TRUE;
499  }
500 
501  if (view_id == flutter::kFlutterImplicitViewId) {
502  // Store for rendering later
503  g_hash_table_insert(priv->framebuffers_by_view_id, GINT_TO_POINTER(view_id),
504  g_ptr_array_ref(framebuffers));
505  } else {
506  // Composite into a single framebuffer.
507  if (framebuffers->len > 1) {
508  size_t width = 0, height = 0;
509 
510  for (guint i = 0; i < framebuffers->len; i++) {
511  FlFramebuffer* framebuffer =
512  FL_FRAMEBUFFER(g_ptr_array_index(framebuffers, i));
513 
514  size_t w = fl_framebuffer_get_width(framebuffer);
515  size_t h = fl_framebuffer_get_height(framebuffer);
516  if (w > width) {
517  width = w;
518  }
519  if (h > height) {
520  height = h;
521  }
522  }
523 
524  FlFramebuffer* view_framebuffer =
525  fl_framebuffer_new(priv->general_format, width, height);
526  glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
527  fl_framebuffer_get_id(view_framebuffer));
528  render(self, framebuffers, width, height);
529  g_ptr_array_set_size(framebuffers, 0);
530  g_ptr_array_add(framebuffers, view_framebuffer);
531  }
532 
533  // Read back pixel values.
534  FlFramebuffer* framebuffer =
535  FL_FRAMEBUFFER(g_ptr_array_index(framebuffers, 0));
536  size_t width = fl_framebuffer_get_width(framebuffer);
537  size_t height = fl_framebuffer_get_height(framebuffer);
538  size_t data_length = width * height * 4;
539  g_autofree uint8_t* data = static_cast<uint8_t*>(malloc(data_length));
540  glBindFramebuffer(GL_READ_FRAMEBUFFER, fl_framebuffer_get_id(framebuffer));
541  glReadPixels(0, 0, width, height, priv->general_format, GL_UNSIGNED_BYTE,
542  data);
543 
544  // Write into a texture in the views context.
545  fl_renderable_make_current(renderable);
546  FlFramebuffer* view_framebuffer =
547  fl_framebuffer_new(priv->general_format, width, height);
548  glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
549  fl_framebuffer_get_id(view_framebuffer));
550  glBindTexture(GL_TEXTURE_2D,
551  fl_framebuffer_get_texture_id(view_framebuffer));
552  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
553  GL_UNSIGNED_BYTE, data);
554 
555  g_autoptr(GPtrArray) secondary_framebuffers =
556  g_ptr_array_new_with_free_func(g_object_unref);
557  g_ptr_array_add(secondary_framebuffers, g_object_ref(view_framebuffer));
558  g_hash_table_insert(priv->framebuffers_by_view_id, GINT_TO_POINTER(view_id),
559  g_ptr_array_ref(secondary_framebuffers));
560  }
561 
562  fl_renderable_redraw(renderable);
563 
564  return TRUE;
565 }

References fl_framebuffer_get_height(), fl_framebuffer_get_id(), fl_framebuffer_get_texture_id(), fl_framebuffer_get_width(), fl_framebuffer_new(), fl_renderable_make_current(), fl_renderable_redraw(), fl_renderer_unblock_main_thread(), height, i, priv, render(), TRUE, and width.

Referenced by compositor_present_view_callback(), and TEST().

◆ fl_renderer_remove_view()

void fl_renderer_remove_view ( FlRenderer *  renderer,
FlutterViewId  view_id 
)

fl_renderer_remove_view: @renderer: an #FlRenderer. @view_id: the ID of the view.

Remove a view from the renderer.

Definition at line 354 of file fl_renderer.cc.

354  {
355  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
356  fl_renderer_get_instance_private(self));
357 
358  g_return_if_fail(FL_IS_RENDERER(self));
359 
360  g_hash_table_remove(priv->views, GINT_TO_POINTER(view_id));
361 }

References priv.

Referenced by fl_view_dispose().

◆ fl_renderer_render()

void fl_renderer_render ( FlRenderer *  renderer,
FlutterViewId  view_id,
int  width,
int  height,
const GdkRGBA *  background_color 
)

fl_renderer_render: @renderer: an #FlRenderer. @view_id: view to render. @width: width of the window in pixels. @height: height of the window in pixels. @background_color: color to use for background.

Performs OpenGL commands to render current Flutter view.

Definition at line 585 of file fl_renderer.cc.

589  {
590  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
591  fl_renderer_get_instance_private(self));
592 
593  g_return_if_fail(FL_IS_RENDERER(self));
594 
595  glClearColor(background_color->red, background_color->green,
596  background_color->blue, background_color->alpha);
597  glClear(GL_COLOR_BUFFER_BIT);
598 
599  GPtrArray* framebuffers = reinterpret_cast<GPtrArray*>((g_hash_table_lookup(
600  priv->framebuffers_by_view_id, GINT_TO_POINTER(view_id))));
601  if (framebuffers != nullptr) {
602  render(self, framebuffers, width, height);
603  }
604 
605  glFlush();
606 }

References height, priv, render(), and width.

Referenced by render_cb(), and TEST().

◆ fl_renderer_set_engine()

void fl_renderer_set_engine ( FlRenderer *  renderer,
FlEngine *  engine 
)

fl_renderer_set_engine: @renderer: an #FlRenderer. @engine: an #FlEngine.

Called when the renderer is connected to an engine.

Definition at line 332 of file fl_renderer.cc.

332  {
333  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
334  fl_renderer_get_instance_private(self));
335 
336  g_return_if_fail(FL_IS_RENDERER(self));
337 
338  g_weak_ref_init(&priv->engine, engine);
339 }

References priv.

Referenced by fl_engine_new_with_renderer().

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

567  {
568  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
569  fl_renderer_get_instance_private(self));
570 
571  g_return_if_fail(FL_IS_RENDERER(self));
572 
573  // Note: NVIDIA and Vivante are temporarily disabled due to
574  // https://github.com/flutter/flutter/issues/152099
575  priv->has_gl_framebuffer_blit =
576  !is_nvidia() && !is_vivante() &&
577  (epoxy_gl_version() >= 30 ||
578  epoxy_has_gl_extension("GL_EXT_framebuffer_blit"));
579 
580  if (!priv->has_gl_framebuffer_blit) {
581  setup_shader(self);
582  }
583 }

References is_nvidia(), is_vivante(), priv, and setup_shader().

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

435  {
436  FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
437  fl_renderer_get_instance_private(self));
438 
439  g_return_if_fail(FL_IS_RENDERER(self));
440 
441  priv->target_width = target_width;
442  priv->target_height = target_height;
443 
444  if (priv->had_first_frame && !priv->blocking_main_thread) {
445  priv->blocking_main_thread = true;
446  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&priv->engine));
447  if (engine != nullptr) {
449  }
450  }
451 }

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

Referenced by handle_geometry_changed(), and TEST().

FL_RENDERER_ERROR_FAILED
@ FL_RENDERER_ERROR_FAILED
Definition: fl_renderer.h:23
i
int i
Definition: fl_socket_accessible.cc:18
priv
FlPixelBufferTexturePrivate * priv
Definition: fl_pixel_buffer_texture.cc:30
fl_framebuffer_get_texture_id
GLuint fl_framebuffer_get_texture_id(FlFramebuffer *self)
Definition: fl_framebuffer.cc:86
fl_framebuffer_get_height
size_t fl_framebuffer_get_height(FlFramebuffer *self)
Definition: fl_framebuffer.cc:98
is_vivante
static gboolean is_vivante()
Definition: fl_renderer.cc:93
setup_shader
static void setup_shader(FlRenderer *self)
Definition: fl_renderer.cc:161
fl_framebuffer_new
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height)
Definition: fl_framebuffer.cc:42
initialize
static void initialize(FlRenderer *self)
Definition: fl_renderer.cc:130
fl_framebuffer_get_width
size_t fl_framebuffer_get_width(FlFramebuffer *self)
Definition: fl_framebuffer.cc:94
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_renderer_unblock_main_thread
static void fl_renderer_unblock_main_thread(FlRenderer *self)
Definition: fl_renderer.cc:148
height
const uint8_t uint32_t uint32_t * height
Definition: fl_pixel_buffer_texture_test.cc:39
render
static void render(FlRenderer *self, GPtrArray *framebuffers, int width, int height)
Definition: fl_renderer.cc:290
fl_engine_get_task_runner
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:1209
fl_renderer_make_current
void fl_renderer_make_current(FlRenderer *self)
Definition: fl_renderer.cc:369
FlRendererError
FlRendererError
Definition: fl_renderer.h:22
fl_renderable_redraw
void fl_renderable_redraw(FlRenderable *self)
Definition: fl_renderable.cc:11
fl_renderable_make_current
void fl_renderable_make_current(FlRenderable *self)
Definition: fl_renderable.cc:17
is_nvidia
static gboolean is_nvidia()
Definition: fl_renderer.cc:87
width
const uint8_t uint32_t * width
Definition: fl_pixel_buffer_texture_test.cc:38
FlRendererPrivate
Definition: fl_renderer.cc:41
fl_task_runner_block_main_thread
void fl_task_runner_block_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:176
fl_framebuffer_get_id
GLuint fl_framebuffer_get_id(FlFramebuffer *self)
Definition: fl_framebuffer.cc:82