diff options
author | Jason Ekstrand <jason@jlekstrand.net> | 2013-10-27 22:25:01 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-11-07 16:34:59 -0800 |
commit | 33ff636812b8f5db20be5c4c77bc3f9f25ea274b (patch) | |
tree | 2d6c810c751b8244f88a7337694a20bd8954b4a4 | |
parent | b6a3cc7f178123d7b094c3036de32548cdeeaeb7 (diff) | |
download | weston-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.c | 95 | ||||
-rw-r--r-- | src/compositor.c | 92 | ||||
-rw-r--r-- | src/compositor.h | 5 | ||||
-rw-r--r-- | 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 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) |