Damage tracking for transformed outputs

This commit is contained in:
emersion 2018-01-26 22:11:09 +01:00
parent a98ece68d3
commit ece2c1e4e2
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
12 changed files with 185 additions and 154 deletions

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);