[PATCH weston] compositor: Fix partial repaints
Ander Conselvan de Oliveira
ander.conselvan.de.oliveira at intel.com
Tue Oct 30 08:44:01 PDT 2012
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.
---
src/compositor.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c
index 3597cf7..56474a5 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -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);
--
1.7.10.4
More information about the wayland-devel
mailing list