| Flutter Linux Embedder |

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_engine_private.h"`
`#include "flutter/shell/platform/linux/fl_framebuffer.h"`
`#include "flutter/shell/platform/linux/fl_view_private.h"`

Go to the source code of this file.

## Classes
struct | FlRendererPrivate

## Functions
static gboolean | is_nvidia ()
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 | initialize (FlRenderer *self)
static void | fl_renderer_unblock_main_thread (FlRenderer *self)
static void | setup_shader (FlRenderer *self)
static void | render_with_blit (FlRenderer *self, GPtrArray *framebuffers)
static void | render_with_textures (FlRenderer *self, GPtrArray *framebuffers, int width, int height)
static void | fl_renderer_dispose (GObject *object)
static void | fl_renderer_class_init (FlRendererClass *klass)
static void | fl_renderer_init (FlRenderer *self)
void | fl_renderer_set_engine (FlRenderer *self, FlEngine *engine)
void | fl_renderer_add_view (FlRenderer *self, FlutterViewId view_id, FlView *view)
void | fl_renderer_remove_view (FlRenderer *self, FlutterViewId view_id)
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)
gdouble | fl_renderer_get_refresh_rate (FlRenderer *self)
guint32 | fl_renderer_get_fbo (FlRenderer *self)
gboolean | fl_renderer_create_backing_store (FlRenderer *self, 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, FlutterViewId view_id, const FlutterLayer **layers, size_t layers_count)
void | fl_renderer_setup (FlRenderer *self)
void | fl_renderer_render (FlRenderer *self, FlutterViewId view_id, int width, int height, const GdkRGBA *background_color)
void | fl_renderer_cleanup (FlRenderer *self)

## Variables
static const char * | vertex_shader_src
static const char * | fragment_shader_src

## Function Documentation

## ◆ fl_renderer_add_view()

void fl_renderer_add_view | ( | FlRenderer * | renderer,
|  | FlutterViewId | view_id,
|  | FlView * | view
| ) |  |

fl_renderer_add_view: @renderer: an #FlRenderer. @view_id: the ID of the view. @view: the view Flutter is renderering to.

Add a view to render on.

Definition at line 314 of file fl_renderer.cc.

316 {
317 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
318 fl_renderer_get_instance_private(self));
319
320 g_return_if_fail(FL_IS_RENDERER(self));
321
322 g_hash_table_insert(priv->views, GINT_TO_POINTER(view_id), view);
323 }

References priv, and view.

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

## ◆ fl_renderer_class_init()

static void fl_renderer_class_init | ( | FlRendererClass * | klass | ) |
| static

Definition at line 291 of file fl_renderer.cc.

291 {
292 G_OBJECT_CLASS(klass)->dispose = fl_renderer_dispose;
293 }

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

528 {
529 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
530 fl_renderer_get_instance_private(self));
531
532 g_return_if_fail(FL_IS_RENDERER(self));
533
534 if (priv->program != 0) {
535 glDeleteProgram(priv->program);
536 }
537 }

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

350 {
351 g_return_if_fail(FL_IS_RENDERER(self));
352 FL_RENDERER_GET_CLASS(self)->clear_current(self);
353 }

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

401 {
402 fl_renderer_make_current(self);
403
404 // OpenGL context is required when destroying #FlFramebuffer.
405 g_object_unref(backing_store->open_gl.framebuffer.user_data);
406 return TRUE;
407 }

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

370 {
371 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
372 fl_renderer_get_instance_private(self));
373
374 fl_renderer_make_current(self);
375
376 initialize(self);
377
378 FlFramebuffer* framebuffer = fl_framebuffer_new(
379 priv->general_format, config->size.width, config->size.height);
380 if (!framebuffer) {
381 g_warning("Failed to create backing store");
382 return FALSE;
383 }
384
385 backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
386 backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
387 backing_store_out->open_gl.framebuffer.user_data = framebuffer;
388 backing_store_out->open_gl.framebuffer.name =
389 fl_framebuffer_get_id(framebuffer);
390 backing_store_out->open_gl.framebuffer.target = priv->sized_format;
391 backing_store_out->open_gl.framebuffer.destruction_callback = [](void* p) {
392 // Backing store destroyed in fl_renderer_collect_backing_store(), set
393 // on FlutterCompositor.collect_backing_store_callback during engine start.
394 };
395
396 return TRUE;
397 }

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

static void fl_renderer_dispose | ( | GObject * | object | ) |
| static

Definition at line 277 of file fl_renderer.cc.

277 {
278 FlRenderer* self = FL_RENDERER(object);
279 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
280 fl_renderer_get_instance_private(self));
281
282 fl_renderer_unblock_main_thread(self);
283
284 g_weak_ref_clear(&priv->engine);
285 g_clear_pointer(&priv->views, g_hash_table_unref);
286 g_clear_pointer(&priv->framebuffers_by_view_id, g_hash_table_unref);
287
288 G_OBJECT_CLASS(fl_renderer_parent_class)->dispose(object);
289 }

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

360 {
361 g_return_val_if_fail(FL_IS_RENDERER(self), 0);
362
363 // There is only one frame buffer object - always return that.
364 return 0;
365 }

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

334 {
335 g_return_val_if_fail(FL_IS_RENDERER(self), NULL);
336
337 return reinterpret_cast<void*>(eglGetProcAddress(name));
338 }

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

355 {
356 g_return_val_if_fail(FL_IS_RENDERER(self), -1.0);
357 return FL_RENDERER_GET_CLASS(self)->get_refresh_rate(self);
358 }

Referenced by fl_engine_start(), and TEST().

## ◆ fl_renderer_init()

static void fl_renderer_init | ( | FlRenderer * | self | ) |
| static

Definition at line 295 of file fl_renderer.cc.

295 {
296 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
297 fl_renderer_get_instance_private(self));
298 priv->views =
299 g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr, nullptr);
300 priv->framebuffers_by_view_id =
301 g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr,
302 (GDestroyNotify)g_ptr_array_unref);
303 }

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

340 {
341 g_return_if_fail(FL_IS_RENDERER(self));
342 FL_RENDERER_GET_CLASS(self)->make_current(self);
343 }

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

345 {
346 g_return_if_fail(FL_IS_RENDERER(self));
347 FL_RENDERER_GET_CLASS(self)->make_resource_current(self);
348 }

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

432 {
433 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
434 fl_renderer_get_instance_private(self));
435
436 g_return_val_if_fail(FL_IS_RENDERER(self), FALSE);
437
438 // ignore incoming frame with wrong dimensions in trivial case with just one
439 // layer
440 if (priv->blocking_main_thread && layers_count == 1 &&
441 layers[0]->offset.x == 0 && layers[0]->offset.y == 0 &&
442 (layers[0]->size.width != priv->target_width ||
443 layers[0]->size.height != priv->target_height)) {
444 return TRUE;
445 }
446
447 priv->had_first_frame = true;
448
449 fl_renderer_unblock_main_thread(self);
450
451 GPtrArray* framebuffers = reinterpret_cast<GPtrArray*>((g_hash_table_lookup(
452 priv->framebuffers_by_view_id, GINT_TO_POINTER(view_id))));
453 if (framebuffers == nullptr) {
454 framebuffers = g_ptr_array_new_with_free_func(g_object_unref);
455 g_hash_table_insert(priv->framebuffers_by_view_id, GINT_TO_POINTER(view_id),
456 framebuffers);
457 }
458 g_ptr_array_set_size(framebuffers, 0);
459 for (size_t i = 0; i < layers_count; ++i) {
460 const FlutterLayer* layer = layers[i];
461 switch (layer->type) {
462 case kFlutterLayerContentTypeBackingStore: {
463 const FlutterBackingStore* backing_store = layer->backing_store;
464 FlFramebuffer* framebuffer =
465 FL_FRAMEBUFFER(backing_store->open_gl.framebuffer.user_data);
466 g_ptr_array_add(framebuffers, g_object_ref(framebuffer));
467 } break;
468 case kFlutterLayerContentTypePlatformView: {
469 // TODO(robert-ancell) Not implemented -
470 // https://github.com/flutter/flutter/issues/41724
471 } break;
472 }
473 }
474
475 FlView* view =
476 FL_VIEW(g_hash_table_lookup(priv->views, GINT_TO_POINTER(view_id)));
477 if (view != nullptr) {
478 fl_view_redraw(view);
479 }
480
481 return TRUE;
482 }

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

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

325 {
326 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
327 fl_renderer_get_instance_private(self));
328
329 g_return_if_fail(FL_IS_RENDERER(self));
330
331 g_hash_table_remove(priv->views, GINT_TO_POINTER(view_id));
332 }

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

505 {
506 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
507 fl_renderer_get_instance_private(self));
508
509 g_return_if_fail(FL_IS_RENDERER(self));
510
511 glClearColor(background_color->red, background_color->green,
512 background_color->blue, background_color->alpha);
513 glClear(GL_COLOR_BUFFER_BIT);
514
515 GPtrArray* framebuffers = reinterpret_cast<GPtrArray*>((g_hash_table_lookup(
516 priv->framebuffers_by_view_id, GINT_TO_POINTER(view_id))));
517 if (framebuffers != nullptr) {
518 if (priv->has_gl_framebuffer_blit) {
519 render_with_blit(self, framebuffers);
520 } else {
521 render_with_textures(self, framebuffers, width, height);
522 }
523 }
524
525 glFlush();
526 }

References height, priv, render_with_blit(), render_with_textures(), 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 305 of file fl_renderer.cc.

305 {
306 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
307 fl_renderer_get_instance_private(self));
308
309 g_return_if_fail(FL_IS_RENDERER(self));
310
311 g_weak_ref_init(&priv->engine, engine);
312 }

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

484 {
485 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
486 fl_renderer_get_instance_private(self));
487
488 g_return_if_fail(FL_IS_RENDERER(self));
489
490 // Note: NVIDIA is temporarily disabled due to
491 // https://github.com/flutter/flutter/issues/152099
492 priv->has_gl_framebuffer_blit =
493 !is_nvidia() && (epoxy_gl_version() >= 30 ||
494 epoxy_has_gl_extension("GL_EXT_framebuffer_blit"));
495
496 if (!priv->has_gl_framebuffer_blit) {
497 setup_shader(self);
498 }
499 }

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

Referenced by realize_cb(), and TEST().

## ◆ fl_renderer_unblock_main_thread()

static void fl_renderer_unblock_main_thread | ( | FlRenderer * | self | ) |
| static

Definition at line 136 of file fl_renderer.cc.

136 {
137 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
138 fl_renderer_get_instance_private(self));
139 if (priv->blocking_main_thread) {
140 priv->blocking_main_thread = false;
141
142 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&priv->engine));
143 if (engine != nullptr) {
144 fl_task_runner_release_main_thread(fl_engine_get_task_runner(engine));
145 }
146 }
147 }

References fl_engine_get_task_runner(), fl_task_runner_release_main_thread(), 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 409 of file fl_renderer.cc.

411 {
412 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
413 fl_renderer_get_instance_private(self));
414
415 g_return_if_fail(FL_IS_RENDERER(self));
416
417 priv->target_width = target_width;
418 priv->target_height = target_height;
419
420 if (priv->had_first_frame && !priv->blocking_main_thread) {
421 priv->blocking_main_thread = true;
422 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&priv->engine));
423 if (engine != nullptr) {
424 fl_task_runner_block_main_thread(fl_engine_get_task_runner(engine));
425 }
426 }
427 }

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

Referenced by handle_geometry_changed(), and TEST().

## ◆ get_program_log()

static gchar* get_program_log | ( | GLuint | program | ) |
| static

Definition at line 100 of file fl_renderer.cc.

100 {
101 GLint log_length;
102 gchar* log;
103
104 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
105
106 log = static_cast<gchar*>(g_malloc(log_length + 1));
107 glGetProgramInfoLog(program, log_length, nullptr, log);
108
109 return log;
110 }

Referenced by setup_shader().

## ◆ get_shader_log()

static gchar* get_shader_log | ( | GLuint | shader | ) |
| static

Definition at line 87 of file fl_renderer.cc.

87 {
88 GLint log_length;
89 gchar* log;
90
91 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
92
93 log = static_cast<gchar*>(g_malloc(log_length + 1));
94 glGetShaderInfoLog(shader, log_length, nullptr, log);
95
96 return log;
97 }

Referenced by setup_shader().

## ◆ initialize()

static void initialize | ( | FlRenderer * | self | ) |
| static

Definition at line 118 of file fl_renderer.cc.

118 {
119 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
120 fl_renderer_get_instance_private(self));
121
122 if (priv->initialized) {
123 return;
124 }
125 priv->initialized = TRUE;
126
127 if (epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) {
128 priv->sized_format = GL_BGRA8_EXT;
129 priv->general_format = GL_BGRA_EXT;
130 } else {
131 priv->sized_format = GL_RGBA8;
132 priv->general_format = GL_RGBA;
133 }
134 }

References priv, and TRUE.

Referenced by fl_renderer_create_backing_store().

## ◆ is_nvidia()

static gboolean is_nvidia | ( |  | ) |
| static

Definition at line 81 of file fl_renderer.cc.

81 {
82 const gchar* vendor = reinterpret_cast<const gchar*>(glGetString(GL_VENDOR));
83 return strstr(vendor, "NVIDIA") != nullptr;
84 }

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

113 {
114 return (2.0 * position / pixels) - 1.0;
115 }

Referenced by render_with_textures().

## ◆ render_with_blit()

static void render_with_blit | ( | FlRenderer * | self,
|  | GPtrArray * | framebuffers
| ) |  |
| static

Definition at line 189 of file fl_renderer.cc.

189 {
190 // Disable the scissor test as it can affect blit operations.
191 // Prevents regressions like: https://github.com/flutter/flutter/issues/140828
192 // See OpenGL specification version 4.6, section 18.3.1.
193 glDisable(GL_SCISSOR_TEST);
194
195 for (guint i = 0; i < framebuffers->len; i++) {
196 FlFramebuffer* framebuffer =
197 FL_FRAMEBUFFER(g_ptr_array_index(framebuffers, i));
198
199 GLuint framebuffer_id = fl_framebuffer_get_id(framebuffer);
200 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer_id);
201 size_t width = fl_framebuffer_get_width(framebuffer);
202 size_t height = fl_framebuffer_get_height(framebuffer);
203 glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
204 GL_COLOR_BUFFER_BIT, GL_NEAREST);
205 }
206 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
207 }

References fl_framebuffer_get_height(), fl_framebuffer_get_id(), fl_framebuffer_get_width(), height, i, and width.

Referenced by fl_renderer_render().

## ◆ render_with_textures()

static void render_with_textures | ( | FlRenderer * | self,
|  | GPtrArray * | framebuffers,
|  | int | width,
|  | int | height
| ) |  |
| static

Definition at line 209 of file fl_renderer.cc.

212 {
213 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
214 fl_renderer_get_instance_private(self));
215
216 // Save bindings that are set by this function. All bindings must be restored
217 // to their original values because Skia expects that its bindings have not
218 // been altered.
219 GLint saved_texture_binding;
220 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
221 GLint saved_vao_binding;
222 glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &saved_vao_binding);
223 GLint saved_array_buffer_binding;
224 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
225
226 glEnable(GL_BLEND);
227 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
228
229 glUseProgram(priv->program);
230
231 for (guint i = 0; i < framebuffers->len; i++) {
232 FlFramebuffer* framebuffer =
233 FL_FRAMEBUFFER(g_ptr_array_index(framebuffers, i));
234
235 GLuint texture_id = fl_framebuffer_get_texture_id(framebuffer);
236 glBindTexture(GL_TEXTURE_2D, texture_id);
237
238 // Translate into OpenGL co-ordinates
239 size_t texture_width = fl_framebuffer_get_width(framebuffer);
240 size_t texture_height = fl_framebuffer_get_height(framebuffer);
241 GLfloat x0 = pixels_to_gl_coords(0, width);
242 GLfloat y0 = pixels_to_gl_coords(height - texture_height, height);
243 GLfloat x1 = pixels_to_gl_coords(texture_width, width);
244 GLfloat y1 = pixels_to_gl_coords(height, height);
245 GLfloat vertex_data[] = {x0, y0, 0, 0, x1, y1, 1, 1, x0, y1, 0, 1,
246 x0, y0, 0, 0, x1, y0, 1, 0, x1, y1, 1, 1};
247
248 GLuint vao, vertex_buffer;
249 glGenVertexArrays(1, &vao);
250 glBindVertexArray(vao);
251 glGenBuffers(1, &vertex_buffer);
252 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
253 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
254 GL_STATIC_DRAW);
255 GLint position_index = glGetAttribLocation(priv->program, "position");
256 glEnableVertexAttribArray(position_index);
257 glVertexAttribPointer(position_index, 2, GL_FLOAT, GL_FALSE,
258 sizeof(GLfloat) * 4, 0);
259 GLint texcoord_index = glGetAttribLocation(priv->program, "in_texcoord");
260 glEnableVertexAttribArray(texcoord_index);
261 glVertexAttribPointer(texcoord_index, 2, GL_FLOAT, GL_FALSE,
262 sizeof(GLfloat) * 4, (void*)(sizeof(GLfloat) * 2));
263
264 glDrawArrays(GL_TRIANGLES, 0, 6);
265
266 glDeleteVertexArrays(1, &vao);
267 glDeleteBuffers(1, &vertex_buffer);
268 }
269
270 glDisable(GL_BLEND);
271
272 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
273 glBindVertexArray(saved_vao_binding);
274 glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding);
275 }

References fl_framebuffer_get_height(), fl_framebuffer_get_texture_id(), fl_framebuffer_get_width(), height, i, pixels_to_gl_coords(), priv, texture_id, and width.

Referenced by fl_renderer_render().

## ◆ setup_shader()

static void setup_shader | ( | FlRenderer * | self | ) |
| static

Definition at line 149 of file fl_renderer.cc.

149 {
150 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
151 fl_renderer_get_instance_private(self));
152
153 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
154 glShaderSource(vertex_shader, 1, &vertex_shader_src, nullptr);
155 glCompileShader(vertex_shader);
156 GLint vertex_compile_status;
157 glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status);
158 if (vertex_compile_status == GL_FALSE) {
159 g_autofree gchar* shader_log = get_shader_log(vertex_shader);
160 g_warning("Failed to compile vertex shader: %s", shader_log);
161 }
162
163 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
164 glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr);
165 glCompileShader(fragment_shader);
166 GLint fragment_compile_status;
167 glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status);
168 if (fragment_compile_status == GL_FALSE) {
169 g_autofree gchar* shader_log = get_shader_log(fragment_shader);
170 g_warning("Failed to compile fragment shader: %s", shader_log);
171 }
172
173 priv->program = glCreateProgram();
174 glAttachShader(priv->program, vertex_shader);
175 glAttachShader(priv->program, fragment_shader);
176 glLinkProgram(priv->program);
177
178 GLint link_status;
179 glGetProgramiv(priv->program, GL_LINK_STATUS, &link_status);
180 if (link_status == GL_FALSE) {
181 g_autofree gchar* program_log = get_program_log(priv->program);
182 g_warning("Failed to link program: %s", program_log);
183 }
184
185 glDeleteShader(vertex_shader);
186 glDeleteShader(fragment_shader);
187 }

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

Referenced by fl_renderer_setup().

## Variable Documentation

## ◆ fragment_shader_src

const char* fragment_shader_src
| static

Initial value:
=
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"\n"
"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 setup_shader().

## ◆ 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 setup_shader().

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_framebuffer_get_texture_id
GLuint fl_framebuffer_get_texture_id(FlFramebuffer *self)
Definition: fl_framebuffer.cc:73
fl_framebuffer_get_height
size_t fl_framebuffer_get_height(FlFramebuffer *self)
Definition: fl_framebuffer.cc:85
setup_shader
static void setup_shader(FlRenderer *self)
Definition: fl_renderer.cc:149
fl_framebuffer_new
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height)
Definition: fl_framebuffer.cc:42
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:277
initialize
static void initialize(FlRenderer *self)
Definition: fl_renderer.cc:118
fl_framebuffer_get_width
size_t fl_framebuffer_get_width(FlFramebuffer *self)
Definition: fl_framebuffer.cc:81
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_view_redraw
void fl_view_redraw(FlView *self)
Definition: fl_view.cc:892
get_shader_log
static gchar * get_shader_log(GLuint shader)
Definition: fl_renderer.cc:87
fl_renderer_unblock_main_thread
static void fl_renderer_unblock_main_thread(FlRenderer *self)
Definition: fl_renderer.cc:136
fl_task_runner_release_main_thread
void fl_task_runner_release_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:197
height
const uint8_t uint32_t uint32_t * height
Definition: fl_pixel_buffer_texture_test.cc:39
get_program_log
static gchar * get_program_log(GLuint program)
Definition: fl_renderer.cc:100
view
FlView * view
Definition: fl_application.cc:35
fl_engine_get_task_runner
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:1001
fl_renderer_make_current
void fl_renderer_make_current(FlRenderer *self)
Definition: fl_renderer.cc:340
render_with_textures
static void render_with_textures(FlRenderer *self, GPtrArray *framebuffers, int width, int height)
Definition: fl_renderer.cc:209
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:113
render_with_blit
static void render_with_blit(FlRenderer *self, GPtrArray *framebuffers)
Definition: fl_renderer.cc:189
is_nvidia
static gboolean is_nvidia()
Definition: fl_renderer.cc:81
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
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:69