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>
This commit is contained in:
parent
b6a3cc7f17
commit
33ff636812
@ -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 x11_output *output = (struct x11_output *)output_base;
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
struct x11_compositor *c = (struct x11_compositor *)ec;
|
struct x11_compositor *c = (struct x11_compositor *)ec;
|
||||||
|
pixman_region32_t transformed_region;
|
||||||
pixman_box32_t *rects;
|
pixman_box32_t *rects;
|
||||||
xcb_rectangle_t *output_rects;
|
xcb_rectangle_t *output_rects;
|
||||||
pixman_box32_t rect, transformed_rect;
|
|
||||||
xcb_void_cookie_t cookie;
|
xcb_void_cookie_t cookie;
|
||||||
int width, height, nrects, i;
|
int nrects, i;
|
||||||
xcb_generic_error_t *err;
|
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));
|
output_rects = calloc(nrects, sizeof(xcb_rectangle_t));
|
||||||
|
|
||||||
if (output_rects == NULL)
|
if (output_rects == NULL) {
|
||||||
|
pixman_region32_fini(&transformed_region);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
width = output_base->width;
|
|
||||||
height = output_base->height;
|
|
||||||
|
|
||||||
for (i = 0; i < nrects; i++) {
|
for (i = 0; i < nrects; i++) {
|
||||||
rect = rects[i];
|
output_rects[i].x = rects[i].x1;
|
||||||
rect.x1 -= output_base->x;
|
output_rects[i].y = rects[i].y1;
|
||||||
rect.y1 -= output_base->y;
|
output_rects[i].width = rects[i].x2 - rects[i].x1;
|
||||||
rect.x2 -= output_base->x;
|
output_rects[i].height = rects[i].y2 - rects[i].y1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_region32_fini(&transformed_region);
|
||||||
|
|
||||||
cookie = xcb_set_clip_rectangles_checked(c->conn, XCB_CLIP_ORDERING_UNSORTED,
|
cookie = xcb_set_clip_rectangles_checked(c->conn, XCB_CLIP_ORDERING_UNSORTED,
|
||||||
output->gc,
|
output->gc,
|
||||||
0, 0, nrects,
|
0, 0, nrects,
|
||||||
|
@ -542,6 +542,98 @@ weston_transformed_rect(int width, int height,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
WL_EXPORT void
|
||||||
weston_surface_to_buffer_float(struct weston_surface *surface,
|
weston_surface_to_buffer_float(struct weston_surface *surface,
|
||||||
float sx, float sy, float *bx, float *by)
|
float sx, float sy, float *bx, float *by)
|
||||||
|
@ -1301,6 +1301,11 @@ weston_transformed_rect(int width, int height,
|
|||||||
enum wl_output_transform transform,
|
enum wl_output_transform transform,
|
||||||
int32_t scale,
|
int32_t scale,
|
||||||
pixman_box32_t rect);
|
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 *
|
void *
|
||||||
weston_load_module(const char *name, const char *entrypoint);
|
weston_load_module(const char *name, const char *entrypoint);
|
||||||
|
@ -126,113 +126,13 @@ pixman_renderer_read_pixels(struct weston_output *output,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
static void
|
||||||
region_global_to_output(struct weston_output *output, pixman_region32_t *region)
|
region_global_to_output(struct weston_output *output, pixman_region32_t *region)
|
||||||
{
|
{
|
||||||
pixman_region32_translate(region, -output->x, -output->y);
|
pixman_region32_translate(region, -output->x, -output->y);
|
||||||
transform_region (region, output->width, output->height, output->transform);
|
weston_transformed_region(output->width, output->height,
|
||||||
scale_region (region, output->current_scale);
|
output->transform, output->current_scale,
|
||||||
|
region, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define D2F(v) pixman_double_to_fixed((double)v)
|
#define D2F(v) pixman_double_to_fixed((double)v)
|
||||||
|
Loading…
Reference in New Issue
Block a user