On Wed, Nov 07, 2012 at 12:25:13PM +0200, Pekka Paalanen wrote:
> 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.

Yeah, that looks good.  The texture_damage region would be part of a
gles2 surface data if we had that, but for now it's fine to have it in
weston_surface.

Kristian

> 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