diff options
author | Sinclair Yeh <sinclair.yeh@intel.com> | 2013-06-06 16:41:30 -0700 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-06-07 01:46:10 -0400 |
commit | 747d4ee17e573766a0b46b60db9b2477b9286d27 (patch) | |
tree | b047aa097f53ca7f775a7429cd835d8eb402dd58 | |
parent | 7583aff275ccbe0c4d6bb37ec9343773d119e18a (diff) |
Avoid unnecessarily re-allocating texture buffer when the size hasn't changed.
v4:
Incorporated krh and anderco's comments. Now adding newly allocated
buffer's dimensions to texture_damage
v3:
* Removed unnecessary parentheses
* Added check for switching from EGL image to SHM buffer
* Moved shader assignment out of IF condition
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.
-rw-r--r-- | src/gl-renderer.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/src/gl-renderer.c b/src/gl-renderer.c index ea6631f1..f6c71948 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -66,6 +66,7 @@ struct gl_surface_state { int num_images; struct weston_buffer_reference buffer_ref; + int height; int pitch; /* in pixels */ }; @@ -1192,14 +1193,28 @@ 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; + /* Only allocate a texture if it doesn't match existing one. + * If gs->num_images is not 0, then a switch from DRM allocated + * buffer to a SHM buffer is happening, and we need to allocate + * a new texture buffer. */ + if (wl_shm_buffer_get_stride(buffer) / 4 != gs->pitch || + wl_shm_buffer_get_height(buffer) != gs->height || + gs->num_images > 0) { + gs->pitch = wl_shm_buffer_get_stride(buffer) / 4; + gs->height = wl_shm_buffer_get_height(buffer); + 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); + pixman_region32_union_rect(&gs->texture_damage, + &gs->texture_damage, + 0, 0, + gs->pitch, gs->height); + } - 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 @@ -1258,6 +1273,7 @@ gl_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer) } gs->pitch = buffer->width; + gs->height = wl_shm_buffer_get_height(buffer); } else { weston_log("unhandled buffer type!\n"); weston_buffer_reference(&gs->buffer_ref, NULL); |