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-actor-surface.h"
|
||||||
#include "wayland/meta-wayland-buffer.h"
|
#include "wayland/meta-wayland-buffer.h"
|
||||||
#include "wayland/meta-wayland-surface.h"
|
#include "wayland/meta-wayland-surface.h"
|
||||||
|
#include "wayland/meta-wayland-transaction.h"
|
||||||
#include "wayland/meta-window-wayland.h"
|
#include "wayland/meta-window-wayland.h"
|
||||||
|
|
||||||
struct _MetaWaylandSubsurface
|
struct _MetaWaylandSubsurface
|
||||||
@ -105,28 +106,6 @@ is_sibling (MetaWaylandSurface *surface,
|
|||||||
return surface != sibling && surface->sub.parent == sibling->sub.parent;
|
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
|
void
|
||||||
meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||||
int parent_x,
|
int parent_x,
|
||||||
@ -452,7 +431,13 @@ wl_subsurface_set_desync (struct wl_client *client,
|
|||||||
meta_wayland_surface_is_synchronized (surface->sub.parent);
|
meta_wayland_surface_is_synchronized (surface->sub.parent);
|
||||||
|
|
||||||
if (!is_parent_effectively_synchronized)
|
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;
|
surface->sub.synchronous = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,6 @@ typedef struct
|
|||||||
struct wl_listener sibling_destroy_listener;
|
struct wl_listener sibling_destroy_listener;
|
||||||
} MetaWaylandSubsurfacePlacementOp;
|
} MetaWaylandSubsurfacePlacementOp;
|
||||||
|
|
||||||
void meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface);
|
|
||||||
|
|
||||||
void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||||
int parent_x,
|
int parent_x,
|
||||||
int parent_y,
|
int parent_y,
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "wayland/meta-wayland-region.h"
|
#include "wayland/meta-wayland-region.h"
|
||||||
#include "wayland/meta-wayland-seat.h"
|
#include "wayland/meta-wayland-seat.h"
|
||||||
#include "wayland/meta-wayland-subsurface.h"
|
#include "wayland/meta-wayland-subsurface.h"
|
||||||
|
#include "wayland/meta-wayland-transaction.h"
|
||||||
#include "wayland/meta-wayland-viewporter.h"
|
#include "wayland/meta-wayland-viewporter.h"
|
||||||
#include "wayland/meta-wayland-xdg-shell.h"
|
#include "wayland/meta-wayland-xdg-shell.h"
|
||||||
#include "wayland/meta-window-wayland.h"
|
#include "wayland/meta-window-wayland.h"
|
||||||
@ -717,7 +718,6 @@ void
|
|||||||
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurfaceState *state)
|
MetaWaylandSurfaceState *state)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *subsurface_surface;
|
|
||||||
gboolean had_damage = FALSE;
|
gboolean had_damage = FALSE;
|
||||||
int old_width, old_height;
|
int old_width, old_height;
|
||||||
|
|
||||||
@ -956,14 +956,6 @@ cleanup:
|
|||||||
surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
|
surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
|
||||||
0);
|
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)
|
if (had_damage)
|
||||||
{
|
{
|
||||||
MetaWindow *toplevel_window;
|
MetaWindow *toplevel_window;
|
||||||
@ -984,22 +976,6 @@ cleanup:
|
|||||||
meta_wayland_surface_role_post_apply_state (surface->role, state);
|
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 *
|
MetaWaylandSurfaceState *
|
||||||
meta_wayland_surface_get_pending_state (MetaWaylandSurface *surface)
|
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))
|
if (meta_wayland_surface_is_synchronized (surface))
|
||||||
{
|
{
|
||||||
ensure_cached_state (surface);
|
if (surface->cached_state)
|
||||||
|
{
|
||||||
meta_wayland_surface_state_merge_into (pending, 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
|
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
|
static void
|
||||||
@ -1745,7 +1735,7 @@ meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface,
|
|||||||
static void
|
static void
|
||||||
meta_wayland_surface_init (MetaWaylandSurface *surface)
|
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 ();
|
surface->buffer_ref = meta_wayland_buffer_ref_new ();
|
||||||
|
|
||||||
|
@ -276,7 +276,8 @@ void meta_wayland_surface_apply_state (MetaWaylandSurface *s
|
|||||||
MetaWaylandSurfaceState *
|
MetaWaylandSurfaceState *
|
||||||
meta_wayland_surface_get_pending_state (MetaWaylandSurface *surface);
|
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,
|
gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
|
||||||
GType role_type,
|
GType role_type,
|
||||||
@ -386,6 +387,12 @@ meta_wayland_surface_can_scanout_untransformed (MetaWaylandSurface *surface,
|
|||||||
|
|
||||||
int meta_wayland_surface_get_geometry_scale (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 *
|
static inline GNode *
|
||||||
meta_get_next_subsurface_sibling (GNode *n)
|
meta_get_next_subsurface_sibling (GNode *n)
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,11 @@ struct _MetaWaylandTransaction
|
|||||||
typedef struct _MetaWaylandTransactionEntry
|
typedef struct _MetaWaylandTransactionEntry
|
||||||
{
|
{
|
||||||
MetaWaylandSurfaceState *state;
|
MetaWaylandSurfaceState *state;
|
||||||
|
|
||||||
|
/* Sub-surface position */
|
||||||
|
gboolean has_sub_pos;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
} MetaWaylandTransactionEntry;
|
} MetaWaylandTransactionEntry;
|
||||||
|
|
||||||
static 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
|
static gboolean
|
||||||
is_ancestor (MetaWaylandSurface *candidate,
|
is_ancestor (MetaWaylandSurface *candidate,
|
||||||
MetaWaylandSurface *reference)
|
MetaWaylandSurface *reference)
|
||||||
@ -149,11 +165,13 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
|||||||
MetaWaylandTransaction **first_candidate)
|
MetaWaylandTransaction **first_candidate)
|
||||||
{
|
{
|
||||||
g_autofree MetaWaylandSurface **surfaces = NULL;
|
g_autofree MetaWaylandSurface **surfaces = NULL;
|
||||||
|
g_autofree MetaWaylandSurfaceState **states = NULL;
|
||||||
unsigned int num_surfaces;
|
unsigned int num_surfaces;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
surfaces = (MetaWaylandSurface **)
|
surfaces = (MetaWaylandSurface **)
|
||||||
g_hash_table_get_keys_as_array (transaction->entries, &num_surfaces);
|
g_hash_table_get_keys_as_array (transaction->entries, &num_surfaces);
|
||||||
|
states = g_new (MetaWaylandSurfaceState *, num_surfaces);
|
||||||
|
|
||||||
/* Sort surfaces from ancestors to descendants */
|
/* Sort surfaces from ancestors to descendants */
|
||||||
qsort (surfaces, num_surfaces, sizeof (MetaWaylandSurface *),
|
qsort (surfaces, num_surfaces, sizeof (MetaWaylandSurface *),
|
||||||
@ -166,7 +184,10 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
|||||||
MetaWaylandTransactionEntry *entry;
|
MetaWaylandTransactionEntry *entry;
|
||||||
|
|
||||||
entry = meta_wayland_transaction_get_entry (transaction, surface);
|
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)
|
if (surface->transaction.last_committed == transaction)
|
||||||
{
|
{
|
||||||
@ -188,7 +209,10 @@ meta_wayland_transaction_apply (MetaWaylandTransaction *transaction,
|
|||||||
|
|
||||||
/* Synchronize child states from descendants to ancestors */
|
/* Synchronize child states from descendants to ancestors */
|
||||||
for (i = num_surfaces - 1; i >= 0; i--)
|
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);
|
meta_wayland_transaction_free (transaction);
|
||||||
}
|
}
|
||||||
@ -296,6 +320,58 @@ meta_wayland_transaction_add_state (MetaWaylandTransaction *transaction,
|
|||||||
entry->state = state;
|
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
|
static void
|
||||||
meta_wayland_transaction_entry_free (MetaWaylandTransactionEntry *entry)
|
meta_wayland_transaction_entry_free (MetaWaylandTransactionEntry *entry)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,15 @@ void meta_wayland_transaction_add_state (MetaWaylandTransaction *transaction,
|
|||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurfaceState *state);
|
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);
|
MetaWaylandTransaction *meta_wayland_transaction_new (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
void meta_wayland_transaction_free (MetaWaylandTransaction *transaction);
|
void meta_wayland_transaction_free (MetaWaylandTransaction *transaction);
|
||||||
|
Loading…
Reference in New Issue
Block a user