[PATCH weston 1/2] compositor: Fix culling of repaints behind opaque surfaces

Kristian Høgsberg hoegsberg at gmail.com
Wed Oct 31 10:46:04 PDT 2012


On Wed, Oct 31, 2012 at 05:55:45PM +0200, Ander Conselvan de Oliveira wrote:
> Culling of the repaint of a surface behind an opaque surface on the
> same plane was broken by commit 547149a9 [1]. The idea of that commit
> is that the damage obscured by an overlay would remain on the primary
> plane damage and be repainted when the overlay moved. However, in the
> case the two surfaces are on the same plane, the opaque one is not
> obscured, so it ends up being repainted.
> 
> This commit adds an opaque field to struct weston_plane, that is built
> incrementally when accumulating damage. The opaque region of surfaces
> on the same plane are removed from the plane's damage, restoring the
> previous culling behavior. But since damage behind opaque region of
> other planes is maintained, the bug solved in the mentioned commit is
> not regressed.
> ---
> 
> I'm not sure if resetting the opaque regions in assign_planes is a good
> idea¸ but since there's no plane list in compositor, that seemed like
> the only obvious way of doing it from weston_output_repaint().

Yeah, that's fine.  Maybe we'll make a compositor global list of
planes eventually and then just clear all plane opaque regions by
looping through that list.  Pekka is pushing the weston_plane
abstraction in his Raspberry Pi work, we'll see what he comes up with,
but for now this is good enough.

Kristian

>  src/compositor-drm.c |   16 ++++++++++++++++
>  src/compositor.c     |   10 ++++++++++
>  src/compositor.h     |    1 +
>  3 files changed, 27 insertions(+)
> 
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index 1730cb2..1133281 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -793,10 +793,26 @@ drm_assign_planes(struct weston_output *output)
>  {
>  	struct drm_compositor *c =
>  		(struct drm_compositor *) output->compositor;
> +	struct drm_output *drm_output = (struct drm_output *) output;
> +	struct drm_sprite *s;
>  	struct weston_surface *es, *next;
>  	pixman_region32_t overlap, surface_overlap;
>  	struct weston_plane *primary, *next_plane;
>  
> +	/* Reset the opaque region of the planes */
> +	pixman_region32_fini(&drm_output->cursor_plane.opaque);
> +	pixman_region32_init(&drm_output->cursor_plane.opaque);
> +	pixman_region32_fini(&drm_output->fb_plane.opaque);
> +	pixman_region32_init(&drm_output->fb_plane.opaque);
> +
> +	wl_list_for_each (s, &c->sprite_list, link) {
> +		if (!drm_sprite_crtc_supported(output, s->possible_crtcs))
> +			continue;
> +
> +		pixman_region32_fini(&s->plane.opaque);
> +		pixman_region32_init(&s->plane.opaque);
> +	}
> +
>  	/*
>  	 * Find a surface for each sprite in the output using some heuristics:
>  	 * 1) size
> diff --git a/src/compositor.c b/src/compositor.c
> index 56474a5..2d5b263 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -925,10 +925,15 @@ surface_accumulate_damage(struct weston_surface *surface,
>  					  surface->geometry.y - surface->plane->y);
>  	}
>  
> +	pixman_region32_subtract(&surface->damage,
> +				 &surface->damage, &surface->plane->opaque);
>  	pixman_region32_union(&surface->plane->damage,
>  			      &surface->plane->damage, &surface->damage);
>  	empty_region(&surface->damage);
>  	pixman_region32_copy(&surface->clip, opaque);
> +	pixman_region32_union(&surface->plane->opaque,
> +			      &surface->plane->opaque,
> +			      &surface->transform.opaque);
>  	pixman_region32_union(opaque, opaque, &surface->transform.opaque);
>  }
>  
> @@ -968,6 +973,9 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
>  
>  	pixman_region32_init(&opaque);
>  
> +	pixman_region32_fini(&ec->primary_plane.opaque);
> +	pixman_region32_init(&ec->primary_plane.opaque);
> +
>  	wl_list_for_each(es, &ec->surface_list, link)
>  		surface_accumulate_damage(es, &opaque);
>  
> @@ -1455,6 +1463,7 @@ WL_EXPORT void
>  weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
>  {
>  	pixman_region32_init(&plane->damage);
> +	pixman_region32_init(&plane->opaque);
>  	plane->x = x;
>  	plane->y = y;
>  }
> @@ -1463,6 +1472,7 @@ WL_EXPORT void
>  weston_plane_release(struct weston_plane *plane)
>  {
>  	pixman_region32_fini(&plane->damage);
> +	pixman_region32_fini(&plane->opaque);
>  }
>  
>  static  void
> diff --git a/src/compositor.h b/src/compositor.h
> index 3176bfd..121f6bf 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -270,6 +270,7 @@ struct weston_layer {
>  
>  struct weston_plane {
>  	pixman_region32_t damage;
> +	pixman_region32_t opaque;
>  	int32_t x, y;
>  };
>  
> -- 
> 1.7.10.4
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list