gles2: update texture only if needed

When a surface is on a non-primary plane (overlay), we do not need to
keep the GL texture up-to-date, since we are not using it. Avoid calling
glTex(Sub)Image2D in that case, and accumulate the texture damage
separately.

This is especially useful for backends, that can put wl_shm buffers into
overlays.

The empty damage check has to be moved from surface_accumulate_damage()
into gles2_renderer_flush_damage(), because it really needs to check the
accumulated damage, not only the current damage. Otherwise, if a surface
migrates from a plane to the primary plane, and does not have new
damage, the texture would not be updated even for accumulated damage.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Pekka Paalanen 12 years ago committed by Kristian Høgsberg
parent a51e6fa322
commit bcdd579a58
  1. 5
      src/compositor.c
  2. 1
      src/compositor.h
  3. 20
      src/gles2-renderer.c

@ -239,6 +239,7 @@ weston_surface_create(struct weston_compositor *compositor)
surface->num_textures = 0; surface->num_textures = 0;
surface->num_images = 0; surface->num_images = 0;
pixman_region32_init(&surface->texture_damage);
surface->buffer = NULL; surface->buffer = NULL;
surface->output = NULL; surface->output = NULL;
@ -782,6 +783,7 @@ destroy_surface(struct wl_resource *resource)
if (surface->buffer) if (surface->buffer)
wl_list_remove(&surface->buffer_destroy_listener.link); wl_list_remove(&surface->buffer_destroy_listener.link);
pixman_region32_fini(&surface->texture_damage);
compositor->renderer->destroy_surface(surface); compositor->renderer->destroy_surface(surface);
pixman_region32_fini(&surface->transform.boundingbox); pixman_region32_fini(&surface->transform.boundingbox);
@ -905,8 +907,7 @@ static void
surface_accumulate_damage(struct weston_surface *surface, surface_accumulate_damage(struct weston_surface *surface,
pixman_region32_t *opaque) pixman_region32_t *opaque)
{ {
if (pixman_region32_not_empty(&surface->damage) && if (surface->buffer && wl_buffer_is_shm(surface->buffer))
surface->buffer && wl_buffer_is_shm(surface->buffer))
surface->compositor->renderer->flush_damage(surface); surface->compositor->renderer->flush_damage(surface);
if (surface->transform.enabled) { if (surface->transform.enabled) {

@ -410,6 +410,7 @@ struct weston_surface {
struct weston_compositor *compositor; struct weston_compositor *compositor;
GLuint textures[3]; GLuint textures[3];
int num_textures; int num_textures;
pixman_region32_t texture_damage;
pixman_region32_t clip; pixman_region32_t clip;
pixman_region32_t damage; pixman_region32_t damage;
pixman_region32_t opaque; pixman_region32_t opaque;

@ -775,6 +775,18 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
int i, n; int i, n;
#endif #endif
pixman_region32_union(&surface->texture_damage,
&surface->texture_damage, &surface->damage);
/* Avoid upload, if the texture won't be used this time.
* We still accumulate the damage in texture_damage.
*/
if (surface->plane != &surface->compositor->primary_plane)
return;
if (!pixman_region32_not_empty(&surface->texture_damage))
return;
glBindTexture(GL_TEXTURE_2D, surface->textures[0]); glBindTexture(GL_TEXTURE_2D, surface->textures[0]);
if (!surface->compositor->has_unpack_subimage) { if (!surface->compositor->has_unpack_subimage) {
@ -783,14 +795,14 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
wl_shm_buffer_get_data(surface->buffer)); wl_shm_buffer_get_data(surface->buffer));
return; goto done;
} }
#ifdef GL_UNPACK_ROW_LENGTH #ifdef GL_UNPACK_ROW_LENGTH
/* Mesa does not define GL_EXT_unpack_subimage */ /* Mesa does not define GL_EXT_unpack_subimage */
glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch); glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch);
data = wl_shm_buffer_get_data(surface->buffer); data = wl_shm_buffer_get_data(surface->buffer);
rectangles = pixman_region32_rectangles(&surface->damage, &n); rectangles = pixman_region32_rectangles(&surface->texture_damage, &n);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rectangles[i].x1); glPixelStorei(GL_UNPACK_SKIP_PIXELS, rectangles[i].x1);
glPixelStorei(GL_UNPACK_SKIP_ROWS, rectangles[i].y1); glPixelStorei(GL_UNPACK_SKIP_ROWS, rectangles[i].y1);
@ -801,6 +813,10 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
GL_BGRA_EXT, GL_UNSIGNED_BYTE, data); GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
} }
#endif #endif
done:
pixman_region32_fini(&surface->texture_damage);
pixman_region32_init(&surface->texture_damage);
} }
static void static void

Loading…
Cancel
Save