| 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"
11 #include "flutter/shell/platform/linux/fl_engine_private.h"
12 #include "flutter/shell/platform/linux/fl_framebuffer.h"
13 #include "flutter/shell/platform/linux/fl_view_private.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.
52 GLint general_format;
53
54 // Views being rendered.
55 GHashTable* views;
56
57 // target dimension for resizing
58 int target_width;
59 int target_height;
60
61 // whether the renderer waits for frame render
62 bool blocking_main_thread;
63
64 // true if frame was completed; resizing is not synchronized until first frame
65 // was rendered
66 bool had_first_frame;
67
68 // True if we can use glBlitFramebuffer.
69 bool has_gl_framebuffer_blit;
70
71 // Shader program.
72 GLuint program;
73
74 // Framebuffers to render keyed by view ID.
75 GHashTable* framebuffers_by_view_id;
76 } FlRendererPrivate;
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) {
144 fl_task_runner_release_main_thread(fl_engine_get_task_runner(engine));
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
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 }
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
367 gboolean fl_renderer_create_backing_store(
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
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 }
398
399 gboolean fl_renderer_collect_backing_store(
400 FlRenderer* self,
401 const FlutterBackingStore* backing_store) {
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 }
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) {
424 fl_task_runner_block_main_thread(fl_engine_get_task_runner(engine));
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
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 }
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