window: destroy the 2nd shm buffer, if both released
authorPekka Paalanen <ppaalanen@gmail.com>
Wed, 13 Feb 2013 14:17:12 +0000 (16:17 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 14 Feb 2013 17:28:42 +0000 (12:28 -0500)
Handle the case when we the compositor somehow migrates from requiring
double buffering into working on single buffering, so we release the
extra shm buffer.

Currently, I do not think this can happen in practice, but in the future
it may happen with sub-surfaces.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
clients/window.c

index 79f9b0e..ef40c7b 100644 (file)
@@ -807,6 +807,8 @@ shm_surface_leaf_release(struct shm_surface_leaf *leaf)
 
        if (leaf->resize_pool)
                shm_pool_destroy(leaf->resize_pool);
+
+       memset(leaf, 0, sizeof *leaf);
 }
 
 struct shm_surface {
@@ -829,17 +831,17 @@ to_shm_surface(struct toysurface *base)
 static void
 shm_surface_buffer_release(void *data, struct wl_buffer *buffer)
 {
-       struct shm_surface_leaf *leaf = data;
+       struct shm_surface *surface = data;
 
-       leaf->busy = 0;
+       if (surface->leaf[0].data->buffer == buffer)
+               surface->leaf[0].busy = 0;
+       else if (surface->leaf[1].data->buffer == buffer)
+               surface->leaf[1].busy = 0;
+       else
+               assert(0 && "shm_surface_buffer_release: unknown buffer");
 
-       /* If both leaves are now free, we should call
-        * shm_surface_leaf_release(shm_surface::leaf[1]).
-        * However, none of Weston's backends switch dynamically
-        * between early buffer release and requiring double-buffering,
-        * so if both leaves are free, we never used the second
-        * leaf to begin with.
-        */
+       if (!surface->leaf[0].busy && !surface->leaf[1].busy)
+               shm_surface_leaf_release(&surface->leaf[1]);
 }
 
 static const struct wl_buffer_listener shm_surface_buffer_listener = {
@@ -908,7 +910,7 @@ shm_surface_prepare(struct toysurface *base, int dx, int dy,
                                           leaf->resize_pool,
                                           &leaf->data);
        wl_buffer_add_listener(leaf->data->buffer,
-                              &shm_surface_buffer_listener, leaf);
+                              &shm_surface_buffer_listener, surface);
 
 out:
        surface->current = leaf;