summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2013-10-27 22:25:01 -0500
committerKristian Høgsberg <krh@bitplanet.net>2013-11-07 16:34:59 -0800
commit33ff636812b8f5db20be5c4c77bc3f9f25ea274b (patch)
tree2d6c810c751b8244f88a7337694a20bd8954b4a4
parentb6a3cc7f178123d7b094c3036de32548cdeeaeb7 (diff)
downloadweston-33ff636812b8f5db20be5c4c77bc3f9f25ea274b.tar.gz
weston-33ff636812b8f5db20be5c4c77bc3f9f25ea274b.tar.bz2
weston-33ff636812b8f5db20be5c4c77bc3f9f25ea274b.zip
Move region transformation code to weston_transformed_region
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@jlekstrand.net>
-rw-r--r--src/compositor-x11.c95
-rw-r--r--src/compositor.c92
-rw-r--r--src/compositor.h5
-rw-r--r--src/pixman-renderer.c106
4 files changed, 121 insertions, 177 deletions
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index be082084..1d1b6a42 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -368,92 +368,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 7b87a9ff..134793c2 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -543,6 +543,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 eb105a5b..c2de99f2 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -1301,6 +1301,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 79c1d5b1..a80be5f5 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)