Re: [PATCH weston v2 08/20] compositor: add weston_matrix_transform_rect() and use it where appropriate
On 01/09/2015 01:42 PM, Giulio Camuffo wrote: Just a nitpick below: +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? I think that is implied pretty well by the return type, since that return type cannot possibly contain anything other than an axis-aligned box. But it may be useful to indicate this is returning a bounding box and not some other rectangle. Another useful transform is an area-preserving one (the resulting rectangle has the same area and center as transformed quadrilateral). That said, it has been very common for people to transform to a bounding box first and name this function transform rectangle. When they realize they need the other function it is then often called transform area. So this naming fits what many other libraries do. ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston v2 08/20] compositor: add weston_matrix_transform_rect() and use it where appropriate
Just a nitpick below: 2014-10-16 18:55 GMT+03:00 Derek Foreman der...@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,
[PATCH weston v2 08/20] compositor: add weston_matrix_transform_rect() and use it where appropriate
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) +{ + 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