[PATCH weston 05/12] compositor, clients: double-buffer opaque region

Pekka Paalanen ppaalanen at gmail.com
Wed Oct 10 02:49:27 PDT 2012


Make wl_surface.set_opaque_region double-buffered as required by the new
protocol. Also, do not reset the opaque region on surface size changes
anymore. Only explicit requests from the client will change the region
now.

In clients, make sure commit happens after setting the opaque region.

Mesa does not need a fix, as it never touches the opaque region.

Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
 clients/simple-egl.c |    4 ++--
 clients/window.c     |   14 +++++++-------
 src/compositor.c     |   26 ++++++++++++++------------
 src/compositor.h     |    3 +++
 4 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/clients/simple-egl.c b/clients/simple-egl.c
index d6842af..2150a41 100644
--- a/clients/simple-egl.c
+++ b/clients/simple-egl.c
@@ -401,8 +401,6 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
 	glDisableVertexAttribArray(window->gl.pos);
 	glDisableVertexAttribArray(window->gl.col);
 
-	eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
-
 	if (window->opaque || window->fullscreen) {
 		region = wl_compositor_create_region(window->display->compositor);
 		wl_region_add(region, 0, 0,
@@ -412,6 +410,8 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
 		wl_region_destroy(region);
 	}
 
+	eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
+
 	window->callback = wl_surface_frame(window->surface);
 	wl_callback_add_listener(window->callback, &frame_listener, window);
 }
diff --git a/clients/window.c b/clients/window.c
index 24bd0c4..4a1ab86 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -819,6 +819,13 @@ window_attach_surface(struct window *window)
 			wl_shell_surface_set_toplevel(window->shell_surface);
 	}
 
+	if (window->opaque_region) {
+		wl_surface_set_opaque_region(window->surface,
+					     window->opaque_region);
+		wl_region_destroy(window->opaque_region);
+		window->opaque_region = NULL;
+	}
+
 	switch (window->buffer_type) {
 #ifdef HAVE_CAIRO_EGL
 	case WINDOW_BUFFER_TYPE_EGL_WINDOW:
@@ -856,13 +863,6 @@ window_attach_surface(struct window *window)
 		wl_region_destroy(window->input_region);
 		window->input_region = NULL;
 	}
-
-	if (window->opaque_region) {
-		wl_surface_set_opaque_region(window->surface,
-					     window->opaque_region);
-		wl_region_destroy(window->opaque_region);
-		window->opaque_region = NULL;
-	}
 }
 
 int
diff --git a/src/compositor.c b/src/compositor.c
index b17a1b3..4fea23a 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -275,6 +275,7 @@ weston_surface_create(struct weston_compositor *compositor)
 	surface->pending.buffer_destroy_listener.notify =
 		surface_handle_pending_buffer_destroy;
 	pixman_region32_init(&surface->pending.damage);
+	pixman_region32_init(&surface->pending.opaque);
 
 	return surface;
 }
@@ -781,6 +782,7 @@ destroy_surface(struct wl_resource *resource)
 	if (weston_surface_is_mapped(surface))
 		weston_surface_unmap(surface);
 
+	pixman_region32_fini(&surface->pending.opaque);
 	pixman_region32_fini(&surface->pending.damage);
 
 	if (surface->pending.buffer)
@@ -831,8 +833,6 @@ weston_surface_attach(struct weston_surface *surface, struct wl_buffer *buffer)
 		if (surface->geometry.width != buffer->width ||
 		    surface->geometry.height != buffer->height) {
 			undef_region(&surface->input);
-			pixman_region32_fini(&surface->opaque);
-			pixman_region32_init(&surface->opaque);
 		}
 	} else {
 		if (weston_surface_is_mapped(surface))
@@ -1216,20 +1216,13 @@ surface_set_opaque_region(struct wl_client *client,
 	struct weston_surface *surface = resource->data;
 	struct weston_region *region;
 
-	pixman_region32_fini(&surface->opaque);
-
 	if (region_resource) {
 		region = region_resource->data;
-		pixman_region32_init_rect(&surface->opaque, 0, 0,
-					  surface->geometry.width,
-					  surface->geometry.height);
-		pixman_region32_intersect(&surface->opaque,
-					  &surface->opaque, &region->region);
+		pixman_region32_copy(&surface->pending.opaque,
+				     &region->region);
 	} else {
-		pixman_region32_init(&surface->opaque);
+		empty_region(&surface->pending.opaque);
 	}
-
-	surface->geometry.dirty = 1;
 }
 
 static void
@@ -1274,6 +1267,15 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
 			      &surface->pending.damage);
 	empty_region(&surface->pending.damage);
 	weston_surface_schedule_repaint(surface);
+
+	/* wl_surface.set_opaque_region */
+	pixman_region32_fini(&surface->opaque);
+	pixman_region32_init_rect(&surface->opaque, 0, 0,
+				  surface->geometry.width,
+				  surface->geometry.height);
+	pixman_region32_intersect(&surface->opaque,
+				  &surface->opaque, &surface->pending.opaque);
+	surface->geometry.dirty = 1;
 }
 
 static const struct wl_surface_interface surface_interface = {
diff --git a/src/compositor.h b/src/compositor.h
index 61fcdee..f30d635 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -477,6 +477,9 @@ struct weston_surface {
 
 		/* wl_surface.damage */
 		pixman_region32_t damage;
+
+		/* wl_surface.set_opaque_region */
+		pixman_region32_t opaque;
 	} pending;
 
 	/*
-- 
1.7.8.6



More information about the wayland-devel mailing list