compositor: damage pending subsurfaces when committing them
authorEmilio Pozuelo Monfort <pochu27@gmail.com>
Fri, 27 Jan 2017 16:30:29 +0000 (17:30 +0100)
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>
Tue, 7 Feb 2017 12:25:27 +0000 (14:25 +0200)
When a client changes the subsurfaces state, we need to damage
them so the result is visible. We do that by flagging the surfaces
when the state changes and causing damage when committing the
state. This prevents normal repaints from considering these changes
until a commit has happened, and allows the client to atomically
schedule several changes.

This fixes the subsurface_z_order test, which is now marked as expected
to succeed.

Signed-off-by: Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Micah Fedke <micah.fedke@collabora.co.uk>
libweston/compositor.c
libweston/compositor.h
tests/subsurface-shot-test.c

index 8d6175e..9ded23f 100644 (file)
@@ -2179,6 +2179,12 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,
        }
 }
 
+/* This recursively adds the sub-surfaces for a view, relying on the
+ * sub-surface order. Thus, if a client restacks the sub-surfaces, that
+ * change first happens to the sub-surface list, and then automatically
+ * propagates here. See weston_surface_damage_subsurfaces() for how the
+ * sub-surfaces receive damage when the client changes the state.
+ */
 static void
 view_list_add(struct weston_compositor *compositor,
              struct weston_view *view)
@@ -2682,6 +2688,24 @@ surface_set_input_region(struct wl_client *client,
        }
 }
 
+/* Cause damage to this sub-surface and all its children.
+ *
+ * This is useful when there are state changes that need an implicit
+ * damage, e.g. a z-order change.
+ */
+static void
+weston_surface_damage_subsurfaces(struct weston_subsurface *sub)
+{
+       struct weston_subsurface *child;
+
+       weston_surface_damage(sub->surface);
+       sub->reordered = false;
+
+       wl_list_for_each(child, &sub->surface->subsurface_list, parent_link)
+               if (child != sub)
+                       weston_surface_damage_subsurfaces(child);
+}
+
 static void
 weston_surface_commit_subsurface_order(struct weston_surface *surface)
 {
@@ -2691,6 +2715,9 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface)
                                 parent_link_pending) {
                wl_list_remove(&sub->parent_link);
                wl_list_insert(&surface->subsurface_list, &sub->parent_link);
+
+               if (sub->reordered)
+                       weston_surface_damage_subsurfaces(sub);
        }
 }
 
@@ -3640,6 +3667,8 @@ subsurface_place_above(struct wl_client *client,
        wl_list_remove(&sub->parent_link_pending);
        wl_list_insert(sibling->parent_link_pending.prev,
                       &sub->parent_link_pending);
+
+       sub->reordered = true;
 }
 
 static void
@@ -3662,6 +3691,8 @@ subsurface_place_below(struct wl_client *client,
        wl_list_remove(&sub->parent_link_pending);
        wl_list_insert(&sibling->parent_link_pending,
                       &sub->parent_link_pending);
+
+       sub->reordered = true;
 }
 
 static void
index b049c98..08e728a 100644 (file)
@@ -1235,6 +1235,9 @@ struct weston_subsurface {
        struct weston_surface_state cached;
        struct weston_buffer_reference cached_buffer_ref;
 
+       /* Sub-surface has been reordered; need to apply damage. */
+       bool reordered;
+
        int synchronized;
 
        /* Used for constructing the view tree */
index 8e4f7c1..10415ec 100644 (file)
@@ -174,7 +174,7 @@ surface_commit_color(struct client *client, struct wl_surface *surface,
        return buf;
 }
 
-FAIL_TEST(subsurface_z_order)
+TEST(subsurface_z_order)
 {
        const char *test_name = get_test_name();
        struct client *client;