mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
protocol: Define Content Update behavior
The protocol currently is in a state where we define that commits create content updates and they are queued up until they are applied, and the old view that commit applies the state or caches it in the parent state. This commit moves the protocol completely to the new model which retains the old behavior when no constraints are being used but allows for constraints to be used to hold back a group of synchronized content updates. To convince yourself that this indeed retains the original behavior I suggest to play around with a few examples and look at the resulting graphs, as is done here: https://gitlab.freedesktop.org/wayland/wayland/-/issues/457#note_2403135 Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
This commit is contained in:
parent
d81525a235
commit
7fc400ffff
1 changed files with 61 additions and 56 deletions
|
|
@ -1667,21 +1667,48 @@
|
|||
etc.) is double-buffered. Protocol requests modify the pending state,
|
||||
as opposed to the active state in use by the compositor.
|
||||
|
||||
A commit request atomically creates a content update from the pending
|
||||
state, even if the pending state has not been touched. The content
|
||||
update is placed in a queue until it becomes active. After commit, the
|
||||
new pending state is as documented for each related request.
|
||||
|
||||
When the content update is applied, the wl_buffer is applied before all
|
||||
other state. This means that all coordinates in double-buffered state
|
||||
are relative to the newly attached wl_buffers, except for
|
||||
wl_surface.attach itself. If there is no newly attached wl_buffer, the
|
||||
coordinates are relative to the previous content update.
|
||||
|
||||
All requests that need a commit to become effective are documented
|
||||
to affect double-buffered state.
|
||||
|
||||
Other interfaces may add further double-buffered surface state.
|
||||
|
||||
A commit request atomically creates a Content Update (CU) from the
|
||||
pending state, even if the pending state has not been touched. The
|
||||
content update is placed at the end of a per-surface queue until it
|
||||
becomes active. After commit, the new pending state is as documented for
|
||||
each related request.
|
||||
|
||||
A CU is either a Desync Content Update (DCU) or a Sync Content Update
|
||||
(SCU). If the surface is effectively synchronized at the commit request,
|
||||
it is a SCU, otherwise a DCU.
|
||||
|
||||
When a surface transitions from effectively synchronized to effectively
|
||||
desynchronized, all SCUs in its queue which are not reachable by any
|
||||
DCU become DCUs and dependency edges from outside the queue to these CUs
|
||||
are removed.
|
||||
|
||||
See wl_subsurface for the definition of 'effectively synchronized' and
|
||||
'effectively desynchronized'.
|
||||
|
||||
When a CU is placed in the queue, the CU has a dependency on the CU in
|
||||
front of it and to the SCU at end of the queue of every direct child
|
||||
surface if that SCU exists and does not have another dependent. This can
|
||||
form a directed acyclic graph of CUs with dependencies as edges.
|
||||
|
||||
In addition to surface state, the CU can have constraints that must be
|
||||
satisfied before it can be applied. Other interfaces may add CU
|
||||
constraints.
|
||||
|
||||
All DCUs which do not have a SCU in front of themselves in their queue,
|
||||
are candidates. If the graph that's reachable by a candidate does not
|
||||
have any unsatisfied constraints, the entire graph must be applied
|
||||
atomically.
|
||||
|
||||
When a CU is applied, the wl_buffer is applied before all other state.
|
||||
This means that all coordinates in double-buffered state are relative to
|
||||
the newly attached wl_buffers, except for wl_surface.attach itself. If
|
||||
there is no newly attached wl_buffer, the coordinates are relative to
|
||||
the previous content update.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
|
|
@ -3120,23 +3147,9 @@
|
|||
hidden, or if a NULL wl_buffer is applied. These rules apply
|
||||
recursively through the tree of surfaces.
|
||||
|
||||
The behaviour of a wl_surface.commit request on a sub-surface
|
||||
depends on the sub-surface's mode. The possible modes are
|
||||
synchronized and desynchronized, see methods
|
||||
wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized
|
||||
mode caches the wl_surface state to be applied when the parent's
|
||||
state gets applied, and desynchronized mode applies the pending
|
||||
wl_surface state directly. A sub-surface is initially in the
|
||||
synchronized mode.
|
||||
|
||||
Sub-surfaces also have another kind of state, which is managed by
|
||||
wl_subsurface requests, as opposed to wl_surface requests. This
|
||||
state includes the sub-surface position relative to the parent
|
||||
surface (wl_subsurface.set_position), and the stacking order of
|
||||
the parent and its sub-surfaces (wl_subsurface.place_above and
|
||||
.place_below). This state is applied when the parent surface's
|
||||
wl_surface state is applied, regardless of the sub-surface's mode.
|
||||
As the exception, set_sync and set_desync are effective immediately.
|
||||
A sub-surface can be in one of two modes. The possible modes are
|
||||
synchronized and desynchronized, see methods wl_subsurface.set_sync and
|
||||
wl_subsurface.set_desync.
|
||||
|
||||
The main surface can be thought to be always in desynchronized mode,
|
||||
since it does not have a parent in the sub-surfaces sense.
|
||||
|
|
@ -3148,6 +3161,22 @@
|
|||
synchronized mode, and then assume that all its child and grand-child
|
||||
sub-surfaces are synchronized, too, without explicitly setting them.
|
||||
|
||||
If a surface behaves as in synchronized mode, it is effectively
|
||||
synchronized, otherwise it is effectively desynchronized.
|
||||
|
||||
A sub-surface is initially in the synchronized mode.
|
||||
|
||||
Sub-surfaces also have another kind of state, which is managed by
|
||||
wl_subsurface requests, as opposed to wl_surface requests. This
|
||||
state includes the sub-surface position relative to the parent
|
||||
surface (wl_subsurface.set_position), and the stacking order of
|
||||
the parent and its sub-surfaces (wl_subsurface.place_above and
|
||||
.place_below).
|
||||
|
||||
This state is double-buffered on the parent's surface regardless of the
|
||||
sub-surface's mode. As the exception, set_sync and set_desync are
|
||||
effective immediately.
|
||||
|
||||
Destroying a sub-surface takes effect immediately. If you need to
|
||||
synchronize the removal of a sub-surface to the parent surface update,
|
||||
unmap the sub-surface first by attaching a NULL wl_buffer, update parent,
|
||||
|
|
@ -3229,42 +3258,18 @@
|
|||
<request name="set_sync">
|
||||
<description summary="set sub-surface to synchronized mode">
|
||||
Change the commit behaviour of the sub-surface to synchronized
|
||||
mode, also described as the parent dependent mode.
|
||||
mode.
|
||||
|
||||
In synchronized mode, wl_surface.commit on a sub-surface will
|
||||
accumulate the committed state in a cache, but the state will
|
||||
not be applied and hence will not change the compositor output.
|
||||
The cached state is applied to the sub-surface immediately after
|
||||
the parent surface's state is applied. This ensures atomic
|
||||
updates of the parent and all its synchronized sub-surfaces.
|
||||
Applying the cached state will invalidate the cache, so further
|
||||
parent surface commits do not (re-)apply old state.
|
||||
|
||||
See wl_subsurface for the recursive effect of this mode.
|
||||
See wl_subsurface and wl_surface.commit for more information.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_desync">
|
||||
<description summary="set sub-surface to desynchronized mode">
|
||||
Change the commit behaviour of the sub-surface to desynchronized
|
||||
mode, also described as independent or freely running mode.
|
||||
mode.
|
||||
|
||||
In desynchronized mode, wl_surface.commit on a sub-surface will
|
||||
apply the pending state directly, without caching, as happens
|
||||
normally with a wl_surface. Calling wl_surface.commit on the
|
||||
parent surface has no effect on the sub-surface's wl_surface
|
||||
state. This mode allows a sub-surface to be updated on its own.
|
||||
|
||||
If cached state exists when wl_surface.commit is called in
|
||||
desynchronized mode, the pending state is added to the cached
|
||||
state, and applied as a whole. This invalidates the cache.
|
||||
|
||||
Note: even if a sub-surface is set to desynchronized, a parent
|
||||
sub-surface may override it to behave as synchronized. For details,
|
||||
see wl_subsurface.
|
||||
|
||||
If a surface's parent surface behaves as desynchronized, then
|
||||
the cached state is applied on set_desync.
|
||||
See wl_subsurface and wl_surface.commit for more information.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue