Skip to content

Commit f30c56f

Browse files
robert-ancellmboetger
authored andcommitted
Use a shared vertex buffer for rendering layers. (flutter#170717)
Only generate the vertex buffer once, and use uniforms to translate and scale it in the vertex shader. We still need to generate the vertex for each view, which seems unnecessary but it cannot be shared across contexts in OpenGL. This should be tackled in a future change.
1 parent 66cbe38 commit f30c56f

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

engine/src/flutter/shell/platform/linux/fl_compositor_opengl.cc

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
static const char* vertex_shader_src =
1717
"attribute vec2 position;\n"
1818
"attribute vec2 in_texcoord;\n"
19+
"uniform vec2 offset;\n"
20+
"uniform vec2 scale;\n"
1921
"varying vec2 texcoord;\n"
2022
"\n"
2123
"void main() {\n"
22-
" gl_Position = vec4(position, 0, 1);\n"
24+
" gl_Position = vec4(offset + position * scale, 0, 1);\n"
2325
" texcoord = in_texcoord;\n"
2426
"}\n";
2527

@@ -71,6 +73,15 @@ struct _FlCompositorOpenGL {
7173
// Shader program.
7274
GLuint program;
7375

76+
// Location of layer offset in [program].
77+
GLuint offset_location;
78+
79+
// Location of layer scale in [program].
80+
GLuint scale_location;
81+
82+
// Verticies for the uniform square.
83+
GLuint vertex_buffer;
84+
7485
// Framebuffers to render keyed by view ID.
7586
GHashTable* framebuffers_by_view_id;
7687

@@ -135,11 +146,6 @@ static gchar* get_program_log(GLuint program) {
135146
return log;
136147
}
137148

138-
/// Converts a pixel co-ordinate from 0..pixels to OpenGL -1..1.
139-
static GLfloat pixels_to_gl_coords(GLfloat position, GLfloat pixels) {
140-
return (2.0 * position / pixels) - 1.0;
141-
}
142-
143149
// Perform single run OpenGL initialization.
144150
static void initialize(FlCompositorOpenGL* self) {
145151
if (self->initialized) {
@@ -200,8 +206,23 @@ static void setup_shader(FlCompositorOpenGL* self) {
200206
g_warning("Failed to link program: %s", program_log);
201207
}
202208

209+
self->offset_location = glGetUniformLocation(self->program, "offset");
210+
self->scale_location = glGetUniformLocation(self->program, "scale");
211+
203212
glDeleteShader(vertex_shader);
204213
glDeleteShader(fragment_shader);
214+
215+
// The uniform square abcd in two triangles cba + cdb
216+
// a--b
217+
// | |
218+
// c--d
219+
GLfloat vertex_data[] = {-1, -1, 0, 0, 1, 1, 1, 1, -1, 1, 0, 1,
220+
-1, -1, 0, 0, 1, -1, 1, 0, 1, 1, 1, 1};
221+
222+
glGenBuffers(1, &self->vertex_buffer);
223+
glBindBuffer(GL_ARRAY_BUFFER, self->vertex_buffer);
224+
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
225+
GL_STATIC_DRAW);
205226
}
206227

207228
static void render_with_blit(FlCompositorOpenGL* self,
@@ -239,6 +260,22 @@ static void render_with_textures(FlCompositorOpenGL* self,
239260
GLint saved_array_buffer_binding;
240261
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
241262

263+
// FIXME(robert-ancell): The vertex array is the same for all views, but
264+
// cannot be shared in OpenGL. Find a way to not generate this every time.
265+
GLuint vao;
266+
glGenVertexArrays(1, &vao);
267+
glBindVertexArray(vao);
268+
glBindBuffer(GL_ARRAY_BUFFER, self->vertex_buffer);
269+
GLint position_location = glGetAttribLocation(self->program, "position");
270+
glEnableVertexAttribArray(position_location);
271+
glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE,
272+
sizeof(GLfloat) * 4, 0);
273+
GLint texcoord_location = glGetAttribLocation(self->program, "in_texcoord");
274+
glEnableVertexAttribArray(texcoord_location);
275+
glVertexAttribPointer(texcoord_location, 2, GL_FLOAT, GL_FALSE,
276+
sizeof(GLfloat) * 4,
277+
reinterpret_cast<void*>(sizeof(GLfloat) * 2));
278+
242279
glEnable(GL_BLEND);
243280
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
244281

@@ -248,42 +285,22 @@ static void render_with_textures(FlCompositorOpenGL* self,
248285
FlFramebuffer* framebuffer =
249286
FL_FRAMEBUFFER(g_ptr_array_index(framebuffers, i));
250287

251-
GLuint texture_id = fl_framebuffer_get_texture_id(framebuffer);
252-
glBindTexture(GL_TEXTURE_2D, texture_id);
253-
254-
// Translate into OpenGL co-ordinates
288+
// FIXME(robert-ancell): The offset from present_layers() is not here, needs
289+
// to be updated.
255290
size_t texture_width = fl_framebuffer_get_width(framebuffer);
256291
size_t texture_height = fl_framebuffer_get_height(framebuffer);
257-
GLfloat x0 = pixels_to_gl_coords(0, width);
258-
GLfloat y0 = pixels_to_gl_coords(height - texture_height, height);
259-
GLfloat x1 = pixels_to_gl_coords(texture_width, width);
260-
GLfloat y1 = pixels_to_gl_coords(height, height);
261-
GLfloat vertex_data[] = {x0, y0, 0, 0, x1, y1, 1, 1, x0, y1, 0, 1,
262-
x0, y0, 0, 0, x1, y0, 1, 0, x1, y1, 1, 1};
263-
264-
GLuint vao, vertex_buffer;
265-
glGenVertexArrays(1, &vao);
266-
glBindVertexArray(vao);
267-
glGenBuffers(1, &vertex_buffer);
268-
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
269-
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
270-
GL_STATIC_DRAW);
271-
GLint position_index = glGetAttribLocation(self->program, "position");
272-
glEnableVertexAttribArray(position_index);
273-
glVertexAttribPointer(position_index, 2, GL_FLOAT, GL_FALSE,
274-
sizeof(GLfloat) * 4, 0);
275-
GLint texcoord_index = glGetAttribLocation(self->program, "in_texcoord");
276-
glEnableVertexAttribArray(texcoord_index);
277-
glVertexAttribPointer(texcoord_index, 2, GL_FLOAT, GL_FALSE,
278-
sizeof(GLfloat) * 4,
279-
reinterpret_cast<void*>(sizeof(GLfloat) * 2));
292+
glUniform2f(self->offset_location, 0, 0);
293+
glUniform2f(self->scale_location, texture_width / width,
294+
texture_height / height);
280295

281-
glDrawArrays(GL_TRIANGLES, 0, 6);
296+
GLuint texture_id = fl_framebuffer_get_texture_id(framebuffer);
297+
glBindTexture(GL_TEXTURE_2D, texture_id);
282298

283-
glDeleteVertexArrays(1, &vao);
284-
glDeleteBuffers(1, &vertex_buffer);
299+
glDrawArrays(GL_TRIANGLES, 0, 6);
285300
}
286301

302+
glDeleteVertexArrays(1, &vao);
303+
287304
glDisable(GL_BLEND);
288305

289306
glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
@@ -638,4 +655,7 @@ void fl_compositor_opengl_cleanup(FlCompositorOpenGL* self) {
638655
if (self->program != 0) {
639656
glDeleteProgram(self->program);
640657
}
658+
if (self->vertex_buffer != 0) {
659+
glDeleteBuffers(1, &self->vertex_buffer);
660+
}
641661
}

0 commit comments

Comments
 (0)