compositor: Fix partial repaints

Partial repaints have been broken since the introduction of the atomic
surface updates. The problem was that surface_commit would set the
geometry dirty flag unconditionally, causing transform updates on every
frame which would in turn cause weston_surface_damage_below() to damage
the whole surface area.

This patch changes this so that flag is only set if the pending buffer
has a different size, the location of the surface changed or the opaque
region changed.

Note that changing the opaque region will cause a full repaint of the
affected surface, because of the transform update.

https://bugs.freedesktop.org/show_bug.cgi?id=56538
This commit is contained in:
Ander Conselvan de Oliveira 2012-10-30 17:44:01 +02:00 committed by Kristian Høgsberg
parent d2fbb3870c
commit 5df8ecac5d
1 changed files with 17 additions and 5 deletions

View File

@ -1234,6 +1234,13 @@ static void
surface_commit(struct wl_client *client, struct wl_resource *resource)
{
struct weston_surface *surface = resource->data;
pixman_region32_t opaque;
if (surface->pending.sx || surface->pending.sy ||
(surface->pending.buffer &&
(surface->pending.buffer->width != surface->geometry.width ||
surface->pending.buffer->height != surface->geometry.height)))
surface->geometry.dirty = 1;
/* wl_surface.attach */
if (surface->pending.buffer || surface->pending.remove_contents)
@ -1249,13 +1256,18 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
empty_region(&surface->pending.damage);
/* wl_surface.set_opaque_region */
pixman_region32_fini(&surface->opaque);
pixman_region32_init_rect(&surface->opaque, 0, 0,
pixman_region32_init_rect(&opaque, 0, 0,
surface->geometry.width,
surface->geometry.height);
pixman_region32_intersect(&surface->opaque,
&surface->opaque, &surface->pending.opaque);
surface->geometry.dirty = 1;
pixman_region32_intersect(&opaque,
&opaque, &surface->pending.opaque);
if (!pixman_region32_equal(&opaque, &surface->opaque)) {
pixman_region32_copy(&surface->opaque, &opaque);
surface->geometry.dirty = 1;
}
pixman_region32_fini(&opaque);
/* wl_surface.set_input_region */
pixman_region32_fini(&surface->input);