[PATCH] Avoid unnecessarily re-allocating texture buffer when the size hasn't changed.
Pekka Paalanen
ppaalanen at gmail.com
Fri May 24 03:19:59 PDT 2013
On Thu, 23 May 2013 13:18:29 -0700
Sinclair Yeh <sinclair.yeh at intel.com> wrote:
> 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);
Seems fine to me.
Thanks,
pq
More information about the wayland-devel
mailing list