[PATCH weston 09/11] Move region transformation code to weston_transformed_region

Jason Ekstrand jason at jlekstrand.net
Mon Oct 28 04:25:01 CET 2013


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 <jason at 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



More information about the wayland-devel mailing list