| Flutter Linux Embedder |

Classes | Enumerations | Functions
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

enum 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 FL_RENDERER_ERROR_FAILED,
24 } FlRendererError;
FlRendererError
FlRendererError
Definition: fl_renderer.h:22
FL_RENDERER_ERROR_FAILED
@ FL_RENDERER_ERROR_FAILED
Definition: fl_renderer.h:23

## 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 }
priv
FlPixelBufferTexturePrivate * priv
Definition: fl_pixel_buffer_texture.cc:30
FlRendererPrivate
Definition: fl_renderer.cc:41

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 {
426 fl_renderer_make_current(self);
427
428 // OpenGL context is required when destroying #FlFramebuffer.
429 g_object_unref(backing_store->open_gl.framebuffer.user_data);
430 return TRUE;
431 }
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_renderer_make_current
void fl_renderer_make_current(FlRenderer *self)
Definition: fl_renderer.cc:369

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
398 fl_renderer_make_current(self);
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 }
fl_framebuffer_get_id
GLuint fl_framebuffer_get_id(FlFramebuffer *self)
Definition: fl_framebuffer.cc:82
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

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
473 fl_renderer_unblock_main_thread(self);
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 }
fl_framebuffer_get_height
size_t fl_framebuffer_get_height(FlFramebuffer *self)
Definition: fl_framebuffer.cc:98
fl_framebuffer_get_width
size_t fl_framebuffer_get_width(FlFramebuffer *self)
Definition: fl_framebuffer.cc:94
fl_framebuffer_get_texture_id
GLuint fl_framebuffer_get_texture_id(FlFramebuffer *self)
Definition: fl_framebuffer.cc:86
height
const uint8_t uint32_t uint32_t * height
Definition: fl_pixel_buffer_texture_test.cc:39
width
const uint8_t uint32_t * width
Definition: fl_pixel_buffer_texture_test.cc:38
fl_renderable_make_current
void fl_renderable_make_current(FlRenderable *self)
Definition: fl_renderable.cc:17
fl_renderable_redraw
void fl_renderable_redraw(FlRenderable *self)
Definition: fl_renderable.cc:11
fl_renderer_unblock_main_thread
static void fl_renderer_unblock_main_thread(FlRenderer *self)
Definition: fl_renderer.cc:148
render
static void render(FlRenderer *self, GPtrArray *framebuffers, int width, int height)
Definition: fl_renderer.cc:290
i
int i
Definition: fl_socket_accessible.cc:18

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 }
setup_shader
static void setup_shader(FlRenderer *self)
Definition: fl_renderer.cc:161
is_vivante
static gboolean is_vivante()
Definition: fl_renderer.cc:93
is_nvidia
static gboolean is_nvidia()
Definition: fl_renderer.cc:87

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) {
448 fl_task_runner_block_main_thread(fl_engine_get_task_runner(engine));
449 }
450 }
451 }
fl_engine_get_task_runner
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:1209
fl_task_runner_block_main_thread
void fl_task_runner_block_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:176

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

Referenced by handle_geometry_changed(), and TEST().