[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