| OLD | NEW |
| 1 # `Source/core/paint` | 1 # `Source/core/paint` |
| 2 | 2 |
| 3 This directory contains implementation of painters of layout objects. It covers | 3 This directory contains implementation of painters of layout objects. It covers |
| 4 the following document lifecycle states: | 4 the following document lifecycle states: |
| 5 | 5 |
| 6 * PaintInvalidation (`InPaintInvalidation` and `PaintInvalidationClean`) | 6 * PaintInvalidation (`InPaintInvalidation` and `PaintInvalidationClean`) |
| 7 * PrePaint (`InPrePaint` and `PrePaintClean`) | 7 * PrePaint (`InPrePaint` and `PrePaintClean`) |
| 8 * Paint (`InPaint` and `PaintClean`) | 8 * Paint (`InPaint` and `PaintClean`) |
| 9 | 9 |
| 10 ## Glossaries | 10 ## Glossaries |
| 11 | 11 |
| 12 ### Stacked elements and stacking contexts | 12 ### Stacked elements and stacking contexts |
| 13 | 13 |
| 14 This chapter is basically a clarification of [CSS 2.1 appendix E. Elaborate desc
ription | 14 This chapter is basically a clarification of [CSS 2.1 appendix E. Elaborate |
| 15 of Stacking Contexts](http://www.w3.org/TR/CSS21/zindex.html). | 15 description of Stacking Contexts](http://www.w3.org/TR/CSS21/zindex.html). |
| 16 | 16 |
| 17 Note: we use 'element' instead of 'object' in this chapter to keep consistency w
ith | 17 Note: we use 'element' instead of 'object' in this chapter to keep consistency |
| 18 the spec. We use 'object' in other places in this document. | 18 with the spec. We use 'object' in other places in this document. |
| 19 | 19 |
| 20 According to the documentation, we can have the following types of elements that
are | 20 According to the documentation, we can have the following types of elements that |
| 21 treated in different ways during painting: | 21 are treated in different ways during painting: |
| 22 | 22 |
| 23 * Stacked objects: objects that are z-ordered in stacking contexts, including: | 23 * Stacked objects: objects that are z-ordered in stacking contexts, including: |
| 24 | 24 |
| 25 * Stacking contexts: elements with non-auto z-indices or other properties | 25 * Stacking contexts: elements with non-auto z-indices or other properties |
| 26 that affect stacking e.g. transform, opacity, blend-mode. | 26 that affect stacking e.g. transform, opacity, blend-mode. |
| 27 | 27 |
| 28 * Elements that are not real stacking contexts but are treated as stacking | 28 * Elements that are not real stacking contexts but are treated as stacking |
| 29 contexts but don't manage other stacked elements. Their z-ordering are | 29 contexts but don't manage other stacked elements. Their z-ordering are |
| 30 managed by real stacking contexts. They are positioned elements with | 30 managed by real stacking contexts. They are positioned elements with |
| 31 `z-index: auto` (E.2.8 in the documentation). | 31 `z-index: auto` (E.2.8 in the documentation). |
| 32 | 32 |
| 33 They must be managed by the enclosing stacking context as stacked elemen
ts | 33 They must be managed by the enclosing stacking context as stacked |
| 34 because `z-index:auto` and `z-index:0` are considered equal for stacking | 34 elements because `z-index:auto` and `z-index:0` are considered equal for |
| 35 context sorting and they may interleave by DOM order. | 35 stacking context sorting and they may interleave by DOM order. |
| 36 | 36 |
| 37 The difference of a stacked element of this type from a real stacking co
ntext | 37 The difference of a stacked element of this type from a real stacking |
| 38 is that it doesn't manage z-ordering of stacked descendants. These desce
ndants | 38 context is that it doesn't manage z-ordering of stacked descendants. |
| 39 are managed by the parent stacking context of this stacked element. | 39 These descendants are managed by the parent stacking context of this |
| 40 stacked element. |
| 40 | 41 |
| 41 "Stacked element" is not defined as a formal term in the documentation, but
we found | 42 "Stacked element" is not defined as a formal term in the documentation, but |
| 42 it convenient to use this term to refer to any elements participating z-inde
x ordering | 43 we found it convenient to use this term to refer to any elements |
| 43 in stacking contexts. | 44 participating z-index ordering in stacking contexts. |
| 44 | 45 |
| 45 A stacked element is represented by a `PaintLayerStackingNode` associated wi
th a | 46 A stacked element is represented by a `PaintLayerStackingNode` associated |
| 46 `PaintLayer`. It's painted as self-painting `PaintLayer`s by `PaintLayerPain
ter` | 47 with a `PaintLayer`. It's painted as self-painting `PaintLayer`s by |
| 47 by executing all of the steps of the painting algorithm explained in the doc
umentation | 48 `PaintLayerPainter` |
| 48 for the element. When painting a stacked element of the second type, we don'
t | 49 by executing all of the steps of the painting algorithm explained in the |
| 49 paint its stacked descendants which are managed by the parent stacking conte
xt. | 50 documentation for the element. When painting a stacked element of the second |
| 51 type, we don't paint its stacked descendants which are managed by the parent |
| 52 stacking context. |
| 50 | 53 |
| 51 * Non-stacked pseudo stacking contexts: elements that are not stacked, but pai
nt | 54 * Non-stacked pseudo stacking contexts: elements that are not stacked, but |
| 52 their descendants (excluding any stacked contents) as if they created stacki
ng | 55 paint their descendants (excluding any stacked contents) as if they created |
| 53 contexts. This includes | 56 stacking contexts. This includes |
| 54 | 57 |
| 55 * inline blocks, inline tables, inline-level replaced elements | 58 * inline blocks, inline tables, inline-level replaced elements |
| 56 (E.2.7.2.1.4 in the documentation) | 59 (E.2.7.2.1.4 in the documentation) |
| 57 * non-positioned floating elements (E.2.5 in the documentation) | 60 * non-positioned floating elements (E.2.5 in the documentation) |
| 58 * [flex items](http://www.w3.org/TR/css-flexbox-1/#painting) | 61 * [flex items](http://www.w3.org/TR/css-flexbox-1/#painting) |
| 59 * [grid items](http://www.w3.org/TR/css-grid-1/#z-order) | 62 * [grid items](http://www.w3.org/TR/css-grid-1/#z-order) |
| 60 * custom scrollbar parts | 63 * custom scrollbar parts |
| 61 | 64 |
| 62 They are painted by `ObjectPainter::paintAllPhasesAtomically()` which execut
es | 65 They are painted by `ObjectPainter::paintAllPhasesAtomically()` which |
| 63 all of the steps of the painting algorithm explained in the documentation, e
xcept | 66 executes all of the steps of the painting algorithm explained in the |
| 64 ignores any descendants which are positioned or have non-auto z-index (which
is | 67 documentation, except ignores any descendants which are positioned or have |
| 65 achieved by skipping descendants with self-painting layers). | 68 non-auto z-index (which is achieved by skipping descendants with |
| 69 self-painting layers). |
| 66 | 70 |
| 67 * Other normal elements. | 71 * Other normal elements. |
| 68 | 72 |
| 69 ### Other glossaries | 73 ### Other glossaries |
| 70 | 74 |
| 71 * Paint container: the parent of an object for painting, as defined by [CSS2.1
spec | 75 * Paint container: the parent of an object for painting, as defined by |
| 72 for painting]((http://www.w3.org/TR/CSS21/zindex.html)). For regular objects
, | 76 [CSS2.1 spec for painting]((http://www.w3.org/TR/CSS21/zindex.html)). For |
| 73 this is the parent in the DOM. For stacked objects, it's the containing stac
king | 77 regular objects, this is the parent in the DOM. For stacked objects, it's |
| 74 context-inducing object. | 78 the containing stacking context-inducing object. |
| 75 | 79 |
| 76 * Paint container chain: the chain of paint ancestors between an element and t
he | 80 * Paint container chain: the chain of paint ancestors between an element and |
| 77 root of the page. | 81 the root of the page. |
| 78 | 82 |
| 79 * Compositing container: an implementation detail of Blink, which uses | 83 * Compositing container: an implementation detail of Blink, which uses |
| 80 `PaintLayer`s to represent some layout objects. It is the ancestor along the
paint | 84 `PaintLayer`s to represent some layout objects. It is the ancestor along the |
| 81 ancestor chain which has a PaintLayer. Implemented in | 85 paint ancestor chain which has a PaintLayer. Implemented in |
| 82 `PaintLayer::compositingContainer()`. Think of it as skipping intermediate n
ormal | 86 `PaintLayer::compositingContainer()`. Think of it as skipping intermediate |
| 83 objects and going directly to the containing stacked object. | 87 normal objects and going directly to the containing stacked object. |
| 84 | 88 |
| 85 * Compositing container chain: same as paint chain, but for compositing contai
ner. | 89 * Compositing container chain: same as paint chain, but for compositing |
| 90 container. |
| 86 | 91 |
| 87 * Paint invalidation container: the nearest object on the compositing containe
r | 92 * Paint invalidation container: the nearest object on the compositing |
| 88 chain which is composited. | 93 container chain which is composited. |
| 89 | 94 |
| 90 * Visual rect: the bounding box of all pixels that will be painted by a | 95 * Visual rect: the bounding box of all pixels that will be painted by a |
| 91 display item client. | 96 display item client. |
| 92 | 97 |
| 93 ## Paint invalidation | 98 ## Paint invalidation |
| 94 | 99 |
| 95 Paint invalidation marks anything that need to be painted differently from the o
riginal | 100 Paint invalidation marks anything that need to be painted differently from the |
| 96 cached painting. | 101 original cached painting. |
| 97 | 102 |
| 98 ### Slimming paint v1 | 103 ### Slimming paint v1 |
| 99 | 104 |
| 100 Though described in this document, most of the actual paint invalidation code is
under | 105 Paint invalidation is a document cycle stage after compositing update and before |
| 101 `Source/core/layout`. | 106 paint. During the previous stages, objects are marked for needing paint |
| 102 | 107 invalidation checking if needed by style change, layout change, compositing |
| 103 Paint invalidation is a document cycle stage after compositing update and before
paint. | 108 change, etc. In paint invalidation stage, we traverse the layout tree in |
| 104 During the previous stages, objects are marked for needing paint invalidation ch
ecking | 109 pre-order, crossing frame boundaries, for marked subtrees and objects and send |
| 105 if needed by style change, layout change, compositing change, etc. In paint inva
lidation stage, | 110 the following information to `GraphicsLayer`s and `PaintController`s: |
| 106 we traverse the layout tree in pre-order, crossing frame boundaries, for marked
subtrees | |
| 107 and objects and send the following information to `GraphicsLayer`s and `PaintCon
troller`s: | |
| 108 | 111 |
| 109 * invalidated display item clients: must invalidate all display item clients | 112 * invalidated display item clients: must invalidate all display item clients |
| 110 that will generate different display items. | 113 that will generate different display items. |
| 111 | 114 |
| 112 * paint invalidation rects: must cover all areas that will generate different | 115 * paint invalidation rects: must cover all areas that will generate different |
| 113 pixels. They are generated based on visual rects of invalidated display item | 116 pixels. They are generated based on visual rects of invalidated display item |
| 114 clients. | 117 clients. |
| 115 | 118 |
| 116 #### `PaintInvalidationState` | 119 #### `PaintInvalidationState` |
| 117 | 120 |
| 118 `PaintInvalidationState` is an optimization used during the paint invalidation p
hase. Before | 121 `PaintInvalidationState` is an optimization used during the paint invalidation |
| 119 the paint invalidation tree walk, a root `PaintInvalidationState` is created for
the root | 122 phase. Before the paint invalidation tree walk, a root `PaintInvalidationState` |
| 120 `LayoutView`. During the tree walk, one `PaintInvalidationState` is created for
each visited | 123 is created for the root `LayoutView`. During the tree walk, one |
| 121 object based on the `PaintInvalidationState` passed from the parent object. | 124 `PaintInvalidationState` is created for each visited object based on the |
| 122 It tracks the following information to provide O(1) complexity access to them if
possible: | 125 `PaintInvalidationState` passed from the parent object. It tracks the following |
| 123 | 126 information to provide O(1) complexity access to them if possible: |
| 124 * Paint invalidation container: Since as indicated by the definitions in [Glos
saries](#Other glossaries), | 127 |
| 125 the paint invalidation container for stacked objects can differ from normal
objects, we | 128 * Paint invalidation container: Since as indicated by the definitions in |
| 126 have to track both separately. Here is an example: | 129 [Glossaries](#Other glossaries), the paint invalidation container for |
| 130 stacked objects can differ from normal objects, we have to track both |
| 131 separately. Here is an example: |
| 127 | 132 |
| 128 <div style="overflow: scroll"> | 133 <div style="overflow: scroll"> |
| 129 <div id=A style="position: absolute"></div> | 134 <div id=A style="position: absolute"></div> |
| 130 <div id=B></div> | 135 <div id=B></div> |
| 131 </div> | 136 </div> |
| 132 | 137 |
| 133 If the scroller is composited (for high-DPI screens for example), it is the
paint invalidation | 138 If the scroller is composited (for high-DPI screens for example), it is the |
| 134 container for div B, but not A. | 139 paint invalidation container for div B, but not A. |
| 135 | 140 |
| 136 * Paint offset and clip rect: if possible, `PaintInvalidationState` accumulate
s paint offsets | 141 * Paint offset and clip rect: if possible, `PaintInvalidationState` |
| 137 and overflow clipping rects from the paint invalidation container to provide
O(1) complexity to | 142 accumulates paint offsets and overflow clipping rects from the paint |
| 138 map a point or a rect in current object's local space to paint invalidation
container's space. | 143 invalidation container to provide O(1) complexity to map a point or a rect |
| 139 Because locations of objects are determined by their containing blocks, and
the containing block | 144 in current object's local space to paint invalidation container's space. |
| 140 for absolute-position objects differs from non-absolute, we track paint offs
ets and overflow | 145 Because locations of objects are determined by their containing blocks, and |
| 141 clipping rects for absolute-position objects separately. | 146 the containing block for absolute-position objects differs from |
| 142 | 147 non-absolute, we track paint offsets and overflow clipping rects for |
| 143 In cases that accurate accumulation of paint offsets and clipping rects is impos
sible, | 148 absolute-position objects separately. |
| 144 we will fall back to slow-path using `LayoutObject::localToAncestorPoint()` or | 149 |
| 145 `LayoutObject::mapToVisualRectInAncestorSpace()`. This includes the following ca
ses: | 150 In cases that accurate accumulation of paint offsets and clipping rects is |
| 146 | 151 impossible, we will fall back to slow-path using |
| 147 * An object has transform related property, is multi-column or has flipped blo
cks writing-mode, | 152 `LayoutObject::localToAncestorPoint()` or |
| 148 causing we can't simply accumulate paint offset for mapping a local rect to
paint invalidation | 153 `LayoutObject::mapToVisualRectInAncestorSpace()`. This includes the following |
| 149 container; | 154 cases: |
| 155 |
| 156 * An object has transform related property, is multi-column or has flipped |
| 157 blocks writing-mode, causing we can't simply accumulate paint offset for |
| 158 mapping a local rect to paint invalidation container; |
| 150 | 159 |
| 151 * An object has has filter (including filter induced by reflection), which | 160 * An object has has filter (including filter induced by reflection), which |
| 152 needs to expand visual rect for descendants, because currently we don't | 161 needs to expand visual rect for descendants, because currently we don't |
| 153 include and filter extents into visual overflow; | 162 include and filter extents into visual overflow; |
| 154 | 163 |
| 155 * For a fixed-position object we calculate its offset using `LayoutObject::loc
alToAncestorPoint()`, | 164 * For a fixed-position object we calculate its offset using |
| 156 but map for its descendants in fast-path if no other things prevent us from
doing this; | 165 `LayoutObject::localToAncestorPoint()`, but map for its descendants in |
| 157 | 166 fast-path if no other things prevent us from doing this; |
| 158 * Because we track paint offset from the normal paint invalidation container o
nly, if we are going | 167 |
| 159 to use `m_paintInvalidationContainerForStackedContents` and it's different f
rom the normal paint | 168 * Because we track paint offset from the normal paint invalidation container |
| 160 invalidation container, we have to force slow-path because the accumulated p
aint offset is not | 169 only, if we are going to use |
| 161 usable; | 170 `m_paintInvalidationContainerForStackedContents` and it's different from the |
| 162 | 171 normal paint invalidation container, we have to force slow-path because the |
| 163 * We also stop to track paint offset and clipping rect for absolute-position o
bjects when | 172 accumulated paint offset is not usable; |
| 164 `m_paintInvalidationContainerForStackedContents` becomes different from `m_p
aintInvalidationContainer`. | 173 |
| 174 * We also stop to track paint offset and clipping rect for absolute-position |
| 175 objects when `m_paintInvalidationContainerForStackedContents` becomes |
| 176 different from `m_paintInvalidationContainer`. |
| 165 | 177 |
| 166 ### Paint invalidation of texts | 178 ### Paint invalidation of texts |
| 167 | 179 |
| 168 Texts are painted by `InlineTextBoxPainter` using `InlineTextBox` as display ite
m client. | 180 Texts are painted by `InlineTextBoxPainter` using `InlineTextBox` as display |
| 169 Text backgrounds and masks are painted by `InlineTextFlowPainter` using `InlineF
lowBox` | 181 item client. Text backgrounds and masks are painted by `InlineTextFlowPainter` |
| 170 as display item client. We should invalidate these display item clients when the
ir painting | 182 using `InlineFlowBox` as display item client. We should invalidate these display |
| 171 will change. | 183 item clients when their painting will change. |
| 172 | 184 |
| 173 `LayoutInline`s and `LayoutText`s are marked for full paint invalidation if need
ed when | 185 `LayoutInline`s and `LayoutText`s are marked for full paint invalidation if |
| 174 new style is set on them. During paint invalidation, we invalidate the `InlineFl
owBox`s | 186 needed when new style is set on them. During paint invalidation, we invalidate |
| 175 directly contained by the `LayoutInline` in `LayoutInline::invalidateDisplayItem
Clients()` and | 187 the `InlineFlowBox`s directly contained by the `LayoutInline` in |
| 176 `InlineTextBox`s contained by the `LayoutText` in `LayoutText::invalidateDisplay
ItemClients()`. | 188 `LayoutInline::invalidateDisplayItemClients()` and `InlineTextBox`s contained by |
| 177 We don't need to traverse into the subtree of `InlineFlowBox`s in `LayoutInline:
:invalidateDisplayItemClients()` | 189 the `LayoutText` in `LayoutText::invalidateDisplayItemClients()`. We don't need |
| 178 because the descendant `InlineFlowBox`s and `InlineTextBox`s will be handled by
their | 190 to traverse into the subtree of `InlineFlowBox`s in |
| 179 owning `LayoutInline`s and `LayoutText`s, respectively, when changed style is pr
opagated. | 191 `LayoutInline::invalidateDisplayItemClients()` because the descendant |
| 192 `InlineFlowBox`s and `InlineTextBox`s will be handled by their owning |
| 193 `LayoutInline`s and `LayoutText`s, respectively, when changed style is propagate
d. |
| 180 | 194 |
| 181 ### Specialty of `::first-line` | 195 ### Specialty of `::first-line` |
| 182 | 196 |
| 183 `::first-line` pseudo style dynamically applies to all `InlineBox`'s in the firs
t line in the | 197 `::first-line` pseudo style dynamically applies to all `InlineBox`'s in the |
| 184 block having `::first-line` style. The actual applied style is computed from the
`::first-line` | 198 first line in the block having `::first-line` style. The actual applied style is |
| 185 style and other applicable styles. | 199 computed from the `::first-line` style and other applicable styles. |
| 186 | 200 |
| 187 If the first line contains any `LayoutInline`, we compute the style from the `::
first-line` style | 201 If the first line contains any `LayoutInline`, we compute the style from the |
| 188 and the style of the `LayoutInline` and apply the computed style to the first li
ne part of the | 202 `::first-line` style and the style of the `LayoutInline` and apply the computed |
| 189 `LayoutInline`. In blink's style implementation, the combined first line style o
f `LayoutInline` | 203 style to the first line part of the `LayoutInline`. In Blink's style |
| 190 is identified with `FIRST_LINE_INHERITED` pseudo ID. | 204 implementation, the combined first line style of `LayoutInline` is identified |
| 205 with `FIRST_LINE_INHERITED` pseudo ID. |
| 191 | 206 |
| 192 The normal paint invalidation of texts doesn't work for first line because | 207 The normal paint invalidation of texts doesn't work for first line because |
| 193 * `ComputedStyle::visualInvalidationDiff()` can't detect first line style chan
ges; | 208 * `ComputedStyle::visualInvalidationDiff()` can't detect first line style |
| 194 * The normal paint invalidation is based on whole LayoutObject's, not aware of
the first line. | 209 changes; |
| 195 | 210 * The normal paint invalidation is based on whole LayoutObject's, not aware of |
| 196 We have a special path for first line style change: the style system informs the
layout system | 211 the first line. |
| 197 when the computed first-line style changes through `LayoutObject::firstLineStyle
DidChange()`. | 212 |
| 198 When this happens, we invalidate all `InlineBox`es in the first line. | 213 We have a special path for first line style change: the style system informs the |
| 214 layout system when the computed first-line style changes through |
| 215 `LayoutObject::firstLineStyleDidChange()`. When this happens, we invalidate all |
| 216 `InlineBox`es in the first line. |
| 199 | 217 |
| 200 ### Slimming paint v2 | 218 ### Slimming paint v2 |
| 201 | 219 |
| 202 TODO(wangxianzhu): add details | 220 TODO(wangxianzhu): add details |
| 203 | 221 |
| 204 ## [`PrePaintTreeWalk`](PrePaintTreeWalk.h) (Slimming paint v2 only) | 222 ## [`PrePaintTreeWalk`](PrePaintTreeWalk.h) (Slimming Paint invalidation/v2 only
) |
| 205 | 223 |
| 206 During `InPrePaint` document lifecycle state, this class is called to walk the w
hole | 224 During `InPrePaint` document lifecycle state, this class is called to walk the |
| 207 layout tree, beginning from the root FrameView, across frame boundaries. We do t
he | 225 whole layout tree, beginning from the root FrameView, across frame boundaries. |
| 208 following during the tree walk: | 226 We do the following during the tree walk: |
| 209 | 227 |
| 210 * Building paint property tree: creates paint property tree nodes for special | 228 ### Building paint property trees |
| 211 things in the layout tree, including but not limit to: overflow clip, transf
orm, | 229 [`PaintPropertyTreeBuilder`](PaintPropertyTreeBuilder.h) |
| 212 fixed-pos, animation, mask, filter, etc. Also sets direct compositing reason
s to be | 230 |
| 213 used later for compositing. | 231 This class is responsible for building property trees |
| 214 | 232 (see [the platform paint README file](../../platform/graphics/paint/README.md)). |
| 215 * Paint invalidation: Not implemented yet. TODO(wangxianzhu): add details afte
r | 233 |
| 216 it's implemented. | 234 Each `PaintLayer`'s `LayoutObject` has one or more `FragmentData` objects (see |
| 235 below for more on fragments). Every `FragmentData` has an |
| 236 `ObjectPaintProperties` object if any property nodes are induced by it. For |
| 237 example, if the object has a transform, its `ObjectPaintProperties::Transform()` |
| 238 field points at the `TransformPaintPropertyNode` representing that transform. |
| 239 |
| 240 The `NeedsPaintPropertyUpdate`, `SubtreeNeedsPaintPropertyUpdate` and |
| 241 `DescendantNeedsPaintPropertyUpdate` dirty bits on `LayoutObject` control how |
| 242 much of the layout tree is traversed during each `PrePaintTreeWalk`. |
| 243 |
| 244 ### Fragments |
| 245 |
| 246 In the absence of multicolumn/pagination, there is a 1:1 correspondence between |
| 247 self-painting `PaintLayer`s and `FragmentData`. If there is |
| 248 multicolumn/pagination, there may be more `FragmentData`s.. If a `PaintLayer` |
| 249 has a property node, each of its fragments will have one. The parent of a |
| 250 fragment's property node is the property node that belongs to the ancestor |
| 251 `PaintLayer` which is part of the same column. For example, if there are 3 |
| 252 columns and both a parent and child `PaintLayer` have a transform, there will be |
| 253 3 `FragmentData` objects for the parent, 3 for the child, each `FragmentData` |
| 254 will have its own `TransformPaintPropertyNode`, and the child's ith fragment's |
| 255 transform will point to the ith parent's transform. |
| 256 |
| 257 See [`LayoutMultiColumnFlowThread.h`](../layout/LayoutMultiColumnFlowThread.h) |
| 258 for a much more detail about multicolumn/pagination. |
| 259 |
| 260 ### Paint invalidation: `PaintInvalidator` implements a tree walk that |
| 261 performs paint invalidation. TODO(wangxianzhu): expand on this. |
| 262 |
| 263 ### [`PaintPropertyTreeBuilder`](PaintPropertyTreeBuilder.h) (Slimming Paint inv
alidation only) |
| 217 | 264 |
| 218 ## Paint result caching | 265 ## Paint result caching |
| 219 | 266 |
| 220 `PaintController` holds the previous painting result as a cache of display items
. | 267 `PaintController` holds the previous painting result as a cache of display |
| 221 If some painter would generate results same as those of the previous painting, | 268 items. If some painter would generate results same as those of the previous |
| 222 we'll skip the painting and reuse the display items from cache. | 269 painting, we'll skip the painting and reuse the display items from cache. |
| 223 | 270 |
| 224 ### Display item caching | 271 ### Display item caching |
| 225 | 272 |
| 226 When a painter would create a `DrawingDisplayItem` exactly the same as the displ
ay item | 273 When a painter would create a `DrawingDisplayItem` exactly the same as the |
| 227 created in the previous painting, we'll reuse the previous one instead of repain
ting it. | 274 display item created in the previous painting, we'll reuse the previous one |
| 275 instead of repainting it. |
| 228 | 276 |
| 229 ### Subsequence caching | 277 ### Subsequence caching |
| 230 | 278 |
| 231 When possible, we enclose the display items that `PaintLayerPainter::paintConten
ts()` generates | 279 When possible, we enclose the display items that |
| 232 (including display items generated by sublayers) in a pair of `BeginSubsequence/
EndSubsequence` | 280 `PaintLayerPainter::paintContents()` generates (including display items |
| 233 display items. | 281 generated by sublayers) in a pair of `BeginSubsequence/EndSubsequence` display |
| 234 | 282 items. |
| 235 In a subsequence paint, if the layer would generate exactly the same display ite
ms, we'll get | 283 |
| 236 the whole subsequence from the cache instead of repainting them. | 284 In a subsequence paint, if the layer would generate exactly the same display |
| 285 items, we'll get the whole subsequence from the cache instead of repainting |
| 286 them. |
| 237 | 287 |
| 238 There are many conditions affecting | 288 There are many conditions affecting |
| 239 * whether we need to generate subsequence for a PaintLayer; | 289 * whether we need to generate subsequence for a PaintLayer; |
| 240 * whether we can use cached subsequence for a PaintLayer. | 290 * whether we can use cached subsequence for a PaintLayer. |
| 241 See `shouldCreateSubsequence()` and `shouldRepaintSubsequence()` in `PaintLayerP
ainter.cpp` for | 291 See `shouldCreateSubsequence()` and `shouldRepaintSubsequence()` in |
| 242 the conditions. | 292 `PaintLayerPainter.cpp` for the conditions. |
| 243 | 293 |
| 244 ## Empty paint phase optimization | 294 ## Empty paint phase optimization |
| 245 | 295 |
| 246 During painting, we walk the layout tree multiple times for multiple paint phase
s. Sometimes | 296 During painting, we walk the layout tree multiple times for multiple paint |
| 247 a layer contain nothing needing a certain paint phase and we can skip tree walk
for such | 297 phases. Sometimes a layer contain nothing needing a certain paint phase and we |
| 248 empty phases. Now we have optimized `PaintPhaseDescendantBlockBackgroundsOnly`, | 298 can skip tree walk for such empty phases. Now we have optimized |
| 249 `PaintPhaseDescendantOutlinesOnly` and `PaintPhaseFloat` for empty paint phases. | 299 `PaintPhaseDescendantBlockBackgroundsOnly`, `PaintPhaseDescendantOutlinesOnly` |
| 250 | 300 and `PaintPhaseFloat` for empty paint phases. |
| 251 During paint invalidation, we set the containing self-painting layer's `needsPai
ntPhaseXXX` | 301 |
| 252 flag if the object has something needing to be painted in the paint phase. | 302 During paint invalidation, we set the containing self-painting layer's |
| 253 | 303 `needsPaintPhaseXXX` flag if the object has something needing to be painted in |
| 254 During painting, we check the flag before painting a paint phase and skip the tr
ee walk if | 304 the paint phase. |
| 255 the flag is not set. | 305 |
| 256 | 306 During painting, we check the flag before painting a paint phase and skip the |
| 257 It's hard to clear a `needsPaintPhaseXXX` flag when a layer no longer needs the
paint phase, | 307 tree walk if the flag is not set. |
| 258 so we never clear the flags. Instead, we use another set of flags (`previousPain
tPhaseXXXWasEmpty`) | 308 |
| 259 to record if a painting of a phase actually produced nothing. We'll skip the nex
t | 309 It's hard to clear a `needsPaintPhaseXXX` flag when a layer no longer needs the |
| 260 painting of the phase if the flag is set, regardless of the corresponding | 310 paint phase, so we never clear the flags. Instead, we use another set of flags |
| 261 `needsPaintPhaseXXX` flag. We will clear the `previousPaintPhaseXXXWasEmpty` fla
gs when | 311 (`previousPaintPhaseXXXWasEmpty`) to record if a painting of a phase actually |
| 262 we paint with different clipping, scroll offset or interest rect from the previo
us paint. | 312 produced nothing. We'll skip the next painting of the phase if the flag is set, |
| 263 | 313 regardless of the corresponding `needsPaintPhaseXXX` flag. We will clear the |
| 264 We don't clear the `previousPaintPhaseXXXWasEmpty` flags when the layer is marke
d `needsRepaint`. | 314 `previousPaintPhaseXXXWasEmpty` flags when we paint with different clipping, |
| 265 Instead we clear the flag when the corresponding `needsPaintPhaseXXX` is set. Th
is ensures that | 315 scroll offset or interest rect from the previous paint. |
| 266 we won't clear `previousPaintPhaseXXXWasEmpty` flags when unrelated things chang
ed which won't | 316 |
| 317 We don't clear the `previousPaintPhaseXXXWasEmpty` flags when the layer is |
| 318 marked `needsRepaint`. Instead we clear the flag when the corresponding |
| 319 `needsPaintPhaseXXX` is set. This ensures that we won't clear |
| 320 `previousPaintPhaseXXXWasEmpty` flags when unrelated things changed which won't |
| 267 cause the paint phases to become non-empty. | 321 cause the paint phases to become non-empty. |
| 268 | 322 |
| 269 When layer structure changes, and we are not invalidate paint of the changed sub
tree, | 323 When layer structure changes, and we are not invalidate paint of the changed |
| 270 we need to manually update the `needsPaintPhaseXXX` flags. For example, if an ob
ject changes | 324 subtree, we need to manually update the `needsPaintPhaseXXX` flags. For example, |
| 271 style and creates a self-painting-layer, we copy the flags from its containing s
elf-painting | 325 if an object changes style and creates a self-painting-layer, we copy the flags |
| 272 layer to this layer, assuming that this layer needs all paint phases that its co
ntainer | 326 from its containing self-painting layer to this layer, assuming that this layer |
| 273 self-painting layer needs. | 327 needs all paint phases that its container self-painting layer needs. |
| 274 | 328 |
| 275 We could update the `needsPaintPhaseXXX` flags in a separate tree walk, but that
would regress | 329 We could update the `needsPaintPhaseXXX` flags in a separate tree walk, but that |
| 276 performance of the first paint. For slimming paint v2, we can update the flags d
uring the | 330 would regress performance of the first paint. For slimming paint v2, we can |
| 277 pre-painting tree walk to simplify the logics. | 331 update the flags during the pre-painting tree walk to simplify the logics. |
| OLD | NEW |