compositor, clients: double-buffer opaque region
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@gmail.com>
diff --git a/clients/simple-egl.c b/clients/simple-egl.c
index f956c81..42c22b0 100644
--- a/clients/simple-egl.c
+++ b/clients/simple-egl.c
@@ -401,8 +401,6 @@
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 @@
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 b2ad73a..973b210 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -830,6 +830,13 @@
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:
@@ -867,13 +874,6 @@
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 @@
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 @@
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 @@
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 @@
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, ®ion->region);
+ pixman_region32_copy(&surface->pending.opaque,
+ ®ion->region);
} else {
- pixman_region32_init(&surface->opaque);
+ empty_region(&surface->pending.opaque);
}
-
- surface->geometry.dirty = 1;
}
static void
@@ -1274,6 +1267,15 @@
&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 @@
/* wl_surface.damage */
pixman_region32_t damage;
+
+ /* wl_surface.set_opaque_region */
+ pixman_region32_t opaque;
} pending;
/*