[PATCH weston v2 08/20] compositor: add weston_matrix_transform_rect() and use it where appropriate
Giulio Camuffo
giuliocamuffo at gmail.com
Fri Jan 9 13:42:20 PST 2015
Just a nitpick below:
2014-10-16 18:55 GMT+03:00 Derek Foreman <derekf at osg.samsung.com>:
> New function that transforms a pixman_box32_t rectangle by a matrix.
>
> Since pixman rectangles are represented by 2 corners, non-90 degree
> rotations can't be properly represented. This function gives the
> axis aligned rectangle that encloses the rotated rectangle.
>
> We use this for matrix_transform_region() and weston_matrix_transform_rect(),
> simplifying them and allowing them to work for non 90 degree rotations.
> ---
> src/compositor.c | 96 ++++++++++++++++++++++++++++----------------------------
> src/compositor.h | 4 +++
> 2 files changed, 52 insertions(+), 48 deletions(-)
>
> diff --git a/src/compositor.c b/src/compositor.c
> index e45dd62..7c0f050 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -654,6 +654,50 @@ weston_view_to_global_float(struct weston_view *view,
> }
> }
>
> +WL_EXPORT pixman_box32_t
> +weston_matrix_transform_rect(struct weston_matrix *matrix,
> + pixman_box32_t rect)
The function name doesn't imply it returns an axis aligned bounding
box. Maybe something like "weston_matrix_rect_to_transformed_aabb"
would be better?
> +{
> + int i;
> + pixman_box32_t out;
> +
> + /* since pixman regions are defined by two corners we have
> + * to be careful with rotations that aren't multiples of 90.
> + * We need to take all four corners of the region and rotate
> + * them, then construct the largest possible two corner
> + * rectangle from the result.
> + */
> + struct weston_vector corners[4] = {
> + {{rect.x1, rect.y1, 0, 1}},
> + {{rect.x2, rect.y1, 0, 1}},
> + {{rect.x1, rect.y2, 0, 1}},
> + {{rect.x2, rect.y2, 0, 1}},
> + };
> +
> + for (i = 0; i < 4; i++) {
> + weston_matrix_transform(matrix, &corners[i]);
> + corners[i].f[0] /= corners[i].f[3];
> + corners[i].f[1] /= corners[i].f[3];
> + }
> +
> + out.x1 = floor(corners[0].f[0]);
> + out.y1 = floor(corners[0].f[1]);
> + out.x2 = ceil(corners[0].f[0]);
> + out.y2 = ceil(corners[0].f[1]);
> +
> + for (i = 1; i < 4; i++) {
> + if (floor(corners[i].f[0]) < out.x1)
> + out.x1 = floor(corners[i].f[0]);
> + if (floor(corners[i].f[1]) < out.y1)
> + out.y1 = floor(corners[i].f[1]);
> + if (ceil(corners[i].f[0]) > out.x2)
> + out.x2 = ceil(corners[i].f[0]);
> + if (ceil(corners[i].f[1]) > out.y2)
> + out.y2 = ceil(corners[i].f[1]);
> + }
> + return out;
> +}
> +
> WL_EXPORT void
> weston_transformed_coord(int width, int height,
> enum wl_output_transform transform,
> @@ -747,38 +791,8 @@ weston_matrix_transform_region(pixman_region32_t *dest,
> if (!dest_rects)
> return;
>
> - for (i = 0; i < nrects; i++) {
> - struct weston_vector vec1 = {{
> - src_rects[i].x1, src_rects[i].y1, 0, 1
> - }};
> - weston_matrix_transform(matrix, &vec1);
> - vec1.f[0] /= vec1.f[3];
> - vec1.f[1] /= vec1.f[3];
> -
> - struct weston_vector vec2 = {{
> - src_rects[i].x2, src_rects[i].y2, 0, 1
> - }};
> - weston_matrix_transform(matrix, &vec2);
> - vec2.f[0] /= vec2.f[3];
> - vec2.f[1] /= vec2.f[3];
> -
> - if (vec1.f[0] < vec2.f[0]) {
> - dest_rects[i].x1 = floor(vec1.f[0]);
> - dest_rects[i].x2 = ceil(vec2.f[0]);
> - } else {
> - dest_rects[i].x1 = floor(vec2.f[0]);
> - dest_rects[i].x2 = ceil(vec1.f[0]);
> - }
> -
> -
> - if (vec1.f[1] < vec2.f[1]) {
> - dest_rects[i].y1 = floor(vec1.f[1]);
> - dest_rects[i].y2 = ceil(vec2.f[1]);
> - } else {
> - dest_rects[i].y1 = floor(vec2.f[1]);
> - dest_rects[i].y2 = ceil(vec1.f[1]);
> - }
> - }
> + for (i = 0; i < nrects; i++)
> + dest_rects[i] = weston_matrix_transform_rect(matrix, src_rects[i]);
>
> pixman_region32_clear(dest);
> pixman_region32_init_rects(dest, dest_rects, nrects);
> @@ -939,22 +953,8 @@ WL_EXPORT pixman_box32_t
> weston_surface_to_buffer_rect(struct weston_surface *surface,
> pixman_box32_t rect)
> {
> - struct weston_buffer_viewport *vp = &surface->buffer_viewport;
> - float xf, yf;
> -
> - /* first transform box coordinates if the scaler is set */
> - scaler_surface_to_buffer(surface, rect.x1, rect.y1, &xf, &yf);
> - rect.x1 = floorf(xf);
> - rect.y1 = floorf(yf);
> -
> - scaler_surface_to_buffer(surface, rect.x2, rect.y2, &xf, &yf);
> - rect.x2 = floorf(xf);
> - rect.y2 = floorf(yf);
> -
> - return weston_transformed_rect(surface->width_from_buffer,
> - surface->height_from_buffer,
> - vp->buffer.transform, vp->buffer.scale,
> - rect);
> + return weston_matrix_transform_rect(&surface->surface_to_buffer_matrix,
> + rect);
> }
>
> WL_EXPORT void
> diff --git a/src/compositor.h b/src/compositor.h
> index b15eb01..79b5190 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -1453,6 +1453,10 @@ int
> module_init(struct weston_compositor *compositor,
> int *argc, char *argv[]);
>
> +pixman_box32_t
> +weston_matrix_transform_rect(struct weston_matrix *matrix,
> + pixman_box32_t rect);
> +
> void
> weston_transformed_coord(int width, int height,
> enum wl_output_transform transform,
> --
> 2.1.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list