wayland/surface: Overhaul handling of buffer use count

Move the use count from a separate MetaWaylandBufferRef struct to the
MetaWaylandBuffer class, and remove the former.

The buffer use count is now incremented already in
meta_wayland_surface_commit, since the Wayland protocol defines the
buffer to be in use by the compositor at that point. If the buffer
attachment ends up being dropped again before it is applied to the
surface state (e.g. because another buffer is committed to a
synchronized sub-surface before the parent surface is committed),
the use count is now decremented, and a buffer release event is sent if
the use count drops to 0.

Buffer release events were previously incorrectly not sent under these
circumstances. Test case: Run the weston-subsurfaces demo with the -r1
and/or -t1 command line parameter. Resize the window. Before this
change, weston-subsurfaces would freeze or abort after a few resize
operations, because mutter failed to send release events and the
client ran out of usable buffers.

v2:
* Handle NULL priv->buffer_ref in
  meta_wayland_cursor_surface_apply_state.
v3:
* Remove MetaWaylandBufferRef altogether, move the use count tracking
  to MetaWaylandBuffer itself. Much simpler, and doesn't run into
  lifetime issues when mutter shuts down.
v4:
* Warn if use count isn't 0 in meta_wayland_buffer_finalize.
* Keep pending_buffer_resource_destroyed for attached but not yet
  committed buffers. If the client attaches a buffer and then destroys
  it before commit, we ignore the buffer attachement, same as before
  this MR.
v5:
* Rebase on top of new commit which splits up surface->texture.
* MetaWaylandSurfaceState::buffer can only be non-NULL if
  ::newly_attached is TRUE, simplify accordingly.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1880>
This commit is contained in:
Michel Dänzer
2022-06-22 18:43:11 +02:00
committed by Michel Dänzer
parent 6e6a38342e
commit 05efcb4b21
11 changed files with 102 additions and 157 deletions

View File

@ -215,7 +215,7 @@ meta_wayland_shell_surface_surface_pre_apply_state (MetaWaylandSurfaceRole *sur
meta_wayland_surface_role_get_surface (surface_role);
if (pending->newly_attached &&
!surface->buffer_ref->buffer &&
!surface->buffer &&
priv->window)
meta_window_queue (priv->window, META_QUEUE_CALC_SHOWING);
}