[mutter] wayland/subsurface: Move placement ops to the parents pending state
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] wayland/subsurface: Move placement ops to the parents pending state
- Date: Sun, 14 Mar 2021 00:32:34 +0000 (UTC)
commit ba8499f9ec0ca017f11bcc8e50e66302b2f73aa7
Author: Robert Mader <robert mader posteo de>
Date: Tue Mar 9 22:24:13 2021 +0100
wayland/subsurface: Move placement ops to the parents pending state
Unlike other subsurface state, placement operations need to get
applied in order. As per spec:
```
Requests are handled in order and applied immediately to a pending
state. The final pending state is copied to the active state the
next time the state of the parent surface is applied.
```
Having placement operations being part of the subsurface state
makes it difficult to support arbitrary orderings. Make them
part of the parents surface pending state instead.
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/1691
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1768>
src/wayland/meta-wayland-subsurface.c | 94 +++++++++++------------------------
src/wayland/meta-wayland-subsurface.h | 17 +++++++
src/wayland/meta-wayland-surface.c | 61 +++++++++++++++++++++++
src/wayland/meta-wayland-surface.h | 3 +-
4 files changed, 108 insertions(+), 67 deletions(-)
---
diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c
index 78b23fe649..27bd91f0c6 100644
--- a/src/wayland/meta-wayland-subsurface.c
+++ b/src/wayland/meta-wayland-subsurface.c
@@ -30,19 +30,6 @@
#include "wayland/meta-wayland-surface.h"
#include "wayland/meta-window-wayland.h"
-typedef enum
-{
- META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
- META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW
-} MetaWaylandSubsurfacePlacement;
-
-typedef struct
-{
- MetaWaylandSubsurfacePlacement placement;
- MetaWaylandSurface *sibling;
- struct wl_listener sibling_destroy_listener;
-} MetaWaylandSubsurfacePlacementOp;
-
struct _MetaWaylandSubsurface
{
MetaWaylandActorSurface parent;
@@ -146,57 +133,6 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
surface->sub.pending_pos = FALSE;
}
- if (surface->sub.pending_placement_ops)
- {
- GSList *it;
- MetaWaylandSurface *parent;
-
- parent = surface->sub.parent;
-
- for (it = surface->sub.pending_placement_ops; it; it = it->next)
- {
- MetaWaylandSubsurfacePlacementOp *op = it->data;
- MetaWaylandSurface *sibling;
- GNode *sibling_node;
-
- if (!op->sibling)
- {
- g_free (op);
- continue;
- }
-
- sibling = op->sibling;
- if (is_child (surface, sibling))
- sibling_node = sibling->subsurface_leaf_node;
- else
- sibling_node = sibling->subsurface_branch_node;
-
- g_node_unlink (surface->subsurface_branch_node);
-
- switch (op->placement)
- {
- case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
- g_node_insert_after (parent->subsurface_branch_node,
- sibling_node,
- surface->subsurface_branch_node);
- break;
- case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
- g_node_insert_before (parent->subsurface_branch_node,
- sibling_node,
- surface->subsurface_branch_node);
- break;
- }
-
- wl_list_remove (&op->sibling_destroy_listener.link);
- g_free (op);
- }
-
- g_slist_free (surface->sub.pending_placement_ops);
- surface->sub.pending_placement_ops = NULL;
-
- meta_wayland_surface_notify_subsurface_state_changed (parent);
- }
-
if (is_surface_effectively_synchronized (surface))
meta_wayland_surface_apply_cached_state (surface);
@@ -418,6 +354,16 @@ is_valid_sibling (MetaWaylandSurface *surface,
return FALSE;
}
+static void
+subsurface_handle_pending_surface_destroyed (struct wl_listener *listener,
+ void *data)
+{
+ MetaWaylandSubsurfacePlacementOp *op =
+ wl_container_of (listener, op, surface_destroy_listener);
+
+ op->surface = NULL;
+}
+
static void
subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener,
void *data)
@@ -428,23 +374,39 @@ subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener,
op->sibling = NULL;
}
+void
+meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op)
+{
+ if (op->surface)
+ wl_list_remove (&op->surface_destroy_listener.link);
+ if (op->sibling)
+ wl_list_remove (&op->sibling_destroy_listener.link);
+ g_free (op);
+}
+
static void
queue_subsurface_placement (MetaWaylandSurface *surface,
MetaWaylandSurface *sibling,
MetaWaylandSubsurfacePlacement placement)
{
+ MetaWaylandSurface *parent = surface->sub.parent;
MetaWaylandSubsurfacePlacementOp *op =
g_new0 (MetaWaylandSubsurfacePlacementOp, 1);
op->placement = placement;
+ op->surface = surface;
op->sibling = sibling;
+ op->surface_destroy_listener.notify =
+ subsurface_handle_pending_surface_destroyed;
op->sibling_destroy_listener.notify =
subsurface_handle_pending_sibling_destroyed;
+ wl_resource_add_destroy_listener (surface->resource,
+ &op->surface_destroy_listener);
wl_resource_add_destroy_listener (sibling->resource,
&op->sibling_destroy_listener);
- surface->sub.pending_placement_ops =
- g_slist_append (surface->sub.pending_placement_ops, op);
+ parent->pending_state->subsurface_placement_ops =
+ g_slist_append (parent->pending_state->subsurface_placement_ops, op);
}
static void
diff --git a/src/wayland/meta-wayland-subsurface.h b/src/wayland/meta-wayland-subsurface.h
index d92c021976..7ea6bc5ae1 100644
--- a/src/wayland/meta-wayland-subsurface.h
+++ b/src/wayland/meta-wayland-subsurface.h
@@ -29,6 +29,21 @@ G_DECLARE_FINAL_TYPE (MetaWaylandSubsurface,
META, WAYLAND_SUBSURFACE,
MetaWaylandActorSurface)
+typedef enum
+{
+ META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
+ META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW
+} MetaWaylandSubsurfacePlacement;
+
+typedef struct
+{
+ MetaWaylandSubsurfacePlacement placement;
+ MetaWaylandSurface *surface;
+ MetaWaylandSurface *sibling;
+ struct wl_listener surface_destroy_listener;
+ struct wl_listener sibling_destroy_listener;
+} MetaWaylandSubsurfacePlacementOp;
+
void meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface);
void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
@@ -36,6 +51,8 @@ void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
int parent_y,
MetaRectangle *out_geometry);
+void meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op);
+
void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor);
#endif /* META_WAYLAND_SUBSURFACE_H */
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 962ab05ff3..465b67619d 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -468,6 +468,8 @@ meta_wayland_surface_state_set_default (MetaWaylandSurfaceState *state)
state->has_new_viewport_src_rect = FALSE;
state->has_new_viewport_dst_size = FALSE;
+ state->subsurface_placement_ops = NULL;
+
wl_list_init (&state->presentation_feedback_list);
}
@@ -499,6 +501,13 @@ meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
wl_list_for_each_safe (cb, next, &state->frame_callback_list, link)
wl_resource_destroy (cb->resource);
+ if (state->subsurface_placement_ops)
+ {
+ g_slist_free_full (
+ state->subsurface_placement_ops,
+ (GDestroyNotify) meta_wayland_subsurface_placement_op_free);
+ }
+
meta_wayland_surface_state_discard_presentation_feedback (state);
}
@@ -609,6 +618,21 @@ meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from,
to);
}
+ if (from->subsurface_placement_ops != NULL)
+ {
+ if (to->subsurface_placement_ops != NULL)
+ {
+ to->subsurface_placement_ops =
+ g_slist_concat (to->subsurface_placement_ops,
+ from->subsurface_placement_ops);
+ from->subsurface_placement_ops = NULL;
+ }
+ else
+ {
+ to->subsurface_placement_ops = from->subsurface_placement_ops;
+ }
+ }
+
wl_list_insert_list (&to->presentation_feedback_list,
&from->presentation_feedback_list);
wl_list_init (&from->presentation_feedback_list);
@@ -827,6 +851,43 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
}
}
+ if (state->subsurface_placement_ops)
+ {
+ GSList *l;
+
+ for (l = state->subsurface_placement_ops; l; l = l->next)
+ {
+ MetaWaylandSubsurfacePlacementOp *op = l->data;
+ GNode *sibling_node;
+
+ if (!op->surface || !op->sibling)
+ continue;
+
+ if (op->sibling == surface)
+ sibling_node = surface->subsurface_leaf_node;
+ else
+ sibling_node = op->sibling->subsurface_branch_node;
+
+ g_node_unlink (op->surface->subsurface_branch_node);
+
+ switch (op->placement)
+ {
+ case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
+ g_node_insert_after (surface->subsurface_branch_node,
+ sibling_node,
+ op->surface->subsurface_branch_node);
+ break;
+ case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
+ g_node_insert_before (surface->subsurface_branch_node,
+ sibling_node,
+ op->surface->subsurface_branch_node);
+ break;
+ }
+ }
+
+ meta_wayland_surface_notify_subsurface_state_changed (surface);
+ }
+
cleanup:
/* If we have a buffer that we are not using, decrease the use count so it may
* be released if no-one else has a use-reference to it.
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 22afb0ae17..f0153b23b9 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -121,6 +121,8 @@ struct _MetaWaylandSurfaceState
int viewport_dst_width;
int viewport_dst_height;
+ GSList *subsurface_placement_ops;
+
/* presentation-time */
struct wl_list presentation_feedback_list;
};
@@ -212,7 +214,6 @@ struct _MetaWaylandSurface
int32_t pending_x;
int32_t pending_y;
gboolean pending_pos;
- GSList *pending_placement_ops;
} sub;
/* wp_viewport */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]