From 512dde8ce9723fe98e715ad6fe0a4f04eefd7394 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 10 Oct 2012 12:49:27 +0300 Subject: [PATCH] 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 --- 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 f956c811..42c22b0a 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 b2ad73a6..973b2106 100644 --- a/clients/window.c +++ b/clients/window.c @@ -830,6 +830,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: @@ -867,13 +874,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 b17a1b31..4fea23a5 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, ®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_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 61fcdee7..f30d6352 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; /*