[PATCH 3/8] glamor: Use vertex arrays

Dave Airlie airlied at gmail.com
Mon Jan 18 16:56:51 PST 2016


From: Keith Packard <keithp at keithp.com>

Core contexts require the use of vertex arrays, so switch both glamor
and ephyr/glamor over.

Signed-off-by: Keith Packard <keithp at keithp.com>
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 glamor/glamor.c                    |  2 +
 glamor/glamor_priv.h               |  2 +
 glamor/glamor_vbo.c                |  9 ++++
 hw/kdrive/ephyr/ephyr_glamor_glx.c | 86 +++++++++++++++++++++++++++-----------
 4 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 523f0cb..8828ad3 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -573,6 +573,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         epoxy_has_gl_extension("GL_NV_pack_subimage");
     glamor_priv->has_dual_blend =
         epoxy_has_gl_extension("GL_ARB_blend_func_extended");
+    glamor_priv->has_vertex_array_object =
+        epoxy_has_gl_extension("GL_ARB_vertex_array_object");
 
     glamor_setup_debug_output(screen);
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6a84548..d26593d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -209,6 +209,7 @@ typedef struct glamor_screen_private {
     Bool has_rw_pbo;
     Bool use_quads;
     Bool has_dual_blend;
+    Bool has_vertex_array_object;
     int max_fbo_size;
 
     struct xorg_list
@@ -255,6 +256,7 @@ typedef struct glamor_screen_private {
     char                        *glyph_defines;
 
     /** Vertex buffer for all GPU rendering. */
+    GLuint vao;
     GLuint vbo;
     /** Next offset within the VBO that glamor_get_vbo_space() will use. */
     int vbo_offset;
diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c
index ba60ce6..b8db009 100644
--- a/glamor/glamor_vbo.c
+++ b/glamor/glamor_vbo.c
@@ -174,6 +174,11 @@ glamor_init_vbo(ScreenPtr screen)
     glamor_make_current(glamor_priv);
 
     glGenBuffers(1, &glamor_priv->vbo);
+    if (glamor_priv->has_vertex_array_object) {
+        glGenVertexArrays(1, &glamor_priv->vao);
+        glBindVertexArray(glamor_priv->vao);
+    } else
+        glamor_priv->vao = 0;
 }
 
 void
@@ -183,6 +188,10 @@ glamor_fini_vbo(ScreenPtr screen)
 
     glamor_make_current(glamor_priv);
 
+    if (glamor_priv->vao != 0) {
+        glDeleteVertexArrays(1, &glamor_priv->vao);
+        glamor_priv->vao = 0;
+    }
     if (!glamor_priv->has_map_buffer_range)
         free(glamor_priv->vb);
 }
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 582e3af..30c5245 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -71,6 +71,8 @@ struct ephyr_glamor {
 
     /* Size of the window that we're rendering to. */
     unsigned width, height;
+
+    GLuint vao, vbo;
 };
 
 static GLint
@@ -189,47 +191,53 @@ ephyr_glamor_set_texture(struct ephyr_glamor *glamor, uint32_t tex)
     glamor->tex = tex;
 }
 
+static void
+ephyr_glamor_set_vertices(struct ephyr_glamor *glamor)
+{
+    glVertexAttribPointer(glamor->texture_shader_position_loc,
+                          2, GL_FLOAT, FALSE, 0, (void *) 0);
+    glVertexAttribPointer(glamor->texture_shader_texcoord_loc,
+                          2, GL_FLOAT, FALSE, 0, (void *) (sizeof (float) * 8));
+
+    glEnableVertexAttribArray(glamor->texture_shader_position_loc);
+    glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+}
+
+static void
+ephyr_glamor_clear_vertices(struct ephyr_glamor *glamor)
+{
+    glDisableVertexAttribArray(glamor->texture_shader_position_loc);
+    glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+}
+
 void
 ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
                               struct pixman_region16 *damage)
 {
-    /* Redraw the whole screen, since glXSwapBuffers leaves the back
-     * buffer undefined.
-     */
-    static const float position[] = {
-        -1, -1,
-         1, -1,
-         1,  1,
-        -1,  1,
-    };
-    static const float texcoords[] = {
-        0, 1,
-        1, 1,
-        1, 0,
-        0, 0,
-    };
+    GLint old_vao;
 
     glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx);
 
+    if (glamor->vao) {
+        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
+        glBindVertexArray(glamor->vao);
+    } else
+        ephyr_glamor_set_vertices(glamor);
+
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     glUseProgram(glamor->texture_shader);
     glViewport(0, 0, glamor->width, glamor->height);
     if (!ephyr_glamor_gles2)
         glDisable(GL_COLOR_LOGIC_OP);
 
-    glVertexAttribPointer(glamor->texture_shader_position_loc,
-                          2, GL_FLOAT, FALSE, 0, position);
-    glVertexAttribPointer(glamor->texture_shader_texcoord_loc,
-                          2, GL_FLOAT, FALSE, 0, texcoords);
-    glEnableVertexAttribArray(glamor->texture_shader_position_loc);
-    glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc);
-
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, glamor->tex);
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-    glDisableVertexAttribArray(glamor->texture_shader_position_loc);
-    glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+    if (glamor->vao)
+        glBindVertexArray(old_vao);
+    else
+        ephyr_glamor_clear_vertices(glamor);
 
     glXSwapBuffers(dpy, glamor->glx_win);
 }
@@ -271,6 +279,18 @@ ephyr_glamor_process_event(xcb_generic_event_t *xev)
 struct ephyr_glamor *
 ephyr_glamor_glx_screen_init(xcb_window_t win)
 {
+    static const float position[] = {
+        -1, -1,
+         1, -1,
+         1,  1,
+        -1,  1,
+        0, 1,
+        1, 1,
+        1, 0,
+        0, 0,
+    };
+    GLint old_vao;
+
     GLXContext ctx;
     struct ephyr_glamor *glamor;
     GLXWindow glx_win;
@@ -312,6 +332,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
     glamor->glx_win = glx_win;
     ephyr_glamor_setup_texturing_shader(glamor);
 
+    if (epoxy_has_gl_extension("GL_ARB_vertex_array_object")) {
+        glGenVertexArrays(1, &glamor->vao);
+        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
+        glBindVertexArray(glamor->vao);
+    } else
+        glamor->vao = 0;
+
+    glGenBuffers(1, &glamor->vbo);
+
+    glBindBuffer(GL_ARRAY_BUFFER, glamor->vbo);
+    glBufferData(GL_ARRAY_BUFFER, sizeof (position), position, GL_STATIC_DRAW);
+
+    if (glamor->vao) {
+        ephyr_glamor_set_vertices(glamor);
+        glBindVertexArray(old_vao);
+    } else
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
     return glamor;
 }
 
-- 
2.4.3



More information about the xorg-devel mailing list