Also see individual commits.
Squashing refers to an action of combining a state with the state right before it in the queue. The older state becomes a "sum" of two states, and the newer state becomes empty.
This MR introduces
wlr_surface_synced_state to keep track of objects synchronized with the surface state flow. At any given moment, a surface has a
current state, a
pending state, and optionally a number of cached states. Thus, the following data structure is maintained:
This setup allows to perform state caching and squashing in
O(k) time, where
k is the number of surface-synced objects. When a state is cached, a column of
n+1 states is added right before the last one (
Creation of a surface-synced object adds a row of
k+1 states and is done in
n is the number of cached states at the moment; most of the time,
n is 0. Note that rows have undefined order;
wlr_surface_state::synced must be treated as unordered sets.
There are objects which only have
current state which is updated on surface commit; those don't need to be surface-synced.
wlr_surface.current.seqis meaningless and is always 0. It can't be set to the sequence number of the state being committed.
Consider the following situation:
A(seq 1) ⇄
B(seq 2) ⇄
A is unlocked and then
B is unlocked,
wlr_surface.current.seq is set to
1 and then
B is unlocked first, it's squashed into
A.seq can't be updated to
2, because whatever locked
A still has the old sequence number. After unlocking
wlr_surface.current.seq will be
1. To avoid this inconsistency, sequence numbers aren't updated at all and assumed to be only used for state locking.
Note that this could be fixed in a non-breaking way by introducing
wlr_surface_state.lock_seq and updating
wlr_surface_state.seq on squash, if required.
WhileFixed by !3191 (merged).
wlr_surface_synced_interface.precommitis called right before the current state update,
wlr_surface_role.precommitis called on
wl_surface.commitrequest. This is a bug and will be fixed in another PR.
*.current.committednow indicates which parts of the current state were modified by the most recent commit. Related: #2098
This is (supposed to be) a purely internal change and shouldn't require any action from compositor developers.