Flutter Linux Embedder
fl_renderer.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "fl_renderer.h"
6 
7 #include <epoxy/egl.h>
8 #include <epoxy/gl.h>
9 
10 #include "flutter/shell/platform/embedder/embedder.h"
14 
15 // Vertex shader to draw Flutter window contents.
16 static const char* vertex_shader_src =
17  "attribute vec2 position;\n"
18  "attribute vec2 in_texcoord;\n"
19  "varying vec2 texcoord;\n"
20  "\n"
21  "void main() {\n"
22  " gl_Position = vec4(position, 0, 1);\n"
23  " texcoord = in_texcoord;\n"
24  "}\n";
25 
26 // Fragment shader to draw Flutter window contents.
27 static const char* fragment_shader_src =
28  "#ifdef GL_ES\n"
29  "precision mediump float;\n"
30  "#endif\n"
31  "\n"
32  "uniform sampler2D texture;\n"
33  "varying vec2 texcoord;\n"
34  "\n"
35  "void main() {\n"
36  " gl_FragColor = texture2D(texture, texcoord);\n"
37  "}\n";
38 
39 G_DEFINE_QUARK(fl_renderer_error_quark, fl_renderer_error)
40 
41 typedef struct {
42  // Engine we are rendering.
43  GWeakRef engine;
44 
45  // Flag to track lazy initialization.
46  gboolean initialized;
47 
48  // The pixel format passed to the engine.
49  GLint sized_format;
50 
51  // The format used to create textures.
53 
54  // Views being rendered.
55  GHashTable* views;
56 
57  // target dimension for resizing
60 
61  // whether the renderer waits for frame render
63 
64  // true if frame was completed; resizing is not synchronized until first frame
65  // was rendered
67 
68  // True if we can use glBlitFramebuffer.
70 
71  // Shader program.
72  GLuint program;
73 
74  // Framebuffers to render keyed by view ID.
77 
78 G_DEFINE_TYPE_WITH_PRIVATE(FlRenderer, fl_renderer, G_TYPE_OBJECT)
79 
80 // Check if running on an NVIDIA driver.
81 static gboolean is_nvidia() {
82  const gchar* vendor = reinterpret_cast<const gchar*>(glGetString(GL_VENDOR));
83  return strstr(vendor, "NVIDIA") != nullptr;
84 }
85 
86 // Returns the log for the given OpenGL shader. Must be freed by the caller.
87 static gchar* get_shader_log(GLuint shader) {
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 }
98 
99 // Returns the log for the given OpenGL program. Must be freed by the caller.
100 static gchar* get_program_log(GLuint program) {
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 }
111 
112 /// Converts a pixel co-ordinate from 0..pixels to OpenGL -1..1.
113 static GLfloat pixels_to_gl_coords(GLfloat position, GLfloat pixels) {
114  return (2.0 * position / pixels) - 1.0;
115 }
116 
117 // Perform single run OpenGL initialization.
118 static void initialize(FlRenderer* self) {
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 }
135 
136 static void fl_renderer_unblock_main_thread(FlRenderer* self) {
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 }
148 
149 static void setup_shader(FlRenderer* self) {
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 }
188 
189 static void render_with_blit(FlRenderer* self, GPtrArray* framebuffers) {
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 }
208 
209 static void render_with_textures(FlRenderer* self,
210  GPtrArray* framebuffers,
211  int width,
212  int height) {
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 }
276 
277 static void fl_renderer_dispose(GObject* object) {
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 }
290 
291 static void fl_renderer_class_init(FlRendererClass* klass) {
292  G_OBJECT_CLASS(klass)->dispose = fl_renderer_dispose;
293 }
294 
295 static void fl_renderer_init(FlRenderer* self) {
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 }
304 
305 void fl_renderer_set_engine(FlRenderer* self, FlEngine* engine) {
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 }
313 
314 void fl_renderer_add_view(FlRenderer* self,
315  FlutterViewId view_id,
316  FlView* view) {
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 }
324 
325 void fl_renderer_remove_view(FlRenderer* self, FlutterViewId view_id) {
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 }
333 
334 void* fl_renderer_get_proc_address(FlRenderer* self, const char* name) {
335  g_return_val_if_fail(FL_IS_RENDERER(self), NULL);
336 
337  return reinterpret_cast<void*>(eglGetProcAddress(name));
338 }
339 
340 void fl_renderer_make_current(FlRenderer* self) {
341  g_return_if_fail(FL_IS_RENDERER(self));
342  FL_RENDERER_GET_CLASS(self)->make_current(self);
343 }
344 
345 void fl_renderer_make_resource_current(FlRenderer* self) {
346  g_return_if_fail(FL_IS_RENDERER(self));
347  FL_RENDERER_GET_CLASS(self)->make_resource_current(self);
348 }
349 
350 void fl_renderer_clear_current(FlRenderer* self) {
351  g_return_if_fail(FL_IS_RENDERER(self));
352  FL_RENDERER_GET_CLASS(self)->clear_current(self);
353 }
354 
355 gdouble fl_renderer_get_refresh_rate(FlRenderer* self) {
356  g_return_val_if_fail(FL_IS_RENDERER(self), -1.0);
357  return FL_RENDERER_GET_CLASS(self)->get_refresh_rate(self);
358 }
359 
360 guint32 fl_renderer_get_fbo(FlRenderer* self) {
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 }
366 
368  FlRenderer* self,
369  const FlutterBackingStoreConfig* config,
370  FlutterBackingStore* backing_store_out) {
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 }
398 
400  FlRenderer* self,
401  const FlutterBackingStore* backing_store) {
403 
404  // OpenGL context is required when destroying #FlFramebuffer.
405  g_object_unref(backing_store->open_gl.framebuffer.user_data);
406  return TRUE;
407 }
408 
409 void fl_renderer_wait_for_frame(FlRenderer* self,
410  int target_width,
411  int target_height) {
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 }
428 
429 gboolean fl_renderer_present_layers(FlRenderer* self,
430  FlutterViewId view_id,
431  const FlutterLayer** layers,
432  size_t layers_count) {
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 }
483 
484 void fl_renderer_setup(FlRenderer* self) {
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 }
500 
501 void fl_renderer_render(FlRenderer* self,
502  FlutterViewId view_id,
503  int width,
504  int height,
505  const GdkRGBA* background_color) {
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 }
527 
528 void fl_renderer_cleanup(FlRenderer* self) {
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 }
fl_renderer_remove_view
void fl_renderer_remove_view(FlRenderer *self, FlutterViewId view_id)
Definition: fl_renderer.cc:325
fl_renderer_wait_for_frame
void fl_renderer_wait_for_frame(FlRenderer *self, int target_width, int target_height)
Definition: fl_renderer.cc:409
fl_renderer_present_layers
gboolean fl_renderer_present_layers(FlRenderer *self, FlutterViewId view_id, const FlutterLayer **layers, size_t layers_count)
Definition: fl_renderer.cc:429
fl_renderer_error_quark
GQuark fl_renderer_error_quark(void) G_GNUC_CONST
fl_renderer_init
static void fl_renderer_init(FlRenderer *self)
Definition: fl_renderer.cc:295
FlRendererPrivate::has_gl_framebuffer_blit
bool has_gl_framebuffer_blit
Definition: fl_renderer.cc:69
fl_renderer_get_refresh_rate
gdouble fl_renderer_get_refresh_rate(FlRenderer *self)
Definition: fl_renderer.cc:355
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
FlRendererPrivate::engine
GWeakRef engine
Definition: fl_renderer.cc:43
FlRendererPrivate::target_width
int target_width
Definition: fl_renderer.cc:58
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
fl_renderer_clear_current
void fl_renderer_clear_current(FlRenderer *self)
Definition: fl_renderer.cc:350
FlRendererPrivate::initialized
gboolean initialized
Definition: fl_renderer.cc:46
fl_renderer_get_proc_address
void * fl_renderer_get_proc_address(FlRenderer *self, const char *name)
Definition: fl_renderer.cc:334
fl_view_private.h
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
fl_renderer_set_engine
void fl_renderer_set_engine(FlRenderer *self, FlEngine *engine)
Definition: fl_renderer.cc:305
fl_framebuffer.h
FlRendererPrivate::blocking_main_thread
bool blocking_main_thread
Definition: fl_renderer.cc:62
G_DEFINE_QUARK
G_DEFINE_QUARK(fl_binary_messenger_codec_error_quark, fl_binary_messenger_codec_error) G_DECLARE_FINAL_TYPE(FlBinaryMessengerImpl
G_DEFINE_TYPE_WITH_PRIVATE
G_DEFINE_TYPE_WITH_PRIVATE(FlTextInputHandler, fl_text_input_handler, G_TYPE_OBJECT) static gboolean finish_method(GObject *object
fl_renderer_class_init
static void fl_renderer_class_init(FlRendererClass *klass)
Definition: fl_renderer.cc:291
fragment_shader_src
static const char * fragment_shader_src
Definition: fl_renderer.cc:27
fl_renderer_collect_backing_store
gboolean fl_renderer_collect_backing_store(FlRenderer *self, const FlutterBackingStore *backing_store)
Definition: fl_renderer.cc:399
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_engine_private.h
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
FlRendererPrivate::framebuffers_by_view_id
GHashTable * framebuffers_by_view_id
Definition: fl_renderer.cc:75
FlRendererPrivate::general_format
GLint general_format
Definition: fl_renderer.cc:52
fl_renderer.h
fl_renderer_make_resource_current
void fl_renderer_make_resource_current(FlRenderer *self)
Definition: fl_renderer.cc:345
fl_view_redraw
void fl_view_redraw(FlView *self)
Definition: fl_view.cc:892
FlRendererPrivate::sized_format
GLint sized_format
Definition: fl_renderer.cc:49
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
fl_renderer_cleanup
void fl_renderer_cleanup(FlRenderer *self)
Definition: fl_renderer.cc:528
get_program_log
static gchar * get_program_log(GLuint program)
Definition: fl_renderer.cc:100
view
FlView * view
Definition: fl_application.cc:35
fl_renderer_add_view
void fl_renderer_add_view(FlRenderer *self, FlutterViewId view_id, FlView *view)
Definition: fl_renderer.cc:314
fl_renderer_make_current
void fl_renderer_make_current(FlRenderer *self)
Definition: fl_renderer.cc:340
fl_engine_get_task_runner
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:1001
fl_renderer_render
void fl_renderer_render(FlRenderer *self, FlutterViewId view_id, int width, int height, const GdkRGBA *background_color)
Definition: fl_renderer.cc:501
FlRendererPrivate::views
GHashTable * views
Definition: fl_renderer.cc:55
fl_renderer_create_backing_store
gboolean fl_renderer_create_backing_store(FlRenderer *self, const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
Definition: fl_renderer.cc:367
FlRendererPrivate::target_height
int target_height
Definition: fl_renderer.cc:59
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
FlRendererPrivate::had_first_frame
bool had_first_frame
Definition: fl_renderer.cc:66
fl_renderer_get_fbo
guint32 fl_renderer_get_fbo(FlRenderer *self)
Definition: fl_renderer.cc:360
fl_task_runner_block_main_thread
void fl_task_runner_block_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:176
FlRendererPrivate::program
GLuint program
Definition: fl_renderer.cc:72
fl_framebuffer_get_id
GLuint fl_framebuffer_get_id(FlFramebuffer *self)
Definition: fl_framebuffer.cc:69
fl_renderer_setup
void fl_renderer_setup(FlRenderer *self)
Definition: fl_renderer.cc:484