wayland/surface: Use transactions for applying committed states
A transaction contains the committed state for a surface, plus any cached state for synchronized subsurfaces. v2: * Handle sub-surface positions separately from surface states. v3: * Sync child states only for surfaces with state in the transaction. v4: (Jonas Ådahl) * Drop unnecessary g_object_new call from wl_subsurface_set_desync. (me) * Fix indentation & formatting in meta_wayland_surface_commit. * Add meta_wayland_surface_state_new helper function. * Fix alignment of meta_wayland_transaction_apply_subsurface_position parameters. * Add curly braces around meta_wayland_transaction_sync_child_states call in meta_wayland_transaction_apply. v5: * Make meta_wayland_surface_state_new an inline function. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This commit is contained in:
parent
56260e3e07
commit
0bae4ece19
@ -28,6 +28,7 @@
|
||||
#include "wayland/meta-wayland-actor-surface.h"
|
||||
#include "wayland/meta-wayland-buffer.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-wayland-transaction.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
|
||||
struct _MetaWaylandSubsurface
|
||||
@ -105,28 +106,6 @@ is_sibling (MetaWaylandSurface *surface,
|
||||
return surface != sibling && surface->sub.parent == sibling->sub.parent;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (subsurface);
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (subsurface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
if (surface->sub.pending_pos)
|
||||
{
|
||||
surface->sub.x = surface->sub.pending_x;
|
||||
surface->sub.y = surface->sub.pending_y;
|
||||
surface->sub.pending_pos = FALSE;
|
||||
}
|
||||
|
||||
if (meta_wayland_surface_is_synchronized (surface))
|
||||
meta_wayland_surface_apply_cached_state (surface);
|
||||
|
||||
meta_wayland_actor_surface_sync_actor_state (actor_surface);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||
int parent_x,
|
||||
@ -452,7 +431,13 @@ wl_subsurface_set_desync (struct wl_client *client,
|
||||
meta_wayland_surface_is_synchronized (surface->sub.parent);
|
||||
|
||||
if (!is_parent_effectively_synchronized)
|
||||
meta_wayland_surface_apply_cached_state (surface);
|
||||
{
|
||||
MetaWaylandTransaction *transaction;
|
||||
|
||||
transaction = meta_wayland_transaction_new (surface->compositor);
|
||||
meta_wayland_transaction_add_cached_states (transaction, surface);
|
||||
meta_wayland_transaction_commit (transaction);
|
||||
}
|
||||
|
||||
surface->sub.synchronous = FALSE;
|
||||
}
|
||||
|
@ -44,8 +44,6 @@ typedef struct
|
||||
struct wl_listener sibling_destroy_listener;
|
||||
} MetaWaylandSubsurfacePlacementOp;
|
||||
|
||||
void meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface);
|
||||
|
||||
void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||
int parent_x,
|
||||
int parent_y,
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "wayland/meta-wayland-region.h"
|
||||
#include "wayland/meta-wayland-seat.h"
|
||||
#include "wayland/meta-wayland-subsurface.h"
|
||||
#include "wayland/meta-wayland-transaction.h"
|
||||
#include "wayland/meta-wayland-viewporter.h"
|
||||
#include "wayland/meta-wayland-xdg-shell.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
@ -717,7 +718,6 @@ void
|
||||
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceState *state)
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface;
|
||||
gboolean had_damage = FALSE;
|
||||
int old_width, old_height;
|
||||
|
||||
@ -956,14 +956,6 @@ cleanup:
|
||||
surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
|
||||
0);
|
||||
|
||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
||||
{
|
||||
MetaWaylandSubsurface *subsurface;
|
||||
|
||||
subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||
meta_wayland_subsurface_parent_state_applied (subsurface);
|
||||
}
|
||||
|
||||
if (had_damage)
|
||||
{
|
||||
MetaWindow *toplevel_window;
|
||||
@ -984,22 +976,6 @@ cleanup:
|
||||
meta_wayland_surface_role_post_apply_state (surface->role, state);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_cached_state (MetaWaylandSurface *surface)
|
||||
{
|
||||
if (!surface->cached_state)
|
||||
surface->cached_state = g_object_new (META_TYPE_WAYLAND_SURFACE_STATE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_apply_cached_state (MetaWaylandSurface *surface)
|
||||
{
|
||||
ensure_cached_state (surface);
|
||||
meta_wayland_surface_apply_state (surface, surface->cached_state);
|
||||
meta_wayland_surface_state_reset (surface->cached_state);
|
||||
}
|
||||
|
||||
MetaWaylandSurfaceState *
|
||||
meta_wayland_surface_get_pending_state (MetaWaylandSurface *surface)
|
||||
{
|
||||
@ -1028,16 +1004,30 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface)
|
||||
*/
|
||||
if (meta_wayland_surface_is_synchronized (surface))
|
||||
{
|
||||
ensure_cached_state (surface);
|
||||
|
||||
meta_wayland_surface_state_merge_into (pending, surface->cached_state);
|
||||
if (surface->cached_state)
|
||||
{
|
||||
meta_wayland_surface_state_merge_into (pending, surface->cached_state);
|
||||
meta_wayland_surface_state_reset (pending);
|
||||
}
|
||||
else
|
||||
{
|
||||
surface->cached_state = pending;
|
||||
surface->pending_state = meta_wayland_surface_state_new ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_wayland_surface_apply_state (surface, surface->pending_state);
|
||||
}
|
||||
MetaWaylandTransaction *transaction;
|
||||
|
||||
meta_wayland_surface_state_reset (pending);
|
||||
transaction = meta_wayland_transaction_new (surface->compositor);
|
||||
meta_wayland_transaction_add_state (transaction, surface, pending);
|
||||
if (surface->sub.pending_pos)
|
||||
meta_wayland_transaction_add_subsurface_position (transaction, surface);
|
||||
meta_wayland_transaction_add_cached_child_states (transaction, surface);
|
||||
meta_wayland_transaction_commit (transaction);
|
||||
|
||||
surface->pending_state = meta_wayland_surface_state_new ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1745,7 +1735,7 @@ meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface,
|
||||
static void
|
||||
meta_wayland_surface_init (MetaWaylandSurface *surface)
|
||||
{
|
||||
surface->pending_state = g_object_new (META_TYPE_WAYLAND_SURFACE_STATE, NULL);
|
||||
surface->pending_state = meta_wayland_surface_state_new ();
|
||||
|
||||
surface->buffer_ref = meta_wayland_buffer_ref_new ();
|
||||
|
||||
|
@ -276,7 +276,8 @@ void meta_wayland_surface_apply_state (MetaWaylandSurface *s
|
||||
MetaWaylandSurfaceState *
|
||||
meta_wayland_surface_get_pending_state (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_apply_cached_state (MetaWaylandSurface *surface);
|
||||
MetaWaylandSurfaceState *
|
||||
meta_wayland_surface_ensure_cached_state (MetaWaylandSurface *surface);
|
||||
|
||||
gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||
GType role_type,
|
||||
@ -386,6 +387,12 @@ meta_wayland_surface_can_scanout_untransformed (MetaWaylandSurface *surface,
|
||||
|
||||
int meta_wayland_surface_get_geometry_scale (MetaWaylandSurface *surface);
|
||||
|
||||
static inline MetaWaylandSurfaceState *
|
||||
meta_wayland_surface_state_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_WAYLAND_SURFACE_STATE, NULL);
|
||||
}
|
||||
|
||||
static inline GNode *
|
||||
meta_get_next_subsurface_sibling (GNode *n)
|
||||
{
|
||||
|
@ -41,6 +41,11 @@ struct _MetaWaylandTransaction
|
||||
typedef struct _MetaWaylandTransactionEntry
|
||||
{
|
||||
MetaWaylandSurfaceState *state;
|
||||
|
||||
/* Sub-surface position */
|
||||
gboolean has_sub_pos;
|
||||
int x;
|
||||
int y;
|
||||
} MetaWaylandTransactionEntry;
|
||||
|
||||
static MetaWaylandTransactionEntry *
|
||||
@ -66,6 +71,17 @@ meta_wayland_transaction_sync_child_states (MetaWaylandSurface *surface)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_transaction_apply_subsurface_position (MetaWaylandSurface *surface,
|
||||
MetaWaylandTransactionEntry *entry)
|
||||
{
|
||||
if (!entry->has_sub_pos)
|
||||
return;
|
||||
|
||||
surface->sub.x = entry->x;
|
||||
surface->sub.y = entry->y;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_ancestor (MetaWaylandSurface *candidate,
|
||||
MetaWaylandSurface *reference)
|
||||
@ -149,11 +165,13 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandTransaction **first_candidate)
|
||||
{
|
||||
g_autofree MetaWaylandSurface **surfaces = NULL;
|
||||
g_autofree MetaWaylandSurfaceState **states = NULL;
|
||||
unsigned int num_surfaces;
|
||||
int i;
|
||||
|
||||
surfaces = (MetaWaylandSurface **)
|
||||
g_hash_table_get_keys_as_array (transaction->entries, &num_surfaces);
|
||||
states = g_new (MetaWaylandSurfaceState *, num_surfaces);
|
||||
|
||||
/* Sort surfaces from ancestors to descendants */
|
||||
qsort (surfaces, num_surfaces, sizeof (MetaWaylandSurface *),
|
||||
@ -166,7 +184,10 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandTransactionEntry *entry;
|
||||
|
||||
entry = meta_wayland_transaction_get_entry (transaction, surface);
|
||||
meta_wayland_surface_apply_state (surface, entry->state);
|
||||
states[i] = entry->state;
|
||||
meta_wayland_transaction_apply_subsurface_position (surface, entry);
|
||||
if (entry->state)
|
||||
meta_wayland_surface_apply_state (surface, entry->state);
|
||||
|
||||
if (surface->transaction.last_committed == transaction)
|
||||
{
|
||||
@ -188,7 +209,10 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
||||
|
||||
/* Synchronize child states from descendants to ancestors */
|
||||
for (i = num_surfaces - 1; i >= 0; i--)
|
||||
meta_wayland_transaction_sync_child_states (surfaces[i]);
|
||||
{
|
||||
if (states[i])
|
||||
meta_wayland_transaction_sync_child_states (surfaces[i]);
|
||||
}
|
||||
|
||||
meta_wayland_transaction_free (transaction);
|
||||
}
|
||||
@ -296,6 +320,58 @@ meta_wayland_transaction_add_state (MetaWaylandTransaction *transaction,
|
||||
entry->state = state;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandTransactionEntry *entry;
|
||||
|
||||
entry = meta_wayland_transaction_ensure_entry (transaction, surface);
|
||||
entry->x = surface->sub.pending_x;
|
||||
entry->y = surface->sub.pending_y;
|
||||
entry->has_sub_pos = TRUE;
|
||||
surface->sub.pending_pos = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_wayland_transaction_add_cached_state (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandSurfaceState *cached = surface->cached_state;
|
||||
gboolean is_synchronized;
|
||||
|
||||
is_synchronized = meta_wayland_surface_is_synchronized (surface);
|
||||
|
||||
if (is_synchronized && cached)
|
||||
{
|
||||
meta_wayland_transaction_add_state (transaction, surface, cached);
|
||||
surface->cached_state = NULL;
|
||||
}
|
||||
|
||||
if (surface->sub.pending_pos)
|
||||
meta_wayland_transaction_add_subsurface_position (transaction, surface);
|
||||
|
||||
return is_synchronized;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_transaction_add_cached_child_states (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface;
|
||||
|
||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
||||
meta_wayland_transaction_add_cached_states (transaction, subsurface_surface);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_transaction_add_cached_states (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
if (meta_wayland_transaction_add_cached_state (transaction, surface))
|
||||
meta_wayland_transaction_add_cached_child_states (transaction, surface);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_transaction_entry_free (MetaWaylandTransactionEntry *entry)
|
||||
{
|
||||
|
@ -28,6 +28,15 @@ void meta_wayland_transaction_add_state (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceState *state);
|
||||
|
||||
void meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_transaction_add_cached_states (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_transaction_add_cached_child_states (MetaWaylandTransaction *transaction,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
MetaWaylandTransaction *meta_wayland_transaction_new (MetaWaylandCompositor *compositor);
|
||||
|
||||
void meta_wayland_transaction_free (MetaWaylandTransaction *transaction);
|
||||
|
Loading…
Reference in New Issue
Block a user