diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index ef789b82..6177e059 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -17,14 +17,14 @@ #include enum wlr_surface_state_field { - WLR_SURFACE_STATE_BUFFER = 1, - WLR_SURFACE_STATE_SURFACE_DAMAGE = 2, - WLR_SURFACE_STATE_BUFFER_DAMAGE = 4, - WLR_SURFACE_STATE_OPAQUE_REGION = 8, - WLR_SURFACE_STATE_INPUT_REGION = 16, - WLR_SURFACE_STATE_TRANSFORM = 32, - WLR_SURFACE_STATE_SCALE = 64, - WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 128, + WLR_SURFACE_STATE_BUFFER = 1 << 0, + WLR_SURFACE_STATE_SURFACE_DAMAGE = 1 << 1, + WLR_SURFACE_STATE_BUFFER_DAMAGE = 1 << 2, + WLR_SURFACE_STATE_OPAQUE_REGION = 1 << 3, + WLR_SURFACE_STATE_INPUT_REGION = 1 << 4, + WLR_SURFACE_STATE_TRANSFORM = 1 << 5, + WLR_SURFACE_STATE_SCALE = 1 << 6, + WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7, }; struct wlr_surface_state { @@ -32,7 +32,7 @@ struct wlr_surface_state { struct wl_resource *buffer_resource; int32_t dx, dy; // relative to previous position - pixman_region32_t surface_damage, buffer_damage; + pixman_region32_t surface_damage, buffer_damage; // clipped to bounds pixman_region32_t opaque, input; enum wl_output_transform transform; int32_t scale; @@ -68,11 +68,12 @@ struct wlr_surface { * The last commit's buffer damage, in buffer-local coordinates. This * contains both the damage accumulated by the client via * `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`. - * If the buffer has changed its size or moved, the whole buffer is - * damaged. + * If the buffer has been resized, the whole buffer is damaged. * * This region needs to be scaled and transformed into output coordinates, - * just like the buffer's texture. + * just like the buffer's texture. In addition, if the buffer has shrunk the + * old size needs to be damaged and if the buffer has moved the old and new + * positions need to be damaged. */ pixman_region32_t buffer_damage; /** diff --git a/rootston/output.c b/rootston/output.c index d7c5d821..674cda2d 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -700,8 +700,7 @@ static void damage_from_surface(struct wlr_surface *surface, int sx, int sy, pixman_region32_init(&damage); wlr_surface_get_effective_damage(surface, &damage); - wlr_region_scale(&damage, &damage, - wlr_output->scale / (float)surface->current.scale); + wlr_region_scale(&damage, &damage, wlr_output->scale); if (ceil(wlr_output->scale) > surface->current.scale) { // When scaling up a surface, it'll become blurry so we need to // expand the damage region diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 4eb643ba..12931dad 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -183,16 +183,15 @@ static void surface_update_damage(pixman_region32_t *buffer_damage, pixman_region32_t surface_damage; pixman_region32_init(&surface_damage); - pixman_region32_union(buffer_damage, buffer_damage, - &pending->buffer_damage); pixman_region32_copy(&surface_damage, &pending->surface_damage); - wlr_region_transform(&surface_damage, &surface_damage, wlr_output_transform_invert(pending->transform), pending->width, pending->height); wlr_region_scale(&surface_damage, &surface_damage, pending->scale); - pixman_region32_union(buffer_damage, buffer_damage, &surface_damage); + pixman_region32_union(buffer_damage, + &pending->buffer_damage, &surface_damage); + pixman_region32_fini(&surface_damage); } } @@ -291,8 +290,8 @@ static void surface_apply_damage(struct wlr_surface *surface) { } if (surface->buffer != NULL && surface->buffer->released) { - struct wlr_buffer *updated_buffer = - wlr_buffer_apply_damage(surface->buffer, resource, &surface->buffer_damage); + struct wlr_buffer *updated_buffer = wlr_buffer_apply_damage( + surface->buffer, resource, &surface->buffer_damage); if (updated_buffer != NULL) { surface->buffer = updated_buffer; return; @@ -1029,6 +1028,7 @@ void wlr_surface_get_effective_damage(struct wlr_surface *surface, wlr_region_transform(damage, &surface->buffer_damage, surface->current.transform, surface->current.buffer_width, surface->current.buffer_height); + wlr_region_scale(damage, damage, 1.0 / (float)surface->current.scale); // On resize, damage the previous bounds of the surface. The current bounds // have already been damaged in surface_update_damage.