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 <[email protected]>
---
 src/compositor.c     |    5 +++--
 src/compositor.h     |    1 +
 src/gles2-renderer.c |   20 ++++++++++++++++++--
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 71006f9..ce113b6 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -239,6 +239,7 @@ weston_surface_create(struct weston_compositor *compositor)
 
        surface->num_textures = 0;
        surface->num_images = 0;
+       pixman_region32_init(&surface->texture_damage);
 
        surface->buffer = NULL;
        surface->output = NULL;
@@ -782,6 +783,7 @@ destroy_surface(struct wl_resource *resource)
        if (surface->buffer)
                wl_list_remove(&surface->buffer_destroy_listener.link);
 
+       pixman_region32_fini(&surface->texture_damage);
        compositor->renderer->destroy_surface(surface);
 
        pixman_region32_fini(&surface->transform.boundingbox);
@@ -905,8 +907,7 @@ static void
 surface_accumulate_damage(struct weston_surface *surface,
                          pixman_region32_t *opaque)
 {
-       if (pixman_region32_not_empty(&surface->damage) &&
-           surface->buffer && wl_buffer_is_shm(surface->buffer))
+       if (surface->buffer && wl_buffer_is_shm(surface->buffer))
                surface->compositor->renderer->flush_damage(surface);
 
        if (surface->transform.enabled) {
diff --git a/src/compositor.h b/src/compositor.h
index 121f6bf..f69cede 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -407,6 +407,7 @@ struct weston_surface {
        struct weston_compositor *compositor;
        GLuint textures[3];
        int num_textures;
+       pixman_region32_t texture_damage;
        pixman_region32_t clip;
        pixman_region32_t damage;
        pixman_region32_t opaque;
diff --git a/src/gles2-renderer.c b/src/gles2-renderer.c
index 544cc15..8fd0c09 100644
--- a/src/gles2-renderer.c
+++ b/src/gles2-renderer.c
@@ -769,6 +769,18 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
        int i, n;
 #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]);
 
        if (!surface->compositor->has_unpack_subimage) {
@@ -777,14 +789,14 @@ gles2_renderer_flush_damage(struct weston_surface 
*surface)
                             GL_BGRA_EXT, GL_UNSIGNED_BYTE,
                             wl_shm_buffer_get_data(surface->buffer));
 
-               return;
+               goto done;
        }
 
 #ifdef GL_UNPACK_ROW_LENGTH
        /* Mesa does not define GL_EXT_unpack_subimage */
        glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch);
        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++) {
                glPixelStorei(GL_UNPACK_SKIP_PIXELS, rectangles[i].x1);
                glPixelStorei(GL_UNPACK_SKIP_ROWS, rectangles[i].y1);
@@ -795,6 +807,10 @@ gles2_renderer_flush_damage(struct weston_surface *surface)
                                GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
        }
 #endif
+
+done:
+       pixman_region32_fini(&surface->texture_damage);
+       pixman_region32_init(&surface->texture_damage);
 }
 
 static void
-- 
1.7.8.6

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to