[PATCH 5/7] glamor: Provide a fallback path for using an index buffer to do quads.

Eric Anholt eric at anholt.net
Fri Jun 19 19:09:39 PDT 2015


Improves x11perf -aa10text performance by 1377.59% +/- 23.8198% (n=93)
on Intel with GLES2.

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 glamor/glamor.c       | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
 glamor/glamor_priv.h  | 11 +++++++++
 glamor/glamor_utils.h |  4 +---
 3 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 935fb74..fbb1d85 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -274,6 +274,68 @@ glamor_set_debug_level(int *debug_level)
 
 int glamor_debug_level;
 
+void
+glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
+                                        unsigned count)
+{
+    unsigned i;
+
+    /* For a single quad, don't bother with an index buffer. */
+    if (count ==  1)
+        goto fallback;
+
+    if (glamor_priv->ib_size < count) {
+        /* Basic GLES2 doesn't have any way to map buffer objects for
+         * writing, but it's long past time for drivers to have
+         * MapBufferRange.
+         */
+        if (!glamor_priv->has_map_buffer_range)
+            goto fallback;
+
+        /* Lazy create the buffer name, and only bind it once since
+         * none of the glamor code binds it to anything else.
+         */
+        if (!glamor_priv->ib) {
+            glGenBuffers(1, &glamor_priv->ib);
+            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ib);
+        }
+
+        /* For now, only support GL_UNSIGNED_SHORTs. */
+        if (count > ((1 << 16) - 1) / 4) {
+            goto fallback;
+        } else {
+            uint16_t *data;
+            size_t size = count * 6 * sizeof(GLushort);
+
+            glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
+            data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER,
+                                    0, size,
+                                    GL_MAP_WRITE_BIT |
+                                    GL_MAP_INVALIDATE_BUFFER_BIT);
+            for (i = 0; i < count; i++) {
+                data[i * 6 + 0] = i * 4 + 0;
+                data[i * 6 + 1] = i * 4 + 1;
+                data[i * 6 + 2] = i * 4 + 2;
+                data[i * 6 + 3] = i * 4 + 0;
+                data[i * 6 + 4] = i * 4 + 2;
+                data[i * 6 + 5] = i * 4 + 3;
+            }
+            glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+            glamor_priv->ib_size = count;
+            glamor_priv->ib_type = GL_UNSIGNED_SHORT;
+        }
+    }
+
+    glDrawElements(GL_TRIANGLES, count * 6, glamor_priv->ib_type, NULL);
+    return;
+
+fallback:
+    for (i = 0; i < count; i++)
+        glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
+}
+
+
 /**
  * Creates any pixmaps used internally by glamor, since those can't be
  * allocated at ScreenInit time.
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c80df22..17f8253 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -261,6 +261,14 @@ typedef struct glamor_screen_private {
      */
     char *vb;
     int vb_stride;
+
+    /** Cached index buffer for translating GL_QUADS to triangles. */
+    GLuint ib;
+    /** Index buffer type: GL_UNSIGNED_SHORT or GL_UNSIGNED_INT */
+    GLenum ib_type;
+    /** Number of quads the index buffer has indices for. */
+    unsigned ib_size;
+
     Bool has_source_coords, has_mask_coords;
     int render_nr_quads;
     glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
@@ -643,6 +651,9 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
                                            int flag, int block_w, int block_h,
                                            glamor_pixmap_private *);
 
+void glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
+                                             unsigned count);
+
 /* glamor_core.c */
 void glamor_init_finish_access_shaders(ScreenPtr screen);
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 0927ffb..73cda9c 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1403,9 +1403,7 @@ glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
         glDrawArrays(GL_QUADS, 0, count * 4);
     } else {
-        unsigned i;
-        for (i = 0; i < count; i++)
-            glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
+        glamor_gldrawarrays_quads_using_indices(glamor_priv, count);
     }
 }
 
-- 
2.1.4



More information about the xorg-devel mailing list