[gtk+] gdkgl: Texture quads in one giant draw call



commit c01e37a9a5db5957d08fcb4b8f11ea86c344f6d1
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sat Nov 22 10:17:22 2014 -0800

    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 files changed, 22 insertions(+), 4 deletions(-)
---
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c
index b9563a6..73888a2 100644
--- a/gdk/gdkgl.c
+++ b/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);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]