aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-01-22 10:34:23 +0100
committeremersion <contact@emersion.fr>2018-01-22 10:34:23 +0100
commita8cb02f585dcee9d72beb97c8fc78e2e63d6ac2d (patch)
tree36f0895e96c21b4d14eb1024de06577cece858a2
parent59c53e8333cae17210832fb79514c4d0110c7de8 (diff)
surface: add damage when subsurface moves
-rw-r--r--types/wlr_surface.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 36dfc63d..9896fe1b 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -272,6 +272,9 @@ static void wlr_surface_move_state(struct wlr_surface *surface,
bool update_damage = false;
bool update_size = false;
+ int oldw = state->width;
+ int oldh = state->height;
+
if ((next->invalid & WLR_SURFACE_INVALID_SCALE)) {
state->scale = next->scale;
update_size = true;
@@ -327,13 +330,25 @@ static void wlr_surface_move_state(struct wlr_surface *surface,
pixman_region32_copy(&state->input, &next->input);
}
if ((next->invalid & WLR_SURFACE_INVALID_SUBSURFACE_POSITION)) {
+ // Subsurface has moved
+ int dx = state->subsurface_position.x - next->subsurface_position.x;
+ int dy = state->subsurface_position.y - next->subsurface_position.y;
+
state->subsurface_position.x = next->subsurface_position.x;
state->subsurface_position.y = next->subsurface_position.y;
next->subsurface_position.x = 0;
next->subsurface_position.y = 0;
+
+ if (dx != 0 || dy != 0) {
+ pixman_region32_union_rect(&state->surface_damage,
+ &state->surface_damage, dx, dy, oldw, oldh);
+ pixman_region32_union_rect(&state->surface_damage,
+ &state->surface_damage, 0, 0, state->width, state->height);
+ }
}
if ((next->invalid & WLR_SURFACE_INVALID_FRAME_CALLBACK_LIST)) {
- wl_list_insert_list(&state->frame_callback_list, &next->frame_callback_list);
+ wl_list_insert_list(&state->frame_callback_list,
+ &next->frame_callback_list);
wl_list_init(&next->frame_callback_list);
}
@@ -381,10 +396,12 @@ static void wlr_surface_apply_damage(struct wlr_surface *surface,
if (reupload_buffer) {
wlr_texture_upload_shm(surface->texture, format, buffer);
} else {
- pixman_region32_t damage = surface->current->buffer_damage;
- if (!pixman_region32_not_empty(&damage)) {
- goto release;
- }
+ pixman_region32_t damage;
+ pixman_region32_init(&damage);
+ pixman_region32_copy(&damage, &surface->current->buffer_damage);
+ pixman_region32_intersect_rect(&damage, &damage, 0, 0,
+ surface->current->buffer_width, surface->current->buffer_height);
+
int n;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &n);
for (int i = 0; i < n; ++i) {
@@ -397,6 +414,8 @@ static void wlr_surface_apply_damage(struct wlr_surface *surface,
break;
}
}
+
+ pixman_region32_fini(&damage);
}
release: