mirror of
https://github.com/brl/mutter.git
synced 2025-02-19 22:54:08 +00:00
wayland/surface: Keep transaction entries for all referenced surfaces
This keeps all surfaces referenced by a transaction alive until the transaction is destroyed, and makes sure transactions are applied in the same order as they were committed with respect to all surfaces they reference. v2: * Guard against NULL entry in meta_wayland_transaction_apply. v3: * Keep single entries hash table. v4: * Unref the surface in the meta_wayland_transaction_merge_into while loop only if the "to" transaction didn't already have an entry for it, to prevent premature finalization of the surface (likely followed by a crash). v5: * Unref the surface (implicitly via g_hash_table_iter_remove) in the meta_wayland_transaction_merge_into while loop even if the "to" transaction already had an entry for it, or we leak a reference. * Use g_clear_object & g_steal_pointer to not leave behind a dangling from->state pointer in meta_wayland_transaction_entry_merge_into. v6: * Add curly braces around meta_wayland_transaction_add_placement_surfaces calls. (Jonas Ådahl) Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This commit is contained in:
parent
5fa4ce6fa8
commit
e26df6ac14
@ -35,6 +35,10 @@ struct _MetaWaylandTransaction
|
|||||||
MetaWaylandTransaction *next_candidate;
|
MetaWaylandTransaction *next_candidate;
|
||||||
uint64_t committed_sequence;
|
uint64_t committed_sequence;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keys: All surfaces referenced in the transaction
|
||||||
|
* Values: Pointer to MetaWaylandTransactionEntry for the surface
|
||||||
|
*/
|
||||||
GHashTable *entries;
|
GHashTable *entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -303,7 +307,7 @@ meta_wayland_transaction_ensure_entry (MetaWaylandTransaction *transaction,
|
|||||||
return entry;
|
return entry;
|
||||||
|
|
||||||
entry = g_new0 (MetaWaylandTransactionEntry, 1);
|
entry = g_new0 (MetaWaylandTransactionEntry, 1);
|
||||||
g_hash_table_insert (transaction->entries, surface, entry);
|
g_hash_table_insert (transaction->entries, g_object_ref (surface), entry);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@ -315,6 +319,39 @@ meta_wayland_transaction_entry_free (MetaWaylandTransactionEntry *entry)
|
|||||||
g_free (entry);
|
g_free (entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_transaction_add_placement_surfaces (MetaWaylandTransaction *transaction,
|
||||||
|
MetaWaylandSurface *surface,
|
||||||
|
MetaWaylandSurfaceState *state)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = state->subsurface_placement_ops; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaWaylandSubsurfacePlacementOp *op = l->data;
|
||||||
|
|
||||||
|
if (op->surface)
|
||||||
|
meta_wayland_transaction_ensure_entry (transaction, op->surface);
|
||||||
|
|
||||||
|
if (op->sibling)
|
||||||
|
meta_wayland_transaction_ensure_entry (transaction, op->sibling);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_transaction_add_entry (MetaWaylandTransaction *transaction,
|
||||||
|
MetaWaylandSurface *surface,
|
||||||
|
MetaWaylandTransactionEntry *entry)
|
||||||
|
{
|
||||||
|
g_hash_table_insert (transaction->entries, g_object_ref (surface), entry);
|
||||||
|
|
||||||
|
if (entry->state)
|
||||||
|
{
|
||||||
|
meta_wayland_transaction_add_placement_surfaces (transaction, surface,
|
||||||
|
entry->state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *transaction,
|
meta_wayland_transaction_add_subsurface_position (MetaWaylandTransaction *transaction,
|
||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
@ -347,7 +384,7 @@ meta_wayland_transaction_entry_merge_into (MetaWaylandTransactionEntry *from,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
to->state = from->state;
|
to->state = g_steal_pointer (&from->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -362,16 +399,23 @@ meta_wayland_transaction_merge_into (MetaWaylandTransaction *from,
|
|||||||
while (g_hash_table_iter_next (&iter, (gpointer *) &surface,
|
while (g_hash_table_iter_next (&iter, (gpointer *) &surface,
|
||||||
(gpointer *) &from_entry))
|
(gpointer *) &from_entry))
|
||||||
{
|
{
|
||||||
g_hash_table_iter_steal (&iter);
|
|
||||||
to_entry = meta_wayland_transaction_get_entry (to, surface);
|
to_entry = meta_wayland_transaction_get_entry (to, surface);
|
||||||
if (!to_entry)
|
if (!to_entry)
|
||||||
{
|
{
|
||||||
g_hash_table_insert (to->entries, surface, from_entry);
|
g_hash_table_iter_steal (&iter);
|
||||||
|
meta_wayland_transaction_add_entry (to, surface, from_entry);
|
||||||
|
g_object_unref (surface);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (from_entry->state)
|
||||||
|
{
|
||||||
|
meta_wayland_transaction_add_placement_surfaces (to, surface,
|
||||||
|
from_entry->state);
|
||||||
|
}
|
||||||
|
|
||||||
meta_wayland_transaction_entry_merge_into (from_entry, to_entry);
|
meta_wayland_transaction_entry_merge_into (from_entry, to_entry);
|
||||||
meta_wayland_transaction_entry_free (from_entry);
|
g_hash_table_iter_remove (&iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_wayland_transaction_free (from);
|
meta_wayland_transaction_free (from);
|
||||||
@ -405,7 +449,7 @@ meta_wayland_transaction_new (MetaWaylandCompositor *compositor)
|
|||||||
transaction = g_new0 (MetaWaylandTransaction, 1);
|
transaction = g_new0 (MetaWaylandTransaction, 1);
|
||||||
|
|
||||||
transaction->compositor = compositor;
|
transaction->compositor = compositor;
|
||||||
transaction->entries = g_hash_table_new_full (NULL, NULL, NULL,
|
transaction->entries = g_hash_table_new_full (NULL, NULL, g_object_unref,
|
||||||
(GDestroyNotify) meta_wayland_transaction_entry_free);
|
(GDestroyNotify) meta_wayland_transaction_entry_free);
|
||||||
|
|
||||||
return transaction;
|
return transaction;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user