From c01e37a9a5db5957d08fcb4b8f11ea86c344f6d1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 22 Nov 2014 10:17:22 -0800 Subject: gdkgl: Texture quads in one giant draw call This requires us to use GL_TRIANGLES and six verts per quad instead of four, which makes me think it might not be worth it on well-optimized GL drivers. However, from talking to some driver developers about it, the GL_TRIANGLES should be faster, since this means that there's one giant contiguous buffer instead of many small buffers. If we were really rendering a lot of quads, I'd use an element buffer and GL_PRIMITIVE_RESTART, but we're really not ever rendering that many quads, and the setup cost for that would just be too annoying. --- gdk/gdkgl.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'gdk') diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c index b9563a66a3..73888a2ee2 100644 --- a/gdk/gdkgl.c +++ b/gdk/gdkgl.c @@ -24,6 +24,7 @@ #include #include +#include static cairo_user_data_key_t direct_key; @@ -217,6 +218,7 @@ gdk_gl_texture_quads (GdkGLContext *paint_context, float w = gdk_window_get_width (window) * window_scale; float h = gdk_window_get_height (window) * window_scale; int i; + float *vertex_buffer_data; bind_vao (paint_data); @@ -240,20 +242,36 @@ gdk_gl_texture_quads (GdkGLContext *paint_context, glVertexAttribPointer (program->position_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL); glVertexAttribPointer (program->uv_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL + sizeof(float) * 2); +#define VERTEX_SIZE 4 + +#define QUAD_N_VERTICES 6 + +#define QUAD_SIZE (VERTEX_SIZE * QUAD_N_VERTICES) + + vertex_buffer_data = g_new (float, n_quads * QUAD_SIZE); + for (i = 0; i < n_quads; i++) { GdkTexturedQuad *quad = &quads[i]; - float vertex_buffer_data[] = { + float vertex_data[] = { + (quad->x1 * 2) / w - 1, (quad->y1 * 2) / h - 1, quad->u1, quad->v1, + (quad->x1 * 2) / w - 1, (quad->y2 * 2) / h - 1, quad->u1, quad->v2, (quad->x2 * 2) / w - 1, (quad->y1 * 2) / h - 1, quad->u2, quad->v1, + (quad->x2 * 2) / w - 1, (quad->y2 * 2) / h - 1, quad->u2, quad->v2, (quad->x1 * 2) / w - 1, (quad->y2 * 2) / h - 1, quad->u1, quad->v2, - (quad->x1 * 2) / w - 1, (quad->y1 * 2) / h - 1, quad->u1, quad->v1, + (quad->x2 * 2) / w - 1, (quad->y1 * 2) / h - 1, quad->u2, quad->v1, }; - glBufferData (GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STREAM_DRAW); - glDrawArrays (GL_TRIANGLE_FAN, 0, 4); + float *vertex = &vertex_buffer_data[i * QUAD_SIZE]; + memcpy (vertex, vertex_data, sizeof(vertex_data)); } + glBufferData (GL_ARRAY_BUFFER, sizeof(float) * n_quads * QUAD_SIZE, vertex_buffer_data, GL_STREAM_DRAW); + glDrawArrays (GL_TRIANGLES, 0, n_quads * QUAD_N_VERTICES); + + g_free (vertex_buffer_data); + glDisableVertexAttribArray (0); glDisableVertexAttribArray (1); } -- cgit v1.2.1