v2:
Fixed the wrong comparison

v1:
Depending on specific DRI driver implementation, glTexImage2D() with data
set to NULL may or may not re-allocate the texture buffer each time it is
called.  Unintended consequences happen if later glTexSubImage2D() is called
to only update a sub-region of the texture buffer.

I've explored moving glTexImage2D() from gl_renderer_attach() and simply
mark the texture dirty, but the current implemention seems cleaner because
I won't have to worry about calling ensure_textures() and re-assigning
gs->shader unnecessarily.
---
 src/gl-renderer.c |   32 ++++++++++++++++++++------------
 1 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index be74eba..c508825 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -68,6 +68,7 @@ struct gl_surface_state {
 
        struct weston_buffer_reference buffer_ref;
        int pitch; /* in pixels */
+       int height;
 };
 
 struct gl_renderer {
@@ -1213,18 +1214,24 @@ gl_renderer_attach(struct weston_surface *es, struct 
wl_buffer *buffer)
        }
 
        if (wl_buffer_is_shm(buffer)) {
-               gs->pitch = wl_shm_buffer_get_stride(buffer) / 4;
-               gs->target = GL_TEXTURE_2D;
-
-               ensure_textures(gs, 1);
-               glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
-               glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
-                            gs->pitch, buffer->height, 0,
-                            GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
-               if (wl_shm_buffer_get_format(buffer) == WL_SHM_FORMAT_XRGB8888)
-                       gs->shader = &gr->texture_shader_rgbx;
-               else
-                       gs->shader = &gr->texture_shader_rgba;
+               /* Only allocate a texture if it doesn't match existing one */
+               if (((wl_shm_buffer_get_stride(buffer) / 4) != gs->pitch) ||
+                   (buffer->height != gs->height)) {
+                       gs->pitch = wl_shm_buffer_get_stride(buffer) / 4;
+                       gs->height = buffer->height;
+                       gs->target = GL_TEXTURE_2D;
+
+                       ensure_textures(gs, 1);
+                       glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
+                       glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+                                    gs->pitch, buffer->height, 0,
+                                    GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
+                       if (wl_shm_buffer_get_format(buffer) ==
+                           WL_SHM_FORMAT_XRGB8888)
+                               gs->shader = &gr->texture_shader_rgbx;
+                       else
+                               gs->shader = &gr->texture_shader_rgba;
+               }
        } else if (gr->query_buffer(gr->egl_display, buffer,
                                    EGL_TEXTURE_FORMAT, &format)) {
                for (i = 0; i < gs->num_images; i++)
@@ -1279,6 +1286,7 @@ gl_renderer_attach(struct weston_surface *es, struct 
wl_buffer *buffer)
                }
 
                gs->pitch = buffer->width;
+               gs->height = buffer->height;
        } else {
                weston_log("unhandled buffer type!\n");
                weston_buffer_reference(&gs->buffer_ref, NULL);
-- 
1.7.7.6

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to