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.
This commit is contained in:
26
gdk/gdkgl.c
26
gdk/gdkgl.c
@ -24,6 +24,7 @@
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user