[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