Unify terminology for "double buffered state"
wl_surface.commit
documentation says:
Surface state (input, opaque, and damage regions, attached buffers, etc.) is double-buffered. Protocol requests modify the pending state, as opposed to the current state in use by the compositor. A commit request atomically applies all pending state, replacing the current state. After commit, the new pending state is as documented for each related request.
On commit, a pending wl_buffer is applied first, and all other state second. This means that all coordinates in double-buffered state are relative to the new wl_buffer coming into use, except for wl_surface.attach itself. If there is no pending wl_buffer, the coordinates are relative to the current surface contents.
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.
This defines the term "double buffered state". Requests queue up pieces of state which are then made effective (applied) as a whole; atomically.
The definition of wl_subsurface
affects the behavior of "double buffered state". It adds what I could call as "a delay slot", termed "cached state" in the specification. Cached state gets applied to a wl_surface
when some state is applied to its parent wl_surface
, for instance.
Other extension and compositor features may add more delay slots. If a compositor postpones applying surface state update until the associated buffer fences becomes signalled, that requires a new delay slot. wayland-protocols!26 probably also needs new delay slots.
On the other hand, documenting state as "double-buffered" varies across protocol extension specifications. Some say double-buffered state is applied on wl_surface.commit
, which is inaccurate given the existence of delay slots. Some might say the state is applied when... it's applied? Some might talk about latching state in. And so on. My recollection is that this is quite varied and possibly confusing.
Even the term "double-buffered" itself is not accurate, given delay slots exist.
I would like to have a standard phrase to use in protocol specifications to say that a piece of state has double-buffered semantics. Something along the lines of
This value is xxx state. See wl_surface.commit for details.
and nothing more. Especially no sentence saying it is applied on wl_surface.commit
since it might not.
What should xxx
be?
- double-buffered
- latching
- atomic
- delayed
- ...
Hopefully this would make it easier to word not just specifications that introduce more state, but also specifications that add more delays to applying that state.
As a recap, we currently have:
- pending state, which is what is being modified directly by requests and not being looked at by the compositor, until
wl_surface.commit
-
wl_surface.commit
which is a sort of atomic transition or latching - cached state and other delay slots, that might chain up
- state actively used by the compositor (i.e. immediately going to or already on screen)
By chaining up I mean you could have a sub-surface waiting for the parent commit, which might be waiting for a group transaction, and then waiting for the buffer fence to become signalled. Which delays what is a big question. Does the buffer fence being unsignalled on a synchronized sub-surface mean that also the parent surface's update must wait even though it was just committed?