diff --git a/doc/publican/Content_Updates.xml b/doc/publican/Content_Updates.xml new file mode 100644 index 00000000..30c4ed33 --- /dev/null +++ b/doc/publican/Content_Updates.xml @@ -0,0 +1,460 @@ + + +%BOOK_ENTITIES; +]> + + + Content Updates + +
+ Overview + + + In the Wayland protocol, requests are asynchronous but take effect + immediately when the compositor receives them. However, some requests on + surfaces are not applied immediately but are instead double-buffered to + allow atomic changes. These double-buffered changes are committed through + the wl_surface.commit request, which creates a Content Update. + + + + Content Updates encapsulate all double-buffered state changes and can be + applied by the compositor. The complexity arises when considering + subsurfaces, which can operate in synchronized mode. When a subsurface is + synchronized, its Content Updates must be applied atomically together with + the parent surface's state. This synchronization can extend through an + entire tree of subsurfaces, where child subsurfaces inherit the + synchronized behavior from their parents. + + + + Historically, Content Updates from synchronized subsurfaces were merged + into the pending state of the parent surface on commit. However, the + introduction of constraints—which can defer the application of Content + Updates—necessitated a more sophisticated model. This led to the + implementation of per-surface queues of Content Updates, with dependencies + between Content Updates across different queues. This queuing model + maintains backwards compatibility with the earlier approach of merging + Content Updates into the parent's pending state on commit. + + + + The core protocol defines the semantics of Content Updates using + per-surface queues, but compositors that do not need to support constraints + may implement the simpler legacy model where synchronized subsurface states + are merged directly into the parent's pending state. + +
+ +
+ Rules + + + The core protocol specifies the behavior in wl_subsurface and + wl_surface.commit. The behavior can be summarized by the following rules: + + + + + + Content Updates (CU) contain all double-buffered state of the surface and + selected state from their direct children. + + + + + Surfaces which are effectively synchronized create Synchronized + Content Updates (SCU), otherwise they create Desync Content Updates + (DCU). + + + + + When a CU is created, it gets a dependency on the previous CU of the + same queues (if it exists). + + + + + When a CU is created, it gets a dependency on the last SCU of direct + child surfaces that are not reachable (if they exists). + + + + + The CUs and their dependencies form a DAG, where CUs are nodes and + dependencies are edges. + + + + + All DCUs starting from the front of the queues until the first SCU or + the back of the queue is reached are candidates. + + + + + If the maximal DAG that's reachable from a candidate (candidate DAG) + does not have any constraints, then this DAG can be applied. + + + + + A DAG is applied atomically by recursively applying a content update + without dependencies and removing it from the DAG. + + + + + Surfaces transition from effectively sync to effectively desync after + their parents. + + + + + When a surface transitions to effectively desync, all SCUs in its + queue which are not reachable by a DCU become DCUs. + + + +
+ +
+ Examples + + + These examples should help to build an intuition for how content updates + actually behave. They cover the interesting edge cases, such as + subsurfaces with constraints, and transitioning from a sync subsurface to + a desync one. + + + In all the examples below, the surface T1 refers to a toplevel surface, + SS1 refers to a sub-surface which is a child of T1, and SS2 refers to a + sub-surface which is a child of SS1. + + +
+ Legend + + + + + +
+ +
+ Simple Desynchronized Case + + + + + + + SS2 is effectively desynchronized and commits. This results in the + desynchronized content update (DCU) 1. + + + + + + + + + + DCU 1 is a candidate, and the candidate DAG + reachable from DCU 1 is only + DCU 1 itself. DCU 1 and + thus the candidate DAG does not have any constraints and can be + applied. + + + + + + + + + + The content updates of the candidate DAG get applied to the surface + atomically. + + + + + + + + + + T1 commits a DCU with a buffer-sync constraint. + It is a candidate but its DAG can't be applied because it contains a + constraint. + + + + + + + + + + T1 commits another CU (DCU 3) which is added at + the end of the queue, with a dependency to the previous CU (DCU + 2). Both DCU 2 and DCU + 3 are candidates, but both DAGs contain DCU + 2 with a constraint, and can't be applied. + + + + + + + + + + When the constraint gets cleared, both DAGs can be applied to the + surface atomitcally (either only 2, or + 2 and 3). + + + +
+ +
+ Simple Synchronized Case + + + + + + + SS1 and SS2 are effectively synchronized. SS2 commits SCU 1. + + + + + + + + + + SS1 commits SCU 2. The direct child surfaces SS2 has the last SCU 1 in its queue, which is not reachable. This creates a dependency from SCU 2 to SCU 1. + + + + + + + + + + SS1 commits SCU 3. The direct child surfaces SS2 has the last SCU 1 in its queue, which is already reachable by SCU 2. No dependency to SCU 1 is created. A dependency to the previous CU of the same queue (SCU 2) is created. + + + + + + + + + + T1 commit DCU 4. It is a candidate, its DAG does not contain any constraint and it can be applied. + + + + + + + + + + The DAG gets applied to the surfaces atomically. + + + +
+ +
+ Complex Synchronized Subsurface Case 1 + + + + + + + Every DCU (1 and 6) contain + CUs with constraints in their candidate DAG + + + + + + + + + + Waiting until the buffer-sync constrain on CU + 1 is cleared, the candidate DAG of CU + 1 does not contain constraints and can be applied + + + + + + + + + + That leaves the candidate DAG of CU 6 which still + contains another CU with a buffer-sync constrain + + + + + + + + + + Waiting until the buffer-sync constrain on CU + 6 is cleared, the candidate DAG of + 6 does not contain CUs with constraints and can + be applied. + + + + + + + + + + There is no DCU left and no constraint remaining. Nothing more can be + applied without a new CU. + + + +
+ +
+ Complex Synchronized Subsurface Case 2 + + + + + + + Both DCUs (1 and 6) have a + reachable DAG containing CU 1 with a constraint + + + + + + + + + + Waiting until the buffer-sync constrain on + 1 is cleared, both DAGs contain no CU with + constraints and can be applied in any order + + + + + + + + + + That leaves the same state as in the previous case + + + +
+ +
+ Synchronized to Desynchronized Subsurface + + + + + + + There is one DCU (4) with its reachable DAG + that cannot be applied because CU 4 contains a + constraint + + + + + + + + + + Surface SS1 transitions from effectively + synchronized to effectively desynchronized. SCU + 2 is reachable by DCU 4 so + nothing changes. + + + + + + + + + + Surface SS1 provides a new DCU + (5) but because the CU before + (2) is a Synchronized CU, it is not a candidate + + + +
+ +
+ Synchronized to Desynchronized Transition + + + + + + + There are four SCUs and all surfaces are effectively synchronized. + + + + + + + + + + Surface SS1 transitions to effectively + desynchronized and SCU 2 becomes a DCU because + it is not reachable from a DCU + + + + + + + + + + Surface SS2 transitions to effectively + desynchronized. SCUs 3 and + 4 become DCUs because they are not reachable + from a DCU. SCU 1 does not change because it is + reachable by DCU 2. + + + +
+ +
+
diff --git a/doc/publican/Wayland.xml b/doc/publican/Wayland.xml index 852c2971..f02a97fc 100644 --- a/doc/publican/Wayland.xml +++ b/doc/publican/Wayland.xml @@ -11,6 +11,7 @@ + diff --git a/doc/publican/html/images/content-updates/content-update-legend.png b/doc/publican/html/images/content-updates/content-update-legend.png new file mode 100644 index 00000000..84f12e76 Binary files /dev/null and b/doc/publican/html/images/content-updates/content-update-legend.png differ diff --git a/doc/publican/html/images/content-updates/content-updates.drawio b/doc/publican/html/images/content-updates/content-updates.drawio new file mode 100644 index 00000000..5d780213 --- /dev/null +++ b/doc/publican/html/images/content-updates/content-updates.drawio @@ -0,0 +1,1528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/publican/html/images/content-updates/meson.build b/doc/publican/html/images/content-updates/meson.build new file mode 100644 index 00000000..850e81ff --- /dev/null +++ b/doc/publican/html/images/content-updates/meson.build @@ -0,0 +1,35 @@ +foreach src : files([ + 'simple-desynchronized-state-1.png', + 'simple-desynchronized-state-2.png', + 'simple-desynchronized-state-3.png', + 'simple-desynchronized-state-4.png', + 'simple-desynchronized-state-5.png', + 'simple-desynchronized-state-6.png', + 'simple-synchronized-state-1.png', + 'simple-synchronized-state-2.png', + 'simple-synchronized-state-3.png', + 'simple-synchronized-state-4.png', + 'simple-synchronized-state-5.png', + 'sync-subsurf-case1-1.png', + 'sync-subsurf-case1-2.png', + 'sync-subsurf-case1-3.png', + 'sync-subsurf-case1-4.png', + 'sync-subsurf-case1-5.png', + 'sync-subsurf-case2-1.png', + 'sync-subsurf-case2-2.png', + 'sync-subsurf-case2-3.png', + 'sync-to-desync-subsurf-1.png', + 'sync-to-desync-subsurf-2.png', + 'sync-to-desync-subsurf-3.png', + 'sync-to-desync-transition-1.png', + 'sync-to-desync-transition-2.png', + 'sync-to-desync-transition-3.png', + 'content-update-legend.png', +]) + name = fs.name(src) + publican_inputs += fs.copyfile( + name, + install: true, + install_dir: publican_install_prefix + '/html/images/content-updates', + ) +endforeach diff --git a/doc/publican/html/images/content-updates/simple-desynchronized-state-1.png b/doc/publican/html/images/content-updates/simple-desynchronized-state-1.png new file mode 100644 index 00000000..d319ac25 Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-desynchronized-state-1.png differ diff --git a/doc/publican/html/images/content-updates/simple-desynchronized-state-2.png b/doc/publican/html/images/content-updates/simple-desynchronized-state-2.png new file mode 100644 index 00000000..ecd284cd Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-desynchronized-state-2.png differ diff --git a/doc/publican/html/images/content-updates/simple-desynchronized-state-3.png b/doc/publican/html/images/content-updates/simple-desynchronized-state-3.png new file mode 100644 index 00000000..73da57f8 Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-desynchronized-state-3.png differ diff --git a/doc/publican/html/images/content-updates/simple-desynchronized-state-4.png b/doc/publican/html/images/content-updates/simple-desynchronized-state-4.png new file mode 100644 index 00000000..83dcc063 Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-desynchronized-state-4.png differ diff --git a/doc/publican/html/images/content-updates/simple-desynchronized-state-5.png b/doc/publican/html/images/content-updates/simple-desynchronized-state-5.png new file mode 100644 index 00000000..d4e42d8f Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-desynchronized-state-5.png differ diff --git a/doc/publican/html/images/content-updates/simple-desynchronized-state-6.png b/doc/publican/html/images/content-updates/simple-desynchronized-state-6.png new file mode 100644 index 00000000..ebb88d81 Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-desynchronized-state-6.png differ diff --git a/doc/publican/html/images/content-updates/simple-desynchronized.drawio b/doc/publican/html/images/content-updates/simple-desynchronized.drawio new file mode 100644 index 00000000..c1adfd60 --- /dev/null +++ b/doc/publican/html/images/content-updates/simple-desynchronized.drawio @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/publican/html/images/content-updates/simple-synchronized-state-1.png b/doc/publican/html/images/content-updates/simple-synchronized-state-1.png new file mode 100644 index 00000000..be101446 Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-synchronized-state-1.png differ diff --git a/doc/publican/html/images/content-updates/simple-synchronized-state-2.png b/doc/publican/html/images/content-updates/simple-synchronized-state-2.png new file mode 100644 index 00000000..af6c64ff Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-synchronized-state-2.png differ diff --git a/doc/publican/html/images/content-updates/simple-synchronized-state-3.png b/doc/publican/html/images/content-updates/simple-synchronized-state-3.png new file mode 100644 index 00000000..7ca9ae69 Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-synchronized-state-3.png differ diff --git a/doc/publican/html/images/content-updates/simple-synchronized-state-4.png b/doc/publican/html/images/content-updates/simple-synchronized-state-4.png new file mode 100644 index 00000000..e8b9b3db Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-synchronized-state-4.png differ diff --git a/doc/publican/html/images/content-updates/simple-synchronized-state-5.png b/doc/publican/html/images/content-updates/simple-synchronized-state-5.png new file mode 100644 index 00000000..21c3414a Binary files /dev/null and b/doc/publican/html/images/content-updates/simple-synchronized-state-5.png differ diff --git a/doc/publican/html/images/content-updates/simple-synchronized.drawio b/doc/publican/html/images/content-updates/simple-synchronized.drawio new file mode 100644 index 00000000..a478ae02 --- /dev/null +++ b/doc/publican/html/images/content-updates/simple-synchronized.drawio @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case1-1.png b/doc/publican/html/images/content-updates/sync-subsurf-case1-1.png new file mode 100644 index 00000000..1f7ff8e4 Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case1-1.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case1-2.png b/doc/publican/html/images/content-updates/sync-subsurf-case1-2.png new file mode 100644 index 00000000..6839b679 Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case1-2.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case1-3.png b/doc/publican/html/images/content-updates/sync-subsurf-case1-3.png new file mode 100644 index 00000000..9810a028 Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case1-3.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case1-4.png b/doc/publican/html/images/content-updates/sync-subsurf-case1-4.png new file mode 100644 index 00000000..bf3c04bc Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case1-4.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case1-5.png b/doc/publican/html/images/content-updates/sync-subsurf-case1-5.png new file mode 100644 index 00000000..1b2ebc3b Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case1-5.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case1.drawio b/doc/publican/html/images/content-updates/sync-subsurf-case1.drawio new file mode 100644 index 00000000..385c6fd7 --- /dev/null +++ b/doc/publican/html/images/content-updates/sync-subsurf-case1.drawio @@ -0,0 +1,500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case2-1.png b/doc/publican/html/images/content-updates/sync-subsurf-case2-1.png new file mode 100644 index 00000000..25408cfc Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case2-1.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case2-2.png b/doc/publican/html/images/content-updates/sync-subsurf-case2-2.png new file mode 100644 index 00000000..63ea066c Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case2-2.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case2-3.png b/doc/publican/html/images/content-updates/sync-subsurf-case2-3.png new file mode 100644 index 00000000..3948988d Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-subsurf-case2-3.png differ diff --git a/doc/publican/html/images/content-updates/sync-subsurf-case2.drawio b/doc/publican/html/images/content-updates/sync-subsurf-case2.drawio new file mode 100644 index 00000000..c1eaff66 --- /dev/null +++ b/doc/publican/html/images/content-updates/sync-subsurf-case2.drawio @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/publican/html/images/content-updates/sync-to-desync-subsurf-1.png b/doc/publican/html/images/content-updates/sync-to-desync-subsurf-1.png new file mode 100644 index 00000000..3a56f260 Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-to-desync-subsurf-1.png differ diff --git a/doc/publican/html/images/content-updates/sync-to-desync-subsurf-2.png b/doc/publican/html/images/content-updates/sync-to-desync-subsurf-2.png new file mode 100644 index 00000000..9cb6210c Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-to-desync-subsurf-2.png differ diff --git a/doc/publican/html/images/content-updates/sync-to-desync-subsurf-3.png b/doc/publican/html/images/content-updates/sync-to-desync-subsurf-3.png new file mode 100644 index 00000000..34bf7475 Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-to-desync-subsurf-3.png differ diff --git a/doc/publican/html/images/content-updates/sync-to-desync-subsurf.drawio b/doc/publican/html/images/content-updates/sync-to-desync-subsurf.drawio new file mode 100644 index 00000000..7a72e0f6 --- /dev/null +++ b/doc/publican/html/images/content-updates/sync-to-desync-subsurf.drawio @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/publican/html/images/content-updates/sync-to-desync-transition-1.png b/doc/publican/html/images/content-updates/sync-to-desync-transition-1.png new file mode 100644 index 00000000..cd69f3c3 Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-to-desync-transition-1.png differ diff --git a/doc/publican/html/images/content-updates/sync-to-desync-transition-2.png b/doc/publican/html/images/content-updates/sync-to-desync-transition-2.png new file mode 100644 index 00000000..677a0cdb Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-to-desync-transition-2.png differ diff --git a/doc/publican/html/images/content-updates/sync-to-desync-transition-3.png b/doc/publican/html/images/content-updates/sync-to-desync-transition-3.png new file mode 100644 index 00000000..bdfdb8eb Binary files /dev/null and b/doc/publican/html/images/content-updates/sync-to-desync-transition-3.png differ diff --git a/doc/publican/html/images/content-updates/sync-to-desync-transition.drawio b/doc/publican/html/images/content-updates/sync-to-desync-transition.drawio new file mode 100644 index 00000000..9843acb6 --- /dev/null +++ b/doc/publican/html/images/content-updates/sync-to-desync-transition.drawio @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/publican/html/images/meson.build b/doc/publican/html/images/meson.build index de4cc181..c06e9be8 100644 --- a/doc/publican/html/images/meson.build +++ b/doc/publican/html/images/meson.build @@ -10,6 +10,8 @@ foreach src : files([ ) endforeach +subdir('content-updates') + foreach src : files([ 'wayland-architecture.gv', 'x-architecture.gv', diff --git a/doc/publican/meson.build b/doc/publican/meson.build index 2edf7988..fb730f5f 100644 --- a/doc/publican/meson.build +++ b/doc/publican/meson.build @@ -15,6 +15,7 @@ foreach src : files([ 'Protocol.xml', 'Xwayland.xml', 'Compositors.xml', + 'Content_Updates.xml', 'Color.xml', 'Client.xml', 'Server.xml', diff --git a/protocol/wayland.xml b/protocol/wayland.xml index 5a6a189d..de6756b4 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -1687,21 +1687,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. @@ -3140,23 +3167,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. @@ -3168,6 +3181,15 @@ 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. + + The wl_subsurface interface has requests which modify double-buffered + state of the parent surface (wl_subsurface.set_position, .place_above and + .place_below). + 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, @@ -3198,20 +3220,18 @@ - This schedules a sub-surface position change. + This sets the position of the sub-surface, relative to the parent + surface. + The sub-surface will be moved so that its origin (top left corner pixel) will be at the location x, y of the parent surface coordinate system. The coordinates are not restricted to the parent surface area. Negative values are allowed. - The scheduled coordinates will take effect whenever the state of the - parent surface is applied. - - If more than one set_position request is invoked by the client before - the commit of the parent surface, the position of a new request always - replaces the scheduled position from any previous request. - The initial position is 0, 0. + + Position is double-buffered state on the parent surface, see + wl_subsurface and wl_surface.commit for more information. @@ -3225,13 +3245,11 @@ parent surface. Using any other surface, including this sub-surface, will cause a protocol error. - The z-order is double-buffered. Requests are handled in order and - applied immediately to a pending state. The final pending state is - copied to the active state the next time the state of the parent - surface is applied. - A new sub-surface is initially added as the top-most in the stack of its siblings and parent. + + Z-order is double-buffered state on the parent surface, see + wl_subsurface and wl_surface.commit for more information. @@ -3240,6 +3258,7 @@ The sub-surface is placed just below the reference surface. + See wl_subsurface.place_above. 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. 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.