[Spice-devel] [spice-gtk PATCH egl] egl: Fix usage of Vertex Array Object

Lukas Venhoda lvenhoda at redhat.com
Mon Jul 18 16:41:45 UTC 2016


VAO shouldn't be bound indefinitely.

Move glEnableVertexAttribArray and glVertexAttribPointer to init.
These settings and currently bound Vertex Buffer Object will be saved to VAO.
Unbinding VAO will set these to default (unbinding them).

Instead of calling these settings every frame, bind VAO before draw call,
and unbind it afterwards.

Setting VertexAttribPointer only once could be much faster in some situations,
where the display driver might try to optimize the binding.
With VAO these optimalisations are saved and reused.
---
 src/spice-widget-egl.c  | 28 ++++++++++++++--------------
 src/spice-widget-priv.h |  1 +
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 0698af3..0d7eb6c 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -147,9 +147,9 @@ static gboolean spice_egl_init_shaders(SpiceDisplay *display, GError **err)
 
     glUniform1i(tex_loc, 0);
 
-    /* we only use one VAO, so we always keep it bound */
     glGenVertexArrays(1, &buf);
     glBindVertexArray(buf);
+    d->egl.vao_id = buf;
 
     glGenBuffers(1, &buf);
     glBindBuffer(GL_ARRAY_BUFFER, buf);
@@ -162,6 +162,17 @@ static gboolean spice_egl_init_shaders(SpiceDisplay *display, GError **err)
     glGenTextures(1, &d->egl.tex_id);
     glGenTextures(1, &d->egl.tex_pointer_id);
 
+    glEnableVertexAttribArray(d->egl.attr_pos);
+    glVertexAttribPointer(d->egl.attr_pos, 4, GL_FLOAT,
+                          GL_FALSE, 0, 0);
+        
+    glEnableVertexAttribArray(d->egl.attr_tex);
+    glVertexAttribPointer(d->egl.attr_tex, 2, GL_FLOAT,
+                          GL_FALSE, 0,
+                          (void *)VERTS_ARRAY_SIZE);
+
+    glBindVertexArray(0);
+
     success = TRUE;
 
 end:
@@ -445,35 +456,24 @@ draw_rect_from_arrays(SpiceDisplay *display, const void *verts, const void *tex)
 {
     SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
 
-    glBindBuffer(GL_ARRAY_BUFFER, d->egl.vbuf_id);
+    glBindVertexArray(d->egl.vao_id);
 
     if (verts) {
-        glEnableVertexAttribArray(d->egl.attr_pos);
         glBufferSubData(GL_ARRAY_BUFFER,
                         0,
                         VERTS_ARRAY_SIZE,
                         verts);
-        glVertexAttribPointer(d->egl.attr_pos, 4, GL_FLOAT,
-                              GL_FALSE, 0, 0);
     }
     if (tex) {
-        glEnableVertexAttribArray(d->egl.attr_tex);
         glBufferSubData(GL_ARRAY_BUFFER,
                         VERTS_ARRAY_SIZE,
                         TEX_ARRAY_SIZE,
                         tex);
-        glVertexAttribPointer(d->egl.attr_tex, 2, GL_FLOAT,
-                              GL_FALSE, 0,
-                              (void *)VERTS_ARRAY_SIZE);
     }
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    if (verts)
-        glDisableVertexAttribArray(d->egl.attr_pos);
-    if (tex)
-        glDisableVertexAttribArray(d->egl.attr_tex);
 
-    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindVertexArray(0);
 }
 
 static GLvoid
diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index e36baf3..641e78e 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -136,6 +136,7 @@ struct _SpiceDisplayPrivate {
         EGLConfig           conf;
         EGLContext          ctx;
         gint                mproj, attr_pos, attr_tex;
+        guint               vao_id;
         guint               vbuf_id;
         guint               tex_id;
         guint               tex_pointer_id;
-- 
2.7.4



More information about the Spice-devel mailing list