aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-03-26 15:31:08 -0400
committeremersion <contact@emersion.fr>2018-03-26 15:31:08 -0400
commit4555fc8a543caed15250a038e979bb24cee03a6c (patch)
tree44667d21ef6d897206661a3bb597c7a658a4c418 /util
parentbcb74c2c781405149af99f66ce61b1a8f63771fd (diff)
Fix damage tracking for rotated surfaces
It was broken because the damage extents were rotated about its own center, not about the center of the surface. This adds a new wlr_region_rotated_bounds that rotates regions. This allows us to have only one code path (for both non-rotated views and rotated views) and optimizes rendering for rotated views.
Diffstat (limited to 'util')
-rw-r--r--util/region.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/util/region.c b/util/region.c
index 88e38fd2..38f84c5e 100644
--- a/util/region.c
+++ b/util/region.c
@@ -128,3 +128,52 @@ void wlr_region_expand(pixman_region32_t *dst, pixman_region32_t *src,
pixman_region32_init_rects(dst, dst_rects, nrects);
free(dst_rects);
}
+
+void wlr_region_rotated_bounds(pixman_region32_t *dst, pixman_region32_t *src,
+ float rotation, int ox, int oy) {
+ if (rotation == 0) {
+ pixman_region32_copy(dst, src);
+ return;
+ }
+
+ int nrects;
+ pixman_box32_t *src_rects = pixman_region32_rectangles(src, &nrects);
+
+ pixman_box32_t *dst_rects = malloc(nrects * sizeof(pixman_box32_t));
+ if (dst_rects == NULL) {
+ return;
+ }
+
+ for (int i = 0; i < nrects; ++i) {
+ double x1 = src_rects[i].x1 - ox;
+ double y1 = src_rects[i].y1 - oy;
+ double x2 = src_rects[i].x2 - ox;
+ double y2 = src_rects[i].y2 - oy;
+
+ double rx1 = x1 * cos(rotation) - y1 * sin(rotation);
+ double ry1 = x1 * sin(rotation) + y1 * cos(rotation);
+
+ double rx2 = x2 * cos(rotation) - y1 * sin(rotation);
+ double ry2 = x2 * sin(rotation) + y1 * cos(rotation);
+
+ double rx3 = x2 * cos(rotation) - y2 * sin(rotation);
+ double ry3 = x2 * sin(rotation) + y2 * cos(rotation);
+
+ double rx4 = x1 * cos(rotation) - y2 * sin(rotation);
+ double ry4 = x1 * sin(rotation) + y2 * cos(rotation);
+
+ x1 = fmin(fmin(rx1, rx2), fmin(rx3, rx4));
+ y1 = fmin(fmin(ry1, ry2), fmin(ry3, ry4));
+ x2 = fmax(fmax(rx1, rx2), fmax(rx3, rx4));
+ y2 = fmax(fmax(ry1, ry2), fmax(ry3, ry4));
+
+ dst_rects[i].x1 = floor(ox + x1);
+ dst_rects[i].x2 = ceil(ox + x2);
+ dst_rects[i].y1 = floor(oy + y1);
+ dst_rects[i].y2 = ceil(oy + y2);
+ }
+
+ pixman_region32_fini(dst);
+ pixman_region32_init_rects(dst, dst_rects, nrects);
+ free(dst_rects);
+}