aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/drm/drm.c15
-rw-r--r--backend/wayland/wl_seat.c12
-rw-r--r--include/rootston/output.h4
-rw-r--r--include/wlr/types/wlr_box.h8
-rw-r--r--include/wlr/types/wlr_output.h3
-rw-r--r--include/wlr/util/region.h7
-rw-r--r--rootston/output.c79
-rw-r--r--types/wlr_box.c45
-rw-r--r--types/wlr_output.c2
-rw-r--r--types/wlr_surface.c88
-rw-r--r--util/meson.build2
-rw-r--r--util/region.c74
12 files changed, 185 insertions, 154 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 4ba36bc4..5ab51e82 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -581,15 +581,14 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,
}
struct wlr_box hotspot = {
- .width = plane->surf.width,
- .height = plane->surf.height,
.x = hotspot_x,
.y = hotspot_y,
};
enum wl_output_transform transform =
wlr_output_transform_invert(output->transform);
struct wlr_box transformed_hotspot;
- wlr_box_transform(&hotspot, transform, &transformed_hotspot);
+ wlr_box_transform(&hotspot, transform,
+ plane->surf.width, plane->surf.height, &transformed_hotspot);
plane->cursor_hotspot_x = transformed_hotspot.x;
plane->cursor_hotspot_y = transformed_hotspot.y;
@@ -650,15 +649,15 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output,
}
struct wlr_drm_plane *plane = conn->crtc->cursor;
- struct wlr_box box;
- box.x = x;
- box.y = y;
- wlr_output_effective_resolution(output, &box.width, &box.height);
+ struct wlr_box box = { .x = x, .y = y };
+
+ int width, height;
+ wlr_output_effective_resolution(output, &width, &height);
enum wl_output_transform transform =
wlr_output_transform_invert(output->transform);
struct wlr_box transformed_box;
- wlr_box_transform(&box, transform, &transformed_box);
+ wlr_box_transform(&box, transform, width, height, &transformed_box);
if (plane != NULL) {
transformed_box.x -= plane->cursor_hotspot_x;
diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c
index 90f7d44c..37489678 100644
--- a/backend/wayland/wl_seat.c
+++ b/backend/wayland/wl_seat.c
@@ -54,14 +54,16 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
struct wlr_output *wlr_output = &wlr_wl_pointer->current_output->wlr_output;
- struct wlr_box box;
+ int width, height;
wl_egl_window_get_attached_size(wlr_wl_pointer->current_output->egl_window,
- &box.width, &box.height);
- box.x = wl_fixed_to_int(surface_x);
- box.y = wl_fixed_to_int(surface_y);
+ &width, &height);
+ struct wlr_box box = {
+ .x = wl_fixed_to_int(surface_x),
+ .y = wl_fixed_to_int(surface_y),
+ };
struct wlr_box transformed;
- wlr_box_transform(&box, wlr_output->transform, &transformed);
+ wlr_box_transform(&box, wlr_output->transform, width, height, &transformed);
transformed.x /= wlr_output->scale;
transformed.y /= wlr_output->scale;
diff --git a/include/rootston/output.h b/include/rootston/output.h
index 81f20788..11f53d83 100644
--- a/include/rootston/output.h
+++ b/include/rootston/output.h
@@ -7,7 +7,7 @@
/**
* Damage tracking requires to keep track of previous frames' damage. To allow
- * damage tracking to work with triple buffering, an history of two frames is
+ * damage tracking to work with triple buffering, a history of two frames is
* required.
*/
#define ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN 2
@@ -22,7 +22,7 @@ struct roots_output {
struct roots_view *fullscreen_view;
struct timespec last_frame;
- pixman_region32_t damage;
+ pixman_region32_t damage; // in ouput-local coordinates
bool frame_pending;
// circular queue for previous damage
diff --git a/include/wlr/types/wlr_box.h b/include/wlr/types/wlr_box.h
index 0588201c..d6cc3509 100644
--- a/include/wlr/types/wlr_box.h
+++ b/include/wlr/types/wlr_box.h
@@ -2,6 +2,7 @@
#define WLR_TYPES_WLR_BOX_H
#include <stdbool.h>
+#include <wayland-server.h>
struct wlr_box {
int x, y;
@@ -18,8 +19,11 @@ bool wlr_box_contains_point(const struct wlr_box *box, double x, double y);
bool wlr_box_empty(const struct wlr_box *box);
-enum wl_output_transform;
+/**
+ * Transforms a box inside a `width` x `height` box.
+ */
void wlr_box_transform(const struct wlr_box *box,
- enum wl_output_transform transform, struct wlr_box *dest);
+ enum wl_output_transform transform, int width, int height,
+ struct wlr_box *dest);
#endif
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 823c3b5e..4eefbf55 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -61,7 +61,8 @@ struct wlr_output {
enum wl_output_transform transform;
bool needs_swap;
- pixman_region32_t damage; // damage for cursors and fullscreen surface
+ // damage for cursors and fullscreen surface, in output-local coordinates
+ pixman_region32_t damage;
float transform_matrix[16];
struct {
diff --git a/include/wlr/util/region.h b/include/wlr/util/region.h
index e268436b..5d2b37e1 100644
--- a/include/wlr/util/region.h
+++ b/include/wlr/util/region.h
@@ -2,6 +2,7 @@
#define WLR_UTIL_REGION_H
#include <pixman.h>
+#include <wayland-server.h>
/**
* Scales a region, ie. multiplies all its coordinates by `scale`.
@@ -12,4 +13,10 @@
void wlr_region_scale(pixman_region32_t *dst, pixman_region32_t *src,
float scale);
+/**
+ * Applies a transform to a region inside a box of size `width` x `height`.
+ */
+void wlr_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
+ enum wl_output_transform transform, int width, int height);
+
#endif
diff --git a/rootston/output.c b/rootston/output.c
index 5f08edf1..c6341b6a 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -170,6 +170,39 @@ static bool surface_intersect_output(struct wlr_surface *surface,
return wlr_output_layout_intersects(output_layout, wlr_output, &layout_box);
}
+static void output_get_transformed_size(struct wlr_output *wlr_output,
+ int *width, int *height) {
+ if (wlr_output->transform % 2 == 0) {
+ *width = wlr_output->width;
+ *height = wlr_output->height;
+ } else {
+ *width = wlr_output->height;
+ *height = wlr_output->width;
+ }
+}
+
+static void scissor_output(struct roots_output *output, pixman_box32_t *rect) {
+ struct wlr_output *wlr_output = output->wlr_output;
+
+ struct wlr_box box = {
+ .x = rect->x1,
+ .y = rect->y1,
+ .width = rect->x2 - rect->x1,
+ .height = rect->y2 - rect->y1,
+ };
+
+ int ow, oh;
+ output_get_transformed_size(output->wlr_output, &ow, &oh);
+
+ // Scissor is in renderer coordinates, ie. upside down
+ enum wl_output_transform transform = wlr_output_transform_compose(
+ wlr_output_transform_invert(wlr_output->transform),
+ WL_OUTPUT_TRANSFORM_FLIPPED_180);
+ wlr_box_transform(&box, transform, ow, oh, &box);
+
+ wlr_renderer_scissor(output->desktop->server->renderer, &box);
+}
+
static void render_surface(struct wlr_surface *surface, double lx, double ly,
float rotation, void *_data) {
struct render_data *data = _data;
@@ -187,7 +220,6 @@ static void render_surface(struct wlr_surface *surface, double lx, double ly,
return;
}
- // TODO: output transform support
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_union_rect(&damage, &damage, box.x, box.y,
@@ -205,16 +237,9 @@ static void render_surface(struct wlr_surface *surface, double lx, double ly,
&output->wlr_output->transform_matrix);
int nrects;
- pixman_box32_t *rects =
- pixman_region32_rectangles(&damage, &nrects);
+ pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
- struct wlr_box scissor = {
- .x = rects[i].x1,
- .y = output->wlr_output->height - rects[i].y2,
- .width = rects[i].x2 - rects[i].x1,
- .height = rects[i].y2 - rects[i].y1,
- };
- wlr_renderer_scissor(output->desktop->server->renderer, &scissor);
+ scissor_output(output, &rects[i]);
wlr_render_with_matrix(output->desktop->server->renderer,
surface->texture, &matrix);
}
@@ -258,7 +283,6 @@ static void render_decorations(struct roots_view *view,
struct wlr_box box;
get_decoration_box(view, output, &box);
- // TODO: output transform support
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_union_rect(&damage, &damage, box.x, box.y,
@@ -278,13 +302,7 @@ static void render_decorations(struct roots_view *view,
pixman_box32_t *rects =
pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
- struct wlr_box scissor = {
- .x = rects[i].x1,
- .y = output->wlr_output->height - rects[i].y2,
- .width = rects[i].x2 - rects[i].x1,
- .height = rects[i].y2 - rects[i].y1,
- };
- wlr_renderer_scissor(output->desktop->server->renderer, &scissor);
+ scissor_output(output, &rects[i]);
wlr_render_colored_quad(output->desktop->server->renderer, &color,
&matrix);
}
@@ -359,13 +377,15 @@ static void render_output(struct roots_output *output) {
int buffer_age = -1;
wlr_output_make_current(wlr_output, &buffer_age);
+ int width, height;
+ output_get_transformed_size(output->wlr_output, &width, &height);
+
// Check if we can use damage tracking
pixman_region32_t damage;
pixman_region32_init(&damage);
if (buffer_age <= 0 || buffer_age - 1 > ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN) {
// Buffer new or too old, damage the whole output
- pixman_region32_union_rect(&damage, &damage, 0, 0,
- wlr_output->width, wlr_output->height);
+ pixman_region32_union_rect(&damage, &damage, 0, 0, width, height);
} else {
pixman_region32_copy(&damage, &output->damage);
@@ -376,8 +396,7 @@ static void render_output(struct roots_output *output) {
pixman_region32_union(&damage, &damage, &output->previous_damage[j]);
}
}
- pixman_region32_intersect_rect(&damage, &damage, 0, 0,
- wlr_output->width, wlr_output->height);
+ pixman_region32_intersect_rect(&damage, &damage, 0, 0, width, height);
if (!pixman_region32_not_empty(&damage) && !wlr_output->needs_swap) {
// Output doesn't need swap and isn't damaged, skip rendering completely
@@ -401,13 +420,7 @@ static void render_output(struct roots_output *output) {
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
- struct wlr_box scissor = {
- .x = rects[i].x1,
- .y = wlr_output->height - rects[i].y2,
- .width = rects[i].x2 - rects[i].x1,
- .height = rects[i].y2 - rects[i].y1,
- };
- wlr_renderer_scissor(output->desktop->server->renderer, &scissor);
+ scissor_output(output, &rects[i]);
wlr_renderer_clear(output->desktop->server->renderer,
clear_color[0], clear_color[1], clear_color[2], 1);
}
@@ -491,8 +504,11 @@ static void schedule_render(struct roots_output *output) {
}
static void output_damage_whole(struct roots_output *output) {
- pixman_region32_union_rect(&output->damage, &output->damage,
- 0, 0, output->wlr_output->width, output->wlr_output->height);
+ int width, height;
+ output_get_transformed_size(output->wlr_output, &width, &height);
+
+ pixman_region32_union_rect(&output->damage, &output->damage, 0, 0,
+ width, height);
schedule_render(output);
}
@@ -584,7 +600,6 @@ static void damage_from_surface(struct wlr_surface *surface,
return;
}
- // TODO: output transform support
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_copy(&damage, &surface->current->surface_damage);
diff --git a/types/wlr_box.c b/types/wlr_box.c
index 9afd7ef0..3217a7d0 100644
--- a/types/wlr_box.c
+++ b/types/wlr_box.c
@@ -67,47 +67,50 @@ bool wlr_box_contains_point(const struct wlr_box *box, double x, double y) {
}
void wlr_box_transform(const struct wlr_box *box,
- enum wl_output_transform transform, struct wlr_box *dest) {
+ enum wl_output_transform transform, int width, int height,
+ struct wlr_box *dest) {
+ struct wlr_box src = *box;
+
if (transform % 2 == 0) {
- dest->width = box->width;
- dest->height = box->height;
+ dest->width = src.width;
+ dest->height = src.height;
} else {
- dest->width = box->height;
- dest->height = box->width;
+ dest->width = src.height;
+ dest->height = src.width;
}
switch (transform) {
case WL_OUTPUT_TRANSFORM_NORMAL:
- dest->x = box->x;
- dest->y = box->y;
+ dest->x = src.x;
+ dest->y = src.y;
break;
case WL_OUTPUT_TRANSFORM_90:
- dest->x = box->y;
- dest->y = box->width - box->x;
+ dest->x = src.y;
+ dest->y = width - src.x - src.width;
break;
case WL_OUTPUT_TRANSFORM_180:
- dest->x = box->width - box->x;
- dest->y = box->height - box->y;
+ dest->x = width - src.x - src.width;
+ dest->y = height - src.y - src.height;
break;
case WL_OUTPUT_TRANSFORM_270:
- dest->x = box->height - box->y;
- dest->y = box->x;
+ dest->x = height - src.y - src.height;
+ dest->y = src.x;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED:
- dest->x = box->width - box->x;
- dest->y = box->y;
+ dest->x = width - src.x - src.width;
+ dest->y = src.y;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- dest->x = box->height - box->y;
- dest->y = box->width - box->x;
+ dest->x = height - src.y - src.height;
+ dest->y = width - src.x - src.width;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- dest->x = box->x;
- dest->y = box->height - box->y;
+ dest->x = src.x;
+ dest->y = height - src.y - src.height;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- dest->x = box->y;
- dest->y = box->x;
+ dest->x = src.y;
+ dest->y = src.x;
break;
}
}
diff --git a/types/wlr_output.c b/types/wlr_output.c
index a6dc7f1b..f23f1749 100644
--- a/types/wlr_output.c
+++ b/types/wlr_output.c
@@ -14,6 +14,7 @@
#include <wlr/render/matrix.h>
#include <wlr/render/gles2.h>
#include <wlr/render.h>
+#include <wlr/util/region.h>
static void wl_output_send_to_resource(struct wl_resource *resource) {
assert(resource);
@@ -554,6 +555,7 @@ static void output_fullscreen_surface_handle_commit(
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_copy(&damage, &surface->current->surface_damage);
+ wlr_region_scale(&damage, &damage, output->scale);
pixman_region32_translate(&damage, box.x, box.y);
pixman_region32_union(&output->damage, &output->damage, &damage);
pixman_region32_fini(&damage);
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 9896fe1b..abe830f4 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <wayland-server.h>
#include <wlr/util/log.h>
+#include <wlr/util/region.h>
#include <wlr/render/interface.h>
#include <wlr/types/wlr_surface.h>
#include <wlr/render/egl.h>
@@ -185,85 +186,6 @@ static bool wlr_surface_update_size(struct wlr_surface *surface,
return update_damage;
}
-static void wlr_surface_to_buffer_region(int scale,
- enum wl_output_transform transform, pixman_region32_t *surface_region,
- pixman_region32_t *buffer_region, int width, int height) {
- int nrects;
- pixman_box32_t *src_rects =
- pixman_region32_rectangles(surface_region, &nrects);
- pixman_box32_t *dest_rects = malloc(nrects * sizeof(*dest_rects));
- if (dest_rects == NULL) {
- return;
- }
-
- for (int 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 (int 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_fini(buffer_region);
- pixman_region32_init_rects(buffer_region, dest_rects, nrects);
- free(dest_rects);
-}
-
/**
* Append pending state to current state and clear pending state.
*/
@@ -314,9 +236,11 @@ static void wlr_surface_move_state(struct wlr_surface *surface,
if (update_damage) {
pixman_region32_t buffer_damage;
pixman_region32_init(&buffer_damage);
- wlr_surface_to_buffer_region(state->scale, state->transform,
- &state->surface_damage, &buffer_damage, state->width,
- state->height);
+ pixman_region32_copy(&buffer_damage, &state->surface_damage);
+ wlr_region_transform(&buffer_damage, &buffer_damage,
+ wlr_output_transform_invert(state->transform),
+ state->width, state->height);
+ wlr_region_scale(&buffer_damage, &buffer_damage, state->scale);
pixman_region32_union(&state->buffer_damage,
&state->buffer_damage, &buffer_damage);
pixman_region32_fini(&buffer_damage);
diff --git a/util/meson.build b/util/meson.build
index 6796f818..34aa428b 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -6,5 +6,5 @@ lib_wlr_util = static_library(
'region.c',
),
include_directories: wlr_inc,
- dependencies: [pixman],
+ dependencies: [wayland_server, pixman],
)
diff --git a/util/region.c b/util/region.c
index da66d92c..9c4712f9 100644
--- a/util/region.c
+++ b/util/region.c
@@ -26,4 +26,78 @@ void wlr_region_scale(pixman_region32_t *dst, pixman_region32_t *src,
pixman_region32_fini(dst);
pixman_region32_init_rects(dst, dst_rects, nrects);
+ free(dst_rects);
+}
+
+void wlr_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
+ enum wl_output_transform transform, int width, int height) {
+ if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
+ 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) {
+ switch (transform) {
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ dst_rects[i].x1 = src_rects[i].x1;
+ dst_rects[i].y1 = src_rects[i].y1;
+ dst_rects[i].x2 = src_rects[i].x2;
+ dst_rects[i].y2 = src_rects[i].y2;
+ break;
+ case WL_OUTPUT_TRANSFORM_90:
+ dst_rects[i].x1 = src_rects[i].y1;
+ dst_rects[i].y1 = width - src_rects[i].x2;
+ dst_rects[i].x2 = src_rects[i].y2;
+ dst_rects[i].y2 = width - src_rects[i].x1;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ dst_rects[i].x1 = width - src_rects[i].x2;
+ dst_rects[i].y1 = height - src_rects[i].y2;
+ dst_rects[i].x2 = width - src_rects[i].x1;
+ dst_rects[i].y2 = height - src_rects[i].y1;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ dst_rects[i].x1 = height - src_rects[i].y2;
+ dst_rects[i].y1 = src_rects[i].x1;
+ dst_rects[i].x2 = height - src_rects[i].y1;
+ dst_rects[i].y2 = src_rects[i].x2;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ dst_rects[i].x1 = width - src_rects[i].x2;
+ dst_rects[i].y1 = src_rects[i].y1;
+ dst_rects[i].x2 = width - src_rects[i].x1;
+ dst_rects[i].y2 = src_rects[i].y2;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ dst_rects[i].x1 = height - src_rects[i].y2;
+ dst_rects[i].y1 = width - src_rects[i].x2;
+ dst_rects[i].x2 = height - src_rects[i].y1;
+ dst_rects[i].y2 = width - src_rects[i].x1;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ dst_rects[i].x1 = src_rects[i].x1;
+ dst_rects[i].y1 = height - src_rects[i].y2;
+ dst_rects[i].x2 = src_rects[i].x2;
+ dst_rects[i].y2 = height - src_rects[i].y1;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ dst_rects[i].x1 = src_rects[i].y1;
+ dst_rects[i].y1 = src_rects[i].x1;
+ dst_rects[i].x2 = src_rects[i].y2;
+ dst_rects[i].y2 = src_rects[i].x2;
+ break;
+ }
+ }
+
+ pixman_region32_fini(dst);
+ pixman_region32_init_rects(dst, dst_rects, nrects);
+ free(dst_rects);
}