summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSinclair Yeh <sinclair.yeh@intel.com>2013-06-06 16:41:30 -0700
committerKristian Høgsberg <krh@bitplanet.net>2013-06-07 01:46:10 -0400
commit747d4ee17e573766a0b46b60db9b2477b9286d27 (patch)
treeb047aa097f53ca7f775a7429cd835d8eb402dd58
parent7583aff275ccbe0c4d6bb37ec9343773d119e18a (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.c30
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);