protocol: set_desync should flush
authorPekka Paalanen <ppaalanen@gmail.com>
Fri, 17 May 2013 13:46:05 +0000 (16:46 +0300)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 17 May 2013 20:21:50 +0000 (16:21 -0400)
wl_subsurface.set_desync should apply the cached wl_surface state.
Otherwise, the sub-surface may be stuck: a commit on the parent surface,
if desynchronized, will not commit the sub-surface because it is
desynchronized, too. A commit on the sub-surface may not happen, if it
is waiting for the frame callback from the previous commit.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
protocol/subsurface.xml
src/compositor.c

index 60b4002..8db0495 100644 (file)
        Note: even if a sub-surface is set to desynchronized, a parent
        sub-surface may override it to behave as synchronized. For details,
        see wl_subsurface.
+
+       If a surface's parent surface behaves as desynchronized, then
+       the cached state is applied on set_desync.
       </description>
     </request>
 
index 89b9cef..ed250ba 100644 (file)
@@ -1851,21 +1851,11 @@ weston_subsurface_commit(struct weston_subsurface *sub)
 }
 
 static void
-weston_subsurface_parent_commit(struct weston_subsurface *sub,
-                               int parent_is_synchronized)
+weston_subsurface_synchronized_commit(struct weston_subsurface *sub)
 {
        struct weston_surface *surface = sub->surface;
        struct weston_subsurface *tmp;
 
-       if (sub->position.set) {
-               weston_surface_set_position(sub->surface,
-                                           sub->position.x, sub->position.y);
-               sub->position.set = 0;
-       }
-
-       if (!parent_is_synchronized && !sub->synchronized)
-               return;
-
        /* From now on, commit_from_cache the whole sub-tree, regardless of
         * the synchronized mode of each child. This sub-surface or some
         * of its ancestors were synchronized, so we are synchronized
@@ -1882,6 +1872,20 @@ weston_subsurface_parent_commit(struct weston_subsurface *sub,
 }
 
 static void
+weston_subsurface_parent_commit(struct weston_subsurface *sub,
+                               int parent_is_synchronized)
+{
+       if (sub->position.set) {
+               weston_surface_set_position(sub->surface,
+                                           sub->position.x, sub->position.y);
+               sub->position.set = 0;
+       }
+
+       if (parent_is_synchronized || sub->synchronized)
+               weston_subsurface_synchronized_commit(sub);
+}
+
+static void
 subsurface_configure(struct weston_surface *surface, int32_t dx, int32_t dy,
                     int32_t width, int32_t height)
 {
@@ -2050,8 +2054,13 @@ subsurface_set_desync(struct wl_client *client, struct wl_resource *resource)
 {
        struct weston_subsurface *sub = resource->data;
 
-       if (sub)
+       if (sub && sub->synchronized) {
                sub->synchronized = 0;
+
+               /* If sub became effectively desynchronized, flush. */
+               if (!weston_subsurface_is_synchronized(sub))
+                       weston_subsurface_synchronized_commit(sub);
+       }
 }
 
 static void