10 #include "flutter/shell/platform/embedder/embedder.h"
17 "attribute vec2 position;\n"
18 "attribute vec2 in_texcoord;\n"
19 "varying vec2 texcoord;\n"
22 " gl_Position = vec4(position, 0, 1);\n"
23 " texcoord = in_texcoord;\n"
28 "uniform sampler2D texture;\n"
29 "varying vec2 texcoord;\n"
32 " gl_FragColor = texture2D(texture, texcoord);\n"
65 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
67 log =
static_cast<gchar*
>(g_malloc(log_length + 1));
68 glGetShaderInfoLog(shader, log_length,
nullptr, log);
78 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
80 log =
static_cast<gchar*
>(g_malloc(log_length + 1));
81 glGetProgramInfoLog(program, log_length,
nullptr, log);
88 return (2.0 * position / pixels) - 1.0;
93 fl_renderer_get_instance_private(
self));
94 if (
priv->blocking_main_thread) {
95 priv->blocking_main_thread =
false;
97 FlTaskRunner* runner =
104 FlRenderer*
self = FL_RENDERER(
object);
106 fl_renderer_get_instance_private(
self));
110 g_clear_pointer(&
priv->textures, g_ptr_array_unref);
112 G_OBJECT_CLASS(fl_renderer_parent_class)->dispose(
object);
121 fl_renderer_get_instance_private(
self));
122 priv->textures = g_ptr_array_new_with_free_func(g_object_unref);
127 fl_renderer_get_instance_private(
self));
129 g_return_val_if_fail(FL_IS_RENDERER(
self), FALSE);
136 g_return_val_if_fail(FL_IS_RENDERER(
self), NULL);
138 return reinterpret_cast<void*
>(eglGetProcAddress(name));
142 g_return_if_fail(FL_IS_RENDERER(
self));
143 FL_RENDERER_GET_CLASS(
self)->make_current(
self);
147 g_return_if_fail(FL_IS_RENDERER(
self));
148 FL_RENDERER_GET_CLASS(
self)->make_resource_current(
self);
152 g_return_if_fail(FL_IS_RENDERER(
self));
153 FL_RENDERER_GET_CLASS(
self)->clear_current(
self);
157 g_return_val_if_fail(FL_IS_RENDERER(
self), -1.0);
158 return FL_RENDERER_GET_CLASS(
self)->get_refresh_rate(
self);
162 g_return_val_if_fail(FL_IS_RENDERER(
self), 0);
169 FlRenderer* renderer,
170 const FlutterBackingStoreConfig* config,
171 FlutterBackingStore* backing_store_out) {
174 FlBackingStoreProvider* provider =
177 g_warning(
"Failed to create backing store");
184 backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
185 backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
186 backing_store_out->open_gl.framebuffer.user_data = provider;
187 backing_store_out->open_gl.framebuffer.name = name;
188 backing_store_out->open_gl.framebuffer.target =
format;
189 backing_store_out->open_gl.framebuffer.destruction_callback = [](
void* p) {
199 const FlutterBackingStore* backing_store) {
203 g_object_unref(backing_store->open_gl.framebuffer.user_data);
211 fl_renderer_get_instance_private(
self));
213 g_return_if_fail(FL_IS_RENDERER(
self));
215 priv->target_width = target_width;
216 priv->target_height = target_height;
218 if (
priv->had_first_frame && !
priv->blocking_main_thread) {
219 priv->blocking_main_thread =
true;
220 FlTaskRunner* runner =
227 const FlutterLayer** layers,
228 size_t layers_count) {
230 fl_renderer_get_instance_private(
self));
232 g_return_val_if_fail(FL_IS_RENDERER(
self), FALSE);
236 if (
priv->blocking_main_thread && layers_count == 1 &&
237 layers[0]->offset.x == 0 && layers[0]->offset.y == 0 &&
238 (layers[0]->size.width !=
priv->target_width ||
239 layers[0]->size.height !=
priv->target_height)) {
243 priv->had_first_frame =
true;
251 g_ptr_array_set_size(
priv->textures, 0);
252 for (
size_t i = 0;
i < layers_count; ++
i) {
253 const FlutterLayer* layer = layers[
i];
254 switch (layer->type) {
255 case kFlutterLayerContentTypeBackingStore: {
256 const FlutterBackingStore* backing_store = layer->backing_store;
257 auto framebuffer = &backing_store->open_gl.framebuffer;
258 FlBackingStoreProvider* provider =
259 FL_BACKING_STORE_PROVIDER(framebuffer->user_data);
260 g_ptr_array_add(
priv->textures, g_object_ref(provider));
262 case kFlutterLayerContentTypePlatformView: {
276 fl_renderer_get_instance_private(
self));
278 g_return_if_fail(FL_IS_RENDERER(
self));
280 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
282 glCompileShader(vertex_shader);
283 int vertex_compile_status;
284 glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status);
285 if (vertex_compile_status == GL_FALSE) {
287 g_warning(
"Failed to compile vertex shader: %s", shader_log);
290 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
292 glCompileShader(fragment_shader);
293 int fragment_compile_status;
294 glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status);
295 if (fragment_compile_status == GL_FALSE) {
297 g_warning(
"Failed to compile fragment shader: %s", shader_log);
300 priv->program = glCreateProgram();
301 glAttachShader(
priv->program, vertex_shader);
302 glAttachShader(
priv->program, fragment_shader);
303 glLinkProgram(
priv->program);
306 glGetProgramiv(
priv->program, GL_LINK_STATUS, &link_status);
307 if (link_status == GL_FALSE) {
309 g_warning(
"Failed to link program: %s", program_log);
312 glDeleteShader(vertex_shader);
313 glDeleteShader(fragment_shader);
318 fl_renderer_get_instance_private(
self));
320 g_return_if_fail(FL_IS_RENDERER(
self));
325 GLint saved_texture_binding;
326 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
327 GLint saved_vao_binding;
328 glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &saved_vao_binding);
329 GLint saved_array_buffer_binding;
330 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
332 glClearColor(0.0, 0.0, 0.0, 1.0);
333 glClear(GL_COLOR_BUFFER_BIT);
335 glUseProgram(
priv->program);
337 for (guint
i = 0;
i <
priv->textures->len;
i++) {
338 FlBackingStoreProvider* texture =
339 FL_BACKING_STORE_PROVIDER(g_ptr_array_index(
priv->textures,
i));
345 GdkRectangle texture_geometry =
347 GLfloat texture_x = texture_geometry.x;
348 GLfloat texture_y = texture_geometry.y;
349 GLfloat texture_width = texture_geometry.width;
350 GLfloat texture_height = texture_geometry.height;
356 GLfloat vertex_data[] = {x0, y0, 0, 0, x1, y1, 1, 1, x0, y1, 0, 1,
357 x0, y0, 0, 0, x1, y0, 1, 0, x1, y1, 1, 1};
359 GLuint vao, vertex_buffer;
360 glGenVertexArrays(1, &vao);
361 glBindVertexArray(vao);
362 glGenBuffers(1, &vertex_buffer);
363 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
364 glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_data), vertex_data,
366 GLint position_index = glGetAttribLocation(
priv->program,
"position");
367 glEnableVertexAttribArray(position_index);
368 glVertexAttribPointer(position_index, 2, GL_FLOAT, GL_FALSE,
369 sizeof(GLfloat) * 4, 0);
370 GLint texcoord_index = glGetAttribLocation(
priv->program,
"in_texcoord");
371 glEnableVertexAttribArray(texcoord_index);
372 glVertexAttribPointer(texcoord_index, 2, GL_FLOAT, GL_FALSE,
373 sizeof(GLfloat) * 4, (
void*)(
sizeof(GLfloat) * 2));
375 glDrawArrays(GL_TRIANGLES, 0, 6);
377 glDeleteVertexArrays(1, &vao);
378 glDeleteBuffers(1, &vertex_buffer);
383 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
384 glBindVertexArray(saved_vao_binding);
385 glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding);
390 fl_renderer_get_instance_private(
self));
392 g_return_if_fail(FL_IS_RENDERER(
self));
394 glDeleteProgram(
priv->program);