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_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  {
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 
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 
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 
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) {
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) {
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) {
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