Pushed (though I changed the commit log to have the proper
"damage_buffer" name)

On 26/11/15 02:17 PM, Derek Foreman wrote:
> Add an implementation of wl_surface.buffer_damage, similar to
> wl_surface.damage except it uses buffer co-ordinates.
> 
> Reviewed-by: Pekka Paalanen <[email protected]>
> Signed-off-by: Derek Foreman <[email protected]>
> ---
> 
> Tiny changes since v1:
> rebase on patch to not use MIN() macros
> the width, height test in surface_damage_buffer is now for <= 0
> 
> 
> Oh, and perhaps somewhat important:
> This patch can't land until the wayland protocol it implements is final :)
> 
>  src/compositor.c | 88 
> +++++++++++++++++++++++++++++++++++++++++++++++---------
>  src/compositor.h |  4 ++-
>  2 files changed, 77 insertions(+), 15 deletions(-)
> 
> diff --git a/src/compositor.c b/src/compositor.c
> index 3c86f67..1592f7b 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -525,7 +525,8 @@ weston_surface_state_init(struct weston_surface_state 
> *state)
>       state->sx = 0;
>       state->sy = 0;
>  
> -     pixman_region32_init(&state->damage);
> +     pixman_region32_init(&state->damage_surface);
> +     pixman_region32_init(&state->damage_buffer);
>       pixman_region32_init(&state->opaque);
>       region_init_infinite(&state->input);
>  
> @@ -552,7 +553,8 @@ weston_surface_state_fini(struct weston_surface_state 
> *state)
>  
>       pixman_region32_fini(&state->input);
>       pixman_region32_fini(&state->opaque);
> -     pixman_region32_fini(&state->damage);
> +     pixman_region32_fini(&state->damage_surface);
> +     pixman_region32_fini(&state->damage_buffer);
>  
>       if (state->buffer)
>               wl_list_remove(&state->buffer_destroy_listener.link);
> @@ -2582,8 +2584,23 @@ surface_damage(struct wl_client *client,
>       if (width <= 0 || height <= 0)
>               return;
>  
> -     pixman_region32_union_rect(&surface->pending.damage,
> -                                &surface->pending.damage,
> +     pixman_region32_union_rect(&surface->pending.damage_surface,
> +                                &surface->pending.damage_surface,
> +                                x, y, width, height);
> +}
> +
> +static void
> +surface_damage_buffer(struct wl_client *client,
> +                   struct wl_resource *resource,
> +                   int32_t x, int32_t y, int32_t width, int32_t height)
> +{
> +     struct weston_surface *surface = wl_resource_get_user_data(resource);
> +
> +     if (width <= 0 || height <= 0)
> +             return;
> +
> +     pixman_region32_union_rect(&surface->pending.damage_buffer,
> +                                &surface->pending.damage_buffer,
>                                  x, y, width, height);
>  }
>  
> @@ -2746,6 +2763,40 @@ weston_surface_build_buffer_matrix(struct 
> weston_surface *surface,
>       weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
>  }
>  
> +/* Translate pending damage in buffer co-ordinates to surface
> + * co-ordinates and union it with a pixman_region32_t.
> + * This should only be called after the buffer is attached.
> + */
> +static void
> +apply_damage_buffer(pixman_region32_t *dest,
> +                 struct weston_surface *surface,
> +                 struct weston_surface_state *state)
> +{
> +     struct weston_buffer *buffer = surface->buffer_ref.buffer;
> +
> +     /* wl_surface.damage_buffer needs to be clipped to the buffer,
> +      * translated into surface co-ordinates and unioned with
> +      * any other surface damage.
> +      * None of this makes sense if there is no buffer though.
> +      */
> +     if (buffer && pixman_region32_not_empty(&state->damage_buffer)) {
> +             pixman_region32_t buffer_damage;
> +
> +             pixman_region32_intersect_rect(&state->damage_buffer,
> +                                            &state->damage_buffer,
> +                                            0, 0, buffer->width,
> +                                            buffer->height);
> +             pixman_region32_init(&buffer_damage);
> +             weston_matrix_transform_region(&buffer_damage,
> +                                            
> &surface->buffer_to_surface_matrix,
> +                                            &state->damage_buffer);
> +             pixman_region32_union(dest, dest, &buffer_damage);
> +             pixman_region32_fini(&buffer_damage);
> +     }
> +     /* We should clear this on commit even if there was no buffer */
> +     pixman_region32_clear(&state->damage_buffer);
> +}
> +
>  static void
>  weston_surface_commit_state(struct weston_surface *surface,
>                           struct weston_surface_state *state)
> @@ -2779,15 +2830,20 @@ weston_surface_commit_state(struct weston_surface 
> *surface,
>       state->newly_attached = 0;
>       state->buffer_viewport.changed = 0;
>  
> -     /* wl_surface.damage */
> +     /* wl_surface.damage and wl_surface.damage_buffer */
>       if (weston_timeline_enabled_ &&
> -         pixman_region32_not_empty(&state->damage))
> +         (pixman_region32_not_empty(&state->damage_surface) ||
> +          pixman_region32_not_empty(&state->damage_buffer)))
>               TL_POINT("core_commit_damage", TLP_SURFACE(surface), TLP_END);
> +
>       pixman_region32_union(&surface->damage, &surface->damage,
> -                           &state->damage);
> +                           &state->damage_surface);
> +
> +     apply_damage_buffer(&surface->damage, surface, state);
> +
>       pixman_region32_intersect_rect(&surface->damage, &surface->damage,
>                                      0, 0, surface->width, surface->height);
> -     pixman_region32_clear(&state->damage);
> +     pixman_region32_clear(&state->damage_surface);
>  
>       /* wl_surface.set_opaque_region */
>       pixman_region32_init(&opaque);
> @@ -2906,7 +2962,8 @@ static const struct wl_surface_interface 
> surface_interface = {
>       surface_set_input_region,
>       surface_commit,
>       surface_set_buffer_transform,
> -     surface_set_buffer_scale
> +     surface_set_buffer_scale,
> +     surface_damage_buffer
>  };
>  
>  static void
> @@ -3035,11 +3092,12 @@ weston_subsurface_commit_to_cache(struct 
> weston_subsurface *sub)
>        * translated to correspond to the new surface coordinate system
>        * original_mode.
>        */
> -     pixman_region32_translate(&sub->cached.damage,
> +     pixman_region32_translate(&sub->cached.damage_surface,
>                                 -surface->pending.sx, -surface->pending.sy);
> -     pixman_region32_union(&sub->cached.damage, &sub->cached.damage,
> -                           &surface->pending.damage);
> -     pixman_region32_clear(&surface->pending.damage);
> +     pixman_region32_union(&sub->cached.damage_surface,
> +                           &sub->cached.damage_surface,
> +                           &surface->pending.damage_surface);
> +     pixman_region32_clear(&surface->pending.damage_surface);
>  
>       if (surface->pending.newly_attached) {
>               sub->cached.newly_attached = 1;
> @@ -3053,6 +3111,8 @@ weston_subsurface_commit_to_cache(struct 
> weston_subsurface *sub)
>       sub->cached.sx += surface->pending.sx;
>       sub->cached.sy += surface->pending.sy;
>  
> +     apply_damage_buffer(&sub->cached.damage_surface, surface, 
> &surface->pending);
> +
>       sub->cached.buffer_viewport.changed |=
>               surface->pending.buffer_viewport.changed;
>       sub->cached.buffer_viewport.buffer =
> @@ -4549,7 +4609,7 @@ weston_compositor_create(struct wl_display *display, 
> void *user_data)
>       ec->output_id_pool = 0;
>       ec->repaint_msec = DEFAULT_REPAINT_WINDOW;
>  
> -     if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 3,
> +     if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 4,
>                             ec, compositor_bind))
>               goto fail;
>  
> diff --git a/src/compositor.h b/src/compositor.h
> index 0719abd..acc1f6d 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -931,7 +931,9 @@ struct weston_surface_state {
>       int32_t sy;
>  
>       /* wl_surface.damage */
> -     pixman_region32_t damage;
> +     pixman_region32_t damage_surface;
> +     /* wl_surface.damage_buffer */
> +     pixman_region32_t damage_buffer;
>  
>       /* wl_surface.set_opaque_region */
>       pixman_region32_t opaque;
> 

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

Reply via email to