[PATCH weston 1/3] compositor-drm: Support overlays with transformed buffers

Kristian Høgsberg hoegsberg at gmail.com
Thu Dec 6 19:25:48 PST 2012


On Wed, Dec 05, 2012 at 03:14:04PM +0200, Ander Conselvan de Oliveira wrote:
> Make overlays work when the client uses a buffer with the same
> transformation as the output.
> 
> In order to calculate the destination rectangle, the same logic in
> weston_surface_to_buffer_float() is needed, but with the output
> dimensions instead. For that reason, this patch generalizes this
> function into weston_transformed_{coord,rect} and moves it to util.c.
> The surface functions are then implemented using those.
> 
> ---
> Hi,
> 
> I'm not sure if its worth keeping weston_surface_to_buffer_rect(),
> since this just reduces a few lines in one place in gl-renderer.c.

Yeah, we should probably just consolidate on
weston_transformed_{coord,rect}.  There's a big switch in
screenshooter.c that is similar, but I wasn't immediately able to make
that work with weston_transformed_rect().  Btw, I'm curious about why
you're passing the pixman_box32_t by value...  it works but it's just
a little unconventional...

Kristian

> ---
>  src/compositor-drm.c |   32 ++++++++++++++-------
>  src/compositor.c     |   66 +++++---------------------------------------
>  src/compositor.h     |    9 ++++++
>  src/util.c           |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 113 insertions(+), 69 deletions(-)
> 
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index 24a71f1..2e2b67f 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -588,11 +588,11 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
>  	int found = 0;
>  	struct gbm_bo *bo;
>  	pixman_region32_t dest_rect, src_rect;
> -	pixman_box32_t *box;
> +	pixman_box32_t *box, tbox;
>  	uint32_t format;
>  	wl_fixed_t sx1, sy1, sx2, sy2;
>  
> -	if (output_base->transform != WL_OUTPUT_TRANSFORM_NORMAL)
> +	if (es->buffer_transform != output_base->transform)
>  		return NULL;
>  
>  	if (c->sprites_are_broken)
> @@ -661,10 +661,13 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
>  				  &output_base->region);
>  	pixman_region32_translate(&dest_rect, -output_base->x, -output_base->y);
>  	box = pixman_region32_extents(&dest_rect);
> -	s->dest_x = box->x1;
> -	s->dest_y = box->y1;
> -	s->dest_w = box->x2 - box->x1;
> -	s->dest_h = box->y2 - box->y1;
> +	tbox = weston_transformed_rect(output_base->width,
> +				       output_base->height,
> +				       output_base->transform, *box);
> +	s->dest_x = tbox.x1;
> +	s->dest_y = tbox.y1;
> +	s->dest_w = tbox.x2 - tbox.x1;
> +	s->dest_h = tbox.y2 - tbox.y1;
>  	pixman_region32_fini(&dest_rect);
>  
>  	pixman_region32_init(&src_rect);
> @@ -690,10 +693,19 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
>  	if (sy2 > wl_fixed_from_int(es->geometry.height))
>  		sy2 = wl_fixed_from_int(es->geometry.height);
>  
> -	s->src_x = sx1 << 8;
> -	s->src_y = sy1 << 8;
> -	s->src_w = (sx2 - sx1) << 8;
> -	s->src_h = (sy2 - sy1) << 8;
> +	tbox.x1 = sx1;
> +	tbox.y1 = sy1;
> +	tbox.x2 = sx2;
> +	tbox.y2 = sy2;
> +
> +	tbox = weston_transformed_rect(wl_fixed_from_int(es->geometry.width),
> +				       wl_fixed_from_int(es->geometry.height),
> +				       es->buffer_transform, tbox);
> +
> +	s->src_x = tbox.x1 << 8;
> +	s->src_y = tbox.y1 << 8;
> +	s->src_w = (tbox.x2 - tbox.x1) << 8;
> +	s->src_h = (tbox.y2 - tbox.y1) << 8;
>  	pixman_region32_fini(&src_rect);
>  
>  	return &s->plane;
> diff --git a/src/compositor.c b/src/compositor.c
> index 565212d..9044007 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -314,71 +314,19 @@ WL_EXPORT void
>  weston_surface_to_buffer_float(struct weston_surface *surface,
>  			       float sx, float sy, float *bx, float *by)
>  {
> -	switch (surface->buffer_transform) {
> -	case WL_OUTPUT_TRANSFORM_NORMAL:
> -	default:
> -		*bx = sx;
> -		*by = sy;
> -		break;
> -	case WL_OUTPUT_TRANSFORM_FLIPPED:
> -		*bx = surface->geometry.width - sx;
> -		*by = sy;
> -		break;
> -	case WL_OUTPUT_TRANSFORM_90:
> -		*bx = surface->geometry.height - sy;
> -		*by = sx;
> -		break;
> -	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> -		*bx = surface->geometry.height - sy;
> -		*by = surface->geometry.width - sx;
> -		break;
> -	case WL_OUTPUT_TRANSFORM_180:
> -		*bx = surface->geometry.width - sx;
> -		*by = surface->geometry.height - sy;
> -		break;
> -	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
> -		*bx = sx;
> -		*by = surface->geometry.height - sy;
> -		break;
> -	case WL_OUTPUT_TRANSFORM_270:
> -		*bx = sy;
> -		*by = surface->geometry.width - sx;
> -		break;
> -	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> -		*bx = sy;
> -		*by = sx;
> -		break;
> -	}
> +	weston_transformed_coord(surface->geometry.width,
> +				 surface->geometry.height,
> +				 surface->buffer_transform,
> +				 sx, sy, bx, by);
>  }
>  
>  WL_EXPORT pixman_box32_t
>  weston_surface_to_buffer_rect(struct weston_surface *surface,
>  			      pixman_box32_t rect)
>  {
> -	float x1, x2, y1, y2;
> -
> -	pixman_box32_t ret;
> -
> -	weston_surface_to_buffer_float(surface, rect.x1, rect.y1, &x1, &y1);
> -	weston_surface_to_buffer_float(surface, rect.x2, rect.y2, &x2, &y2);
> -
> -	if (x1 <= x2) {
> -		ret.x1 = x1;
> -		ret.x2 = x2;
> -	} else {
> -		ret.x1 = x2;
> -		ret.x2 = x1;
> -	}
> -
> -	if (y1 <= y2) {
> -		ret.y1 = y1;
> -		ret.y2 = y2;
> -	} else {
> -		ret.y1 = y2;
> -		ret.y2 = y1;
> -	}
> -
> -	return ret;
> +	return weston_transformed_rect(surface->geometry.width,
> +				       surface->geometry.height,
> +				       surface->buffer_transform, rect);
>  }
>  
>  WL_EXPORT void
> diff --git a/src/compositor.h b/src/compositor.h
> index 2547da1..27598bd 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -824,4 +824,13 @@ backend_init(struct wl_display *display, int argc, char *argv[],
>  int
>  module_init(struct weston_compositor *compositor);
>  
> +void
> +weston_transformed_coord(int width, int height,
> +			 enum wl_output_transform transform,
> +			 float sx, float sy, float *bx, float *by);
> +pixman_box32_t
> +weston_transformed_rect(int width, int height,
> +			enum wl_output_transform transform,
> +			pixman_box32_t rect);
> +
>  #endif
> diff --git a/src/util.c b/src/util.c
> index 2134392..5f8e9c8 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -557,3 +557,78 @@ weston_environment_get_fd(const char *env)
>  
>  	return fd;
>  }
> +
> +WL_EXPORT void
> +weston_transformed_coord(int width, int height,
> +			 enum wl_output_transform transform,
> +			 float sx, float sy, float *bx, float *by)
> +{
> +	switch (transform) {
> +	case WL_OUTPUT_TRANSFORM_NORMAL:
> +	default:
> +		*bx = sx;
> +		*by = sy;
> +		break;
> +	case WL_OUTPUT_TRANSFORM_FLIPPED:
> +		*bx = width - sx;
> +		*by = sy;
> +		break;
> +	case WL_OUTPUT_TRANSFORM_90:
> +		*bx = height - sy;
> +		*by = sx;
> +		break;
> +	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> +		*bx = height - sy;
> +		*by = width - sx;
> +		break;
> +	case WL_OUTPUT_TRANSFORM_180:
> +		*bx = width - sx;
> +		*by = height - sy;
> +		break;
> +	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
> +		*bx = sx;
> +		*by = height - sy;
> +		break;
> +	case WL_OUTPUT_TRANSFORM_270:
> +		*bx = sy;
> +		*by = width - sx;
> +		break;
> +	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> +		*bx = sy;
> +		*by = sx;
> +		break;
> +	}
> +}
> +
> +WL_EXPORT pixman_box32_t
> +weston_transformed_rect(int width, int height,
> +			enum wl_output_transform transform,
> +			pixman_box32_t rect)
> +{
> +	float x1, x2, y1, y2;
> +
> +	pixman_box32_t ret;
> +
> +	weston_transformed_coord(width, height, transform,
> +				 rect.x1, rect.y1, &x1, &y1);
> +	weston_transformed_coord(width, height, transform,
> +				 rect.x2, rect.y2, &x2, &y2);
> +
> +	if (x1 <= x2) {
> +		ret.x1 = x1;
> +		ret.x2 = x2;
> +	} else {
> +		ret.x1 = x2;
> +		ret.x2 = x1;
> +	}
> +
> +	if (y1 <= y2) {
> +		ret.y1 = y1;
> +		ret.y2 = y2;
> +	} else {
> +		ret.y1 = y2;
> +		ret.y2 = y1;
> +	}
> +
> +	return ret;
> +}
> -- 
> 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