Both the Pixman renderer and the X11 backend contained effectively the same
region transformation code.  This commit adds a weston_transformed_region
function and changes pixman-renderer and compositor-x11 to use it.

Signed-off-by: Jason Ekstrand <ja...@jlekstrand.net>
---
 src/compositor-x11.c  |  95 ++++++++++----------------------------------
 src/compositor.c      |  92 +++++++++++++++++++++++++++++++++++++++++++
 src/compositor.h      |   5 +++
 src/pixman-renderer.c | 106 ++------------------------------------------------
 4 files changed, 121 insertions(+), 177 deletions(-)

diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 961ee0a..69db8fc 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -366,92 +366,39 @@ set_clip_for_output(struct weston_output *output_base, 
pixman_region32_t *region
        struct x11_output *output = (struct x11_output *)output_base;
        struct weston_compositor *ec = output->base.compositor;
        struct x11_compositor *c = (struct x11_compositor *)ec;
+       pixman_region32_t transformed_region;
        pixman_box32_t *rects;
        xcb_rectangle_t *output_rects;
-       pixman_box32_t rect, transformed_rect;
        xcb_void_cookie_t cookie;
-       int width, height, nrects, i;
+       int nrects, i;
        xcb_generic_error_t *err;
 
-       rects = pixman_region32_rectangles(region, &nrects);
+       pixman_region32_init(&transformed_region);
+       pixman_region32_copy(&transformed_region, region);
+       pixman_region32_translate(&transformed_region,
+                                 -output_base->x, -output_base->y);
+       weston_transformed_region(output_base->width, output_base->height,
+                                 output_base->transform,
+                                 output_base->current_scale,
+                                 &transformed_region, &transformed_region);
+
+       rects = pixman_region32_rectangles(&transformed_region, &nrects);
        output_rects = calloc(nrects, sizeof(xcb_rectangle_t));
 
-       if (output_rects == NULL)
+       if (output_rects == NULL) {
+               pixman_region32_fini(&transformed_region);
                return;
-
-       width = output_base->width;
-       height = output_base->height;
+       }
 
        for (i = 0; i < nrects; i++) {
-               rect = rects[i];
-               rect.x1 -= output_base->x;
-               rect.y1 -= output_base->y;
-               rect.x2 -= output_base->x;
-               rect.y2 -= output_base->y;
-
-               switch (output_base->transform) {
-               default:
-               case WL_OUTPUT_TRANSFORM_NORMAL:
-                       transformed_rect.x1 = rect.x1;
-                       transformed_rect.y1 = rect.y1;
-                       transformed_rect.x2 = rect.x2;
-                       transformed_rect.y2 = rect.y2;
-                       break;
-               case WL_OUTPUT_TRANSFORM_90:
-                       transformed_rect.x1 = height - rect.y2;
-                       transformed_rect.y1 = rect.x1;
-                       transformed_rect.x2 = height - rect.y1;
-                       transformed_rect.y2 = rect.x2;
-                       break;
-               case WL_OUTPUT_TRANSFORM_180:
-                       transformed_rect.x1 = width - rect.x2;
-                       transformed_rect.y1 = height - rect.y2;
-                       transformed_rect.x2 = width - rect.x1;
-                       transformed_rect.y2 = height - rect.y1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_270:
-                       transformed_rect.x1 = rect.y1;
-                       transformed_rect.y1 = width - rect.x2;
-                       transformed_rect.x2 = rect.y2;
-                       transformed_rect.y2 = width - rect.x1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED:
-                       transformed_rect.x1 = width - rect.x2;
-                       transformed_rect.y1 = rect.y1;
-                       transformed_rect.x2 = width - rect.x1;
-                       transformed_rect.y2 = rect.y2;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-                       transformed_rect.x1 = height - rect.y2;
-                       transformed_rect.y1 = width - rect.x2;
-                       transformed_rect.x2 = height - rect.y1;
-                       transformed_rect.y2 = width - rect.x1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED_180:
-                       transformed_rect.x1 = rect.x1;
-                       transformed_rect.y1 = height - rect.y2;
-                       transformed_rect.x2 = rect.x2;
-                       transformed_rect.y2 = height - rect.y1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-                       transformed_rect.x1 = rect.y1;
-                       transformed_rect.y1 = rect.x1;
-                       transformed_rect.x2 = rect.y2;
-                       transformed_rect.y2 = rect.x2;
-                       break;
-               }
-
-               transformed_rect.x1 *= output_base->current_scale;
-               transformed_rect.y1 *= output_base->current_scale;
-               transformed_rect.x2 *= output_base->current_scale;
-               transformed_rect.y2 *= output_base->current_scale;
-
-               output_rects[i].x = transformed_rect.x1;
-               output_rects[i].y = transformed_rect.y1;
-               output_rects[i].width = transformed_rect.x2 - 
transformed_rect.x1;
-               output_rects[i].height = transformed_rect.y2 - 
transformed_rect.y1;
+               output_rects[i].x = rects[i].x1;
+               output_rects[i].y = rects[i].y1;
+               output_rects[i].width = rects[i].x2 - rects[i].x1;
+               output_rects[i].height = rects[i].y2 - rects[i].y1;
        }
 
+       pixman_region32_fini(&transformed_region);
+
        cookie = xcb_set_clip_rectangles_checked(c->conn, 
XCB_CLIP_ORDERING_UNSORTED,
                                        output->gc,
                                        0, 0, nrects,
diff --git a/src/compositor.c b/src/compositor.c
index cc33ba5..7b1d352 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -549,6 +549,98 @@ weston_transformed_rect(int width, int height,
 }
 
 WL_EXPORT void
+weston_transformed_region(int width, int height,
+                         enum wl_output_transform transform,
+                         int32_t scale,
+                         pixman_region32_t *src, pixman_region32_t *dest)
+{
+       pixman_box32_t *src_rects, *dest_rects;
+       int nrects, i;
+
+       if (transform == WL_OUTPUT_TRANSFORM_NORMAL && scale == 1) {
+               if (src != dest)
+                       pixman_region32_copy(dest, src);
+               return;
+       }
+
+       src_rects = pixman_region32_rectangles(src, &nrects);
+       dest_rects = malloc(nrects * sizeof(*dest_rects));
+       if (!dest_rects)
+               return;
+
+       if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
+               memcpy(dest_rects, src_rects, nrects * sizeof(*dest_rects));
+       } else {
+               for (i = 0; i < nrects; i++) {
+                       switch (transform) {
+                       default:
+                       case WL_OUTPUT_TRANSFORM_NORMAL:
+                               dest_rects[i].x1 = src_rects[i].x1;
+                               dest_rects[i].y1 = src_rects[i].y1;
+                               dest_rects[i].x2 = src_rects[i].x2;
+                               dest_rects[i].y2 = src_rects[i].y2;
+                               break;
+                       case WL_OUTPUT_TRANSFORM_90:
+                               dest_rects[i].x1 = height - src_rects[i].y2;
+                               dest_rects[i].y1 = src_rects[i].x1;
+                               dest_rects[i].x2 = height - src_rects[i].y1;
+                               dest_rects[i].y2 = src_rects[i].x2;
+                               break;
+                       case WL_OUTPUT_TRANSFORM_180:
+                               dest_rects[i].x1 = width - src_rects[i].x2;
+                               dest_rects[i].y1 = height - src_rects[i].y2;
+                               dest_rects[i].x2 = width - src_rects[i].x1;
+                               dest_rects[i].y2 = height - src_rects[i].y1;
+                               break;
+                       case WL_OUTPUT_TRANSFORM_270:
+                               dest_rects[i].x1 = src_rects[i].y1;
+                               dest_rects[i].y1 = width - src_rects[i].x2;
+                               dest_rects[i].x2 = src_rects[i].y2;
+                               dest_rects[i].y2 = width - src_rects[i].x1;
+                               break;
+                       case WL_OUTPUT_TRANSFORM_FLIPPED:
+                               dest_rects[i].x1 = width - src_rects[i].x2;
+                               dest_rects[i].y1 = src_rects[i].y1;
+                               dest_rects[i].x2 = width - src_rects[i].x1;
+                               dest_rects[i].y2 = src_rects[i].y2;
+                               break;
+                       case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+                               dest_rects[i].x1 = height - src_rects[i].y2;
+                               dest_rects[i].y1 = width - src_rects[i].x2;
+                               dest_rects[i].x2 = height - src_rects[i].y1;
+                               dest_rects[i].y2 = width - src_rects[i].x1;
+                               break;
+                       case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+                               dest_rects[i].x1 = src_rects[i].x1;
+                               dest_rects[i].y1 = height - src_rects[i].y2;
+                               dest_rects[i].x2 = src_rects[i].x2;
+                               dest_rects[i].y2 = height - src_rects[i].y1;
+                               break;
+                       case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+                               dest_rects[i].x1 = src_rects[i].y1;
+                               dest_rects[i].y1 = src_rects[i].x1;
+                               dest_rects[i].x2 = src_rects[i].y2;
+                               dest_rects[i].y2 = src_rects[i].x2;
+                               break;
+                       }
+               }
+       }
+
+       if (scale != 1) {
+               for (i = 0; i < nrects; i++) {
+                       dest_rects[i].x1 *= scale;
+                       dest_rects[i].x2 *= scale;
+                       dest_rects[i].y1 *= scale;
+                       dest_rects[i].y2 *= scale;
+               }
+       }
+
+       pixman_region32_clear(dest);
+       pixman_region32_init_rects(dest, dest_rects, nrects);
+       free(dest_rects);
+}
+
+WL_EXPORT void
 weston_surface_to_buffer_float(struct weston_surface *surface,
                               float sx, float sy, float *bx, float *by)
 {
diff --git a/src/compositor.h b/src/compositor.h
index b4dd942..bfdd108 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -1300,6 +1300,11 @@ weston_transformed_rect(int width, int height,
                        enum wl_output_transform transform,
                        int32_t scale,
                        pixman_box32_t rect);
+void
+weston_transformed_region(int width, int height,
+                         enum wl_output_transform transform,
+                         int32_t scale,
+                         pixman_region32_t *src, pixman_region32_t *dest);
 
 void *
 weston_load_module(const char *name, const char *entrypoint);
diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
index 79c1d5b..a80be5f 100644
--- a/src/pixman-renderer.c
+++ b/src/pixman-renderer.c
@@ -127,112 +127,12 @@ pixman_renderer_read_pixels(struct weston_output *output,
 }
 
 static void
-box_scale(pixman_box32_t *dst, int scale)
-{
-       dst->x1 *= scale;
-       dst->x2 *= scale;
-       dst->y1 *= scale;
-       dst->y2 *= scale;
-}
-
-static void
-scale_region (pixman_region32_t *region, int scale)
-{
-       pixman_box32_t *rects, *scaled_rects;
-       int nrects, i;
-
-       if (scale != 1) {
-               rects = pixman_region32_rectangles(region, &nrects);
-               scaled_rects = calloc(nrects, sizeof(pixman_box32_t));
-
-               for (i = 0; i < nrects; i++) {
-                       scaled_rects[i] = rects[i];
-                       box_scale(&scaled_rects[i], scale);
-               }
-               pixman_region32_clear(region);
-
-               pixman_region32_init_rects (region, scaled_rects, nrects);
-               free (scaled_rects);
-       }
-}
-
-static void
-transform_region (pixman_region32_t *region, int width, int height, enum 
wl_output_transform transform)
-{
-       pixman_box32_t *rects, *transformed_rects;
-       int nrects, i;
-
-       if (transform == WL_OUTPUT_TRANSFORM_NORMAL)
-               return;
-
-       rects = pixman_region32_rectangles(region, &nrects);
-       transformed_rects = calloc(nrects, sizeof(pixman_box32_t));
-
-       for (i = 0; i < nrects; i++) {
-               switch (transform) {
-               default:
-               case WL_OUTPUT_TRANSFORM_NORMAL:
-                       transformed_rects[i].x1 = rects[i].x1;
-                       transformed_rects[i].y1 = rects[i].y1;
-                       transformed_rects[i].x2 = rects[i].x2;
-                       transformed_rects[i].y2 = rects[i].y2;
-                       break;
-               case WL_OUTPUT_TRANSFORM_90:
-                       transformed_rects[i].x1 = height - rects[i].y2;
-                       transformed_rects[i].y1 = rects[i].x1;
-                       transformed_rects[i].x2 = height - rects[i].y1;
-                       transformed_rects[i].y2 = rects[i].x2;
-                       break;
-               case WL_OUTPUT_TRANSFORM_180:
-                       transformed_rects[i].x1 = width - rects[i].x2;
-                       transformed_rects[i].y1 = height - rects[i].y2;
-                       transformed_rects[i].x2 = width - rects[i].x1;
-                       transformed_rects[i].y2 = height - rects[i].y1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_270:
-                       transformed_rects[i].x1 = rects[i].y1;
-                       transformed_rects[i].y1 = width - rects[i].x2;
-                       transformed_rects[i].x2 = rects[i].y2;
-                       transformed_rects[i].y2 = width - rects[i].x1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED:
-                       transformed_rects[i].x1 = width - rects[i].x2;
-                       transformed_rects[i].y1 = rects[i].y1;
-                       transformed_rects[i].x2 = width - rects[i].x1;
-                       transformed_rects[i].y2 = rects[i].y2;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-                       transformed_rects[i].x1 = height - rects[i].y2;
-                       transformed_rects[i].y1 = width - rects[i].x2;
-                       transformed_rects[i].x2 = height - rects[i].y1;
-                       transformed_rects[i].y2 = width - rects[i].x1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED_180:
-                       transformed_rects[i].x1 = rects[i].x1;
-                       transformed_rects[i].y1 = height - rects[i].y2;
-                       transformed_rects[i].x2 = rects[i].x2;
-                       transformed_rects[i].y2 = height - rects[i].y1;
-                       break;
-               case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-                       transformed_rects[i].x1 = rects[i].y1;
-                       transformed_rects[i].y1 = rects[i].x1;
-                       transformed_rects[i].x2 = rects[i].y2;
-                       transformed_rects[i].y2 = rects[i].x2;
-                       break;
-               }
-       }
-       pixman_region32_clear(region);
-
-       pixman_region32_init_rects (region, transformed_rects, nrects);
-       free (transformed_rects);
-}
-
-static void
 region_global_to_output(struct weston_output *output, pixman_region32_t 
*region)
 {
        pixman_region32_translate(region, -output->x, -output->y);
-       transform_region (region, output->width, output->height, 
output->transform);
-       scale_region (region, output->current_scale);
+       weston_transformed_region(output->width, output->height,
+                                 output->transform, output->current_scale,
+                                 region, region);
 }
 
 #define D2F(v) pixman_double_to_fixed((double)v)
-- 
1.8.3.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to