Chromium Code Reviews| 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 phases: |
| 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 | 14 This chapter is basically a clarification of [CSS 2.1 appendix E. Elaborate |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 * Compositing container: an implementation detail of Blink, which uses | 83 * Compositing container: an implementation detail of Blink, which uses |
| 84 `PaintLayer`s to represent some layout objects. It is the ancestor along the | 84 `PaintLayer`s to represent some layout objects. It is the ancestor along the |
| 85 paint ancestor chain which has a PaintLayer. Implemented in | 85 paint ancestor chain which has a PaintLayer. Implemented in |
| 86 `PaintLayer::compositingContainer()`. Think of it as skipping intermediate | 86 `PaintLayer::compositingContainer()`. Think of it as skipping intermediate |
| 87 normal objects and going directly to the containing stacked object. | 87 normal objects and going directly to the containing stacked object. |
| 88 | 88 |
| 89 * Compositing container chain: same as paint chain, but for compositing | 89 * Compositing container chain: same as paint chain, but for compositing |
| 90 container. | 90 container. |
| 91 | 91 |
| 92 * Paint invalidation container: the nearest object on the compositing | 92 * Paint invalidation container: the nearest object on the compositing |
| 93 container chain which is composited. | 93 container chain which is composited. Slimming paint V2 doesn't have this |
| 94 concept. | |
| 94 | 95 |
| 95 * Visual rect: the bounding box of all pixels that will be painted by a | 96 * Visual rect: the bounding box of all pixels that will be painted by a |
| 96 display item client. | 97 display item client. |
| 97 | 98 |
| 98 ## Paint invalidation | 99 ## PaintInvalidation phase (Deprecated by [PrePaint phase](#PrePaint_phase)) |
| 99 | 100 |
| 100 Paint invalidation marks anything that need to be painted differently from the | 101 Paint invalidation marks anything that need to be painted differently from the |
| 101 original cached painting. | 102 original cached painting. |
| 102 | 103 |
| 103 ### Slimming paint v1 | |
| 104 | |
| 105 Paint invalidation is a document cycle stage after compositing update and before | 104 Paint invalidation is a document cycle stage after compositing update and before |
| 106 paint. During the previous stages, objects are marked for needing paint | 105 paint. During the previous stages, objects are marked for needing paint |
| 107 invalidation checking if needed by style change, layout change, compositing | 106 invalidation checking if needed by style change, layout change, compositing |
| 108 change, etc. In paint invalidation stage, we traverse the layout tree in | 107 change, etc. In paint invalidation stage, we traverse the layout tree in |
| 109 pre-order, crossing frame boundaries, for marked subtrees and objects and send | 108 pre-order, crossing frame boundaries, for marked subtrees and objects and send |
| 110 the following information to `GraphicsLayer`s and `PaintController`s: | 109 the following information to `GraphicsLayer`s and `PaintController`s: |
| 111 | 110 |
| 112 * invalidated display item clients: must invalidate all display item clients | 111 * invalidated display item clients: must invalidate all display item clients |
| 113 that will generate different display items. | 112 that will generate different display items. |
| 114 | 113 |
| 115 * paint invalidation rects: must cover all areas that will generate different | 114 * paint invalidation rects: must cover all areas that will generate different |
| 116 pixels. They are generated based on visual rects of invalidated display item | 115 pixels. They are generated based on visual rects of invalidated display item |
| 117 clients. | 116 clients. |
| 118 | 117 |
| 119 #### `PaintInvalidationState` | 118 ### `PaintInvalidationState` |
| 120 | 119 |
| 121 `PaintInvalidationState` is an optimization used during the paint invalidation | 120 `PaintInvalidationState` is an optimization used during the paint invalidation |
| 122 phase. Before the paint invalidation tree walk, a root `PaintInvalidationState` | 121 phase. Before the paint invalidation tree walk, a root `PaintInvalidationState` |
| 123 is created for the root `LayoutView`. During the tree walk, one | 122 is created for the root `LayoutView`. During the tree walk, one |
| 124 `PaintInvalidationState` is created for each visited object based on the | 123 `PaintInvalidationState` is created for each visited object based on the |
| 125 `PaintInvalidationState` passed from the parent object. It tracks the following | 124 `PaintInvalidationState` passed from the parent object. It tracks the following |
| 126 information to provide O(1) complexity access to them if possible: | 125 information to provide O(1) complexity access to them if possible: |
| 127 | 126 |
| 128 * Paint invalidation container: Since as indicated by the definitions in | 127 * Paint invalidation container: Since as indicated by the definitions in |
| 129 [Glossaries](#Other glossaries), the paint invalidation container for | 128 [Glossaries](#Other glossaries), the paint invalidation container for |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 ### Paint invalidation of texts | 177 ### Paint invalidation of texts |
| 179 | 178 |
| 180 Texts are painted by `InlineTextBoxPainter` using `InlineTextBox` as display | 179 Texts are painted by `InlineTextBoxPainter` using `InlineTextBox` as display |
| 181 item client. Text backgrounds and masks are painted by `InlineTextFlowPainter` | 180 item client. Text backgrounds and masks are painted by `InlineTextFlowPainter` |
| 182 using `InlineFlowBox` as display item client. We should invalidate these display | 181 using `InlineFlowBox` as display item client. We should invalidate these display |
| 183 item clients when their painting will change. | 182 item clients when their painting will change. |
| 184 | 183 |
| 185 `LayoutInline`s and `LayoutText`s are marked for full paint invalidation if | 184 `LayoutInline`s and `LayoutText`s are marked for full paint invalidation if |
| 186 needed when new style is set on them. During paint invalidation, we invalidate | 185 needed when new style is set on them. During paint invalidation, we invalidate |
| 187 the `InlineFlowBox`s directly contained by the `LayoutInline` in | 186 the `InlineFlowBox`s directly contained by the `LayoutInline` in |
| 188 `LayoutInline::invalidateDisplayItemClients()` and `InlineTextBox`s contained by | 187 `LayoutInline::InvalidateDisplayItemClients()` and `InlineTextBox`s contained by |
| 189 the `LayoutText` in `LayoutText::invalidateDisplayItemClients()`. We don't need | 188 the `LayoutText` in `LayoutText::InvalidateDisplayItemClients()`. We don't need |
| 190 to traverse into the subtree of `InlineFlowBox`s in | 189 to traverse into the subtree of `InlineFlowBox`s in |
| 191 `LayoutInline::invalidateDisplayItemClients()` because the descendant | 190 `LayoutInline::InvalidateDisplayItemClients()` because the descendant |
| 192 `InlineFlowBox`s and `InlineTextBox`s will be handled by their owning | 191 `InlineFlowBox`s and `InlineTextBox`s will be handled by their owning |
| 193 `LayoutInline`s and `LayoutText`s, respectively, when changed style is propagate d. | 192 `LayoutInline`s and `LayoutText`s, respectively, when changed style is propagate d. |
| 194 | 193 |
| 195 ### Specialty of `::first-line` | 194 ### Specialty of `::first-line` |
| 196 | 195 |
| 197 `::first-line` pseudo style dynamically applies to all `InlineBox`'s in the | 196 `::first-line` pseudo style dynamically applies to all `InlineBox`'s in the |
| 198 first line in the block having `::first-line` style. The actual applied style is | 197 first line in the block having `::first-line` style. The actual applied style is |
| 199 computed from the `::first-line` style and other applicable styles. | 198 computed from the `::first-line` style and other applicable styles. |
| 200 | 199 |
| 201 If the first line contains any `LayoutInline`, we compute the style from the | 200 If the first line contains any `LayoutInline`, we compute the style from the |
| 202 `::first-line` style and the style of the `LayoutInline` and apply the computed | 201 `::first-line` style and the style of the `LayoutInline` and apply the computed |
| 203 style to the first line part of the `LayoutInline`. In Blink's style | 202 style to the first line part of the `LayoutInline`. In Blink's style |
| 204 implementation, the combined first line style of `LayoutInline` is identified | 203 implementation, the combined first line style of `LayoutInline` is identified |
| 205 with `FIRST_LINE_INHERITED` pseudo ID. | 204 with `FIRST_LINE_INHERITED` pseudo ID. |
| 206 | 205 |
| 207 The normal paint invalidation of texts doesn't work for first line because | 206 The normal paint invalidation of texts doesn't work for first line because |
| 208 * `ComputedStyle::visualInvalidationDiff()` can't detect first line style | 207 * `ComputedStyle::VisualInvalidationDiff()` can't detect first line style |
| 209 changes; | 208 changes; |
| 210 * The normal paint invalidation is based on whole LayoutObject's, not aware of | 209 * The normal paint invalidation is based on whole LayoutObject's, not aware of |
| 211 the first line. | 210 the first line. |
| 212 | 211 |
| 213 We have a special path for first line style change: the style system informs the | 212 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 | 213 layout system when the computed first-line style changes through |
| 215 `LayoutObject::firstLineStyleDidChange()`. When this happens, we invalidate all | 214 `LayoutObject::FirstLineStyleDidChange()`. When this happens, we invalidate all |
| 216 `InlineBox`es in the first line. | 215 `InlineBox`es in the first line. |
| 217 | 216 |
| 218 ### Slimming paint v2 | 217 ## PrePaint phase (Slimming paint invalidation/v2 only) |
| 219 | 218 [`PrePaintTreeWalk`](PrePaintTreeWalk.h) |
| 220 TODO(wangxianzhu): add details | |
| 221 | |
| 222 ## [`PrePaintTreeWalk`](PrePaintTreeWalk.h) (Slimming Paint invalidation/v2 only ) | |
| 223 | 219 |
| 224 During `InPrePaint` document lifecycle state, this class is called to walk the | 220 During `InPrePaint` document lifecycle state, this class is called to walk the |
| 225 whole layout tree, beginning from the root FrameView, across frame boundaries. | 221 whole layout tree, beginning from the root FrameView, across frame boundaries. |
| 226 We do the following during the tree walk: | 222 We do the following during the tree walk: |
| 227 | 223 |
| 228 ### Building paint property trees | 224 ### Building paint property trees |
| 229 [`PaintPropertyTreeBuilder`](PaintPropertyTreeBuilder.h) | 225 [`PaintPropertyTreeBuilder`](PaintPropertyTreeBuilder.h) |
| 230 | 226 |
| 231 This class is responsible for building property trees | 227 This class is responsible for building property trees |
| 232 (see [the platform paint README file](../../platform/graphics/paint/README.md)). | 228 (see [the platform paint README file](../../platform/graphics/paint/README.md)). |
| 233 | 229 |
| 234 Each `PaintLayer`'s `LayoutObject` has one or more `FragmentData` objects (see | 230 Each `PaintLayer`'s `LayoutObject` has one or more `FragmentData` objects (see |
| 235 below for more on fragments). Every `FragmentData` has an | 231 below for more on fragments). Every `FragmentData` has an |
| 236 `ObjectPaintProperties` object if any property nodes are induced by it. For | 232 `ObjectPaintProperties` object if any property nodes are induced by it. For |
| 237 example, if the object has a transform, its `ObjectPaintProperties::Transform()` | 233 example, if the object has a transform, its `ObjectPaintProperties::Transform()` |
| 238 field points at the `TransformPaintPropertyNode` representing that transform. | 234 field points at the `TransformPaintPropertyNode` representing that transform. |
| 239 | 235 |
| 240 The `NeedsPaintPropertyUpdate`, `SubtreeNeedsPaintPropertyUpdate` and | 236 The `NeedsPaintPropertyUpdate`, `SubtreeNeedsPaintPropertyUpdate` and |
| 241 `DescendantNeedsPaintPropertyUpdate` dirty bits on `LayoutObject` control how | 237 `DescendantNeedsPaintPropertyUpdate` dirty bits on `LayoutObject` control how |
| 242 much of the layout tree is traversed during each `PrePaintTreeWalk`. | 238 much of the layout tree is traversed during each `PrePaintTreeWalk`. |
| 243 | 239 |
| 244 ### Fragments | 240 #### Fragments |
| 245 | 241 |
| 246 In the absence of multicolumn/pagination, there is a 1:1 correspondence between | 242 In the absence of multicolumn/pagination, there is a 1:1 correspondence between |
| 247 self-painting `PaintLayer`s and `FragmentData`. If there is | 243 self-painting `PaintLayer`s and `FragmentData`. If there is |
| 248 multicolumn/pagination, there may be more `FragmentData`s.. If a `PaintLayer` | 244 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 | 245 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 | 246 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 | 247 `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 | 248 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` | 249 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 | 250 will have its own `TransformPaintPropertyNode`, and the child's ith fragment's |
| 255 transform will point to the ith parent's transform. | 251 transform will point to the ith parent's transform. |
| 256 | 252 |
| 257 See [`LayoutMultiColumnFlowThread.h`](../layout/LayoutMultiColumnFlowThread.h) | 253 See [`LayoutMultiColumnFlowThread.h`](../layout/LayoutMultiColumnFlowThread.h) |
| 258 for a much more detail about multicolumn/pagination. | 254 for a much more detail about multicolumn/pagination. |
| 259 | 255 |
| 260 ### Paint invalidation: `PaintInvalidator` implements a tree walk that | 256 ### Paint invalidation |
| 261 performs paint invalidation. TODO(wangxianzhu): expand on this. | 257 [`PaintInvalidator](PaintInvalidator.h) |
|
wkorman
2017/05/01 18:03:29
Missing closing `
Xianzhu
2017/05/01 19:11:48
Done.
| |
| 262 | 258 |
| 263 ### [`PaintPropertyTreeBuilder`](PaintPropertyTreeBuilder.h) (Slimming Paint inv alidation only) | 259 This class replaces [`PaintInvalidationState`] for SlimmingPaintInvalidation. |
| 260 The main difference is that in PaintInvalidator, visual rects and locations | |
| 261 are computed by `GeometryMapper`(../../platform/graphics/paint/GeometryMapper.h) , | |
| 262 based on paint properties produced by `PaintPropertyTreeBuilder`. | |
| 264 | 263 |
| 265 ## Paint result caching | 264 TODO(wangxianzhu): Combine documentation of PaintInvalidation phase into here. |
| 265 | |
| 266 ## Paint phase | |
| 267 | |
| 268 ### Paint result caching | |
| 266 | 269 |
| 267 `PaintController` holds the previous painting result as a cache of display | 270 `PaintController` holds the previous painting result as a cache of display |
| 268 items. If some painter would generate results same as those of the previous | 271 items. If some painter would generate results same as those of the previous |
| 269 painting, we'll skip the painting and reuse the display items from cache. | 272 painting, we'll skip the painting and reuse the display items from cache. |
| 270 | 273 |
| 271 ### Display item caching | 274 #### Display item caching |
| 272 | 275 |
| 273 When a painter would create a `DrawingDisplayItem` exactly the same as the | 276 When a painter would create a `DrawingDisplayItem` exactly the same as the |
| 274 display item created in the previous painting, we'll reuse the previous one | 277 display item created in the previous painting, we'll reuse the previous one |
| 275 instead of repainting it. | 278 instead of repainting it. |
| 276 | 279 |
| 277 ### Subsequence caching | 280 #### Subsequence caching |
| 278 | 281 |
| 279 When possible, we enclose the display items that | 282 When possible, we create a scoped `SubsequenceRecorder` in |
| 280 `PaintLayerPainter::paintContents()` generates (including display items | 283 `PaintLayerPainter::PaintContents()` to record all display items generated in |
| 281 generated by sublayers) in a pair of `BeginSubsequence/EndSubsequence` display | 284 the scope as a "subsequence". Before painting a layer, if we are sure that the |
| 282 items. | 285 layer will generate exactly the same display items as the previous paint, we'll |
| 283 | 286 get 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. | |
| 287 | 287 |
| 288 There are many conditions affecting | 288 There are many conditions affecting |
| 289 * whether we need to generate subsequence for a PaintLayer; | 289 * whether we need to generate subsequence for a PaintLayer; |
| 290 * whether we can use cached subsequence for a PaintLayer. | 290 * whether we can use cached subsequence for a PaintLayer. |
| 291 See `shouldCreateSubsequence()` and `shouldRepaintSubsequence()` in | 291 See `ShouldCreateSubsequence()` and `shouldRepaintSubsequence()` in |
| 292 `PaintLayerPainter.cpp` for the conditions. | 292 `PaintLayerPainter.cpp` for the conditions. |
| 293 | 293 |
| 294 ## Empty paint phase optimization | 294 ### Empty paint phase optimization |
| 295 | 295 |
| 296 During painting, we walk the layout tree multiple times for multiple paint | 296 During painting, we walk the layout tree multiple times for multiple paint |
| 297 phases. Sometimes a layer contain nothing needing a certain paint phase and we | 297 phases. Sometimes a layer contain nothing needing a certain paint phase and we |
| 298 can skip tree walk for such empty phases. Now we have optimized | 298 can skip tree walk for such empty phases. Now we have optimized |
| 299 `PaintPhaseDescendantBlockBackgroundsOnly`, `PaintPhaseDescendantOutlinesOnly` | 299 `PaintPhaseDescendantBlockBackgroundsOnly`, `PaintPhaseDescendantOutlinesOnly` |
| 300 and `PaintPhaseFloat` for empty paint phases. | 300 and `PaintPhaseFloat` for empty paint phases. |
| 301 | 301 |
| 302 During paint invalidation, we set the containing self-painting layer's | 302 During paint invalidation, we set the containing self-painting layer's |
| 303 `needsPaintPhaseXXX` flag if the object has something needing to be painted in | 303 `NeedsPaintPhaseXXX` flag if the object has something needing to be painted in |
| 304 the paint phase. | 304 the paint phase. |
| 305 | 305 |
| 306 During painting, we check the flag before painting a paint phase and skip the | 306 During painting, we check the flag before painting a paint phase and skip the |
| 307 tree walk if the flag is not set. | 307 tree walk if the flag is not set. |
| 308 | 308 |
| 309 It's hard to clear a `needsPaintPhaseXXX` flag when a layer no longer needs the | 309 It's hard to clear a `NeedsPaintPhaseXXX` flag when a layer no longer needs the |
| 310 paint phase, so we never clear the flags. Instead, we use another set of flags | 310 paint phase, so we never clear the flags. Instead, we use another set of flags |
| 311 (`previousPaintPhaseXXXWasEmpty`) to record if a painting of a phase actually | 311 (`PreviousPaintPhaseXXXWasEmpty`) to record if a painting of a phase actually |
| 312 produced nothing. We'll skip the next painting of the phase if the flag is set, | 312 produced nothing. We'll skip the next painting of the phase if the flag is set, |
| 313 regardless of the corresponding `needsPaintPhaseXXX` flag. We will clear the | 313 regardless of the corresponding `NeedsPaintPhaseXXX` flag. We will clear the |
| 314 `previousPaintPhaseXXXWasEmpty` flags when we paint with different clipping, | 314 `PreviousPaintPhaseXXXWasEmpty` flags when we paint with different clipping, |
| 315 scroll offset or interest rect from the previous paint. | 315 scroll offset or interest rect from the previous paint. |
| 316 | 316 |
| 317 We don't clear the `previousPaintPhaseXXXWasEmpty` flags when the layer is | 317 We don't clear the `PreviousPaintPhaseXXXWasEmpty` flags when the layer is |
| 318 marked `needsRepaint`. Instead we clear the flag when the corresponding | 318 marked `NeedsRepaint`. Instead we clear the flag when the corresponding |
| 319 `needsPaintPhaseXXX` is set. This ensures that we won't clear | 319 `NeedsPaintPhaseXXX` is set. This ensures that we won't clear |
| 320 `previousPaintPhaseXXXWasEmpty` flags when unrelated things changed which won't | 320 `PreviousPaintPhaseXXXWasEmpty` flags when unrelated things changed which won't |
| 321 cause the paint phases to become non-empty. | |
| 322 | 321 |
| 323 When layer structure changes, and we are not invalidate paint of the changed | 322 When layer structure changes, and we are not invalidate paint of the changed |
| 324 subtree, we need to manually update the `needsPaintPhaseXXX` flags. For example, | 323 subtree, we need to manually update the `NeedsPaintPhaseXXX` flags. For example, |
| 325 if an object changes style and creates a self-painting-layer, we copy the flags | 324 if an object changes style and creates a self-painting-layer, we copy the flags |
| 326 from its containing self-painting layer to this layer, assuming that this layer | 325 from its containing self-painting layer to this layer, assuming that this layer |
| 327 needs all paint phases that its container self-painting layer needs. | 326 needs all paint phases that its container self-painting layer needs. |
| 328 | 327 |
| 329 We could update the `needsPaintPhaseXXX` flags in a separate tree walk, but that | 328 We could update the `NeedsPaintPhaseXXX` flags in a separate tree walk, but that |
| 330 would regress performance of the first paint. For slimming paint v2, we can | 329 would regress performance of the first paint. For slimming paint v2, we can |
| 331 update the flags during the pre-painting tree walk to simplify the logics. | 330 update the flags during the pre-painting tree walk to simplify the logics. |
| OLD | NEW |