tree: b51bf684ae591bea89ce970163bbb8c8195083f5 [path history] [tgz]
  1. test_data/
  2. BackgroundImageGeometry.cpp
  3. BackgroundImageGeometry.h
  4. BlockFlowPainter.cpp
  5. BlockFlowPainter.h
  6. BlockFlowPaintInvalidator.cpp
  7. BlockFlowPaintInvalidator.h
  8. BlockPainter.cpp
  9. BlockPainter.h
  10. BlockPaintInvalidator.cpp
  11. BlockPaintInvalidator.h
  12. BoxBorderPainter.cpp
  13. BoxBorderPainter.h
  14. BoxClipper.cpp
  15. BoxClipper.h
  16. BoxDecorationData.cpp
  17. BoxDecorationData.h
  18. BoxPainter.cpp
  19. BoxPainter.h
  20. BoxPaintInvalidator.cpp
  21. BoxPaintInvalidator.h
  22. BoxPaintInvalidatorTest.cpp
  23. BoxReflectionUtils.cpp
  24. BoxReflectionUtils.h
  26. ClipPathClipper.cpp
  27. ClipPathClipper.h
  28. ClipRect.cpp
  29. ClipRect.h
  30. ClipRects.h
  31. ClipRectsCache.h
  32. DetailsMarkerPainter.cpp
  33. DetailsMarkerPainter.h
  34. EllipsisBoxPainter.cpp
  35. EllipsisBoxPainter.h
  36. EmbeddedObjectPainter.cpp
  37. EmbeddedObjectPainter.h
  38. EmbeddedObjectPaintInvalidator.cpp
  39. EmbeddedObjectPaintInvalidator.h
  40. FieldsetPainter.cpp
  41. FieldsetPainter.h
  42. FileUploadControlPainter.cpp
  43. FileUploadControlPainter.h
  44. FilterEffectBuilder.cpp
  45. FilterEffectBuilder.h
  46. FilterPainter.cpp
  47. FilterPainter.h
  48. FindPropertiesNeedingUpdate.h
  49. FirstMeaningfulPaintDetector.cpp
  50. FirstMeaningfulPaintDetector.h
  51. FirstMeaningfulPaintDetectorTest.cpp
  52. FloatClipRecorder.cpp
  53. FloatClipRecorder.h
  54. FramePainter.cpp
  55. FramePainter.h
  56. FrameSetPainter.cpp
  57. FrameSetPainter.h
  58. GridPainter.cpp
  59. GridPainter.h
  60. HTMLCanvasPainter.cpp
  61. HTMLCanvasPainter.h
  62. HTMLCanvasPainterTest.cpp
  63. HTMLCanvasPaintInvalidator.cpp
  64. HTMLCanvasPaintInvalidator.h
  65. ImagePainter.cpp
  66. ImagePainter.h
  67. InlineFlowBoxPainter.cpp
  68. InlineFlowBoxPainter.h
  69. InlinePainter.cpp
  70. InlinePainter.h
  71. InlineTextBoxPainter.cpp
  72. InlineTextBoxPainter.h
  73. LayerClipRecorder.cpp
  74. LayerClipRecorder.h
  75. LayerClipRecorderTest.cpp
  76. LayerHitTestRects.h
  77. LayoutObjectDrawingRecorder.h
  78. LayoutObjectDrawingRecorderTest.cpp
  79. LineBoxListPainter.cpp
  80. LineBoxListPainter.h
  81. ListItemPainter.cpp
  82. ListItemPainter.h
  83. ListMarkerPainter.cpp
  84. ListMarkerPainter.h
  85. MediaControlsPainter.cpp
  86. MediaControlsPainter.h
  87. MultiColumnSetPainter.cpp
  88. MultiColumnSetPainter.h
  89. NinePieceImageGrid.cpp
  90. NinePieceImageGrid.h
  91. NinePieceImageGridTest.cpp
  92. NinePieceImagePainter.cpp
  93. NinePieceImagePainter.h
  94. ObjectPainter.cpp
  95. ObjectPainter.h
  96. ObjectPaintInvalidator.cpp
  97. ObjectPaintInvalidator.h
  98. ObjectPaintInvalidatorTest.cpp
  99. ObjectPaintProperties.cpp
  100. ObjectPaintProperties.h
  101. OWNERS
  102. PaintControllerPaintTest.cpp
  103. PaintControllerPaintTest.h
  104. PaintInfo.cpp
  105. PaintInfo.h
  106. PaintInfoTest.cpp
  107. PaintInvalidationCapableScrollableArea.cpp
  108. PaintInvalidationCapableScrollableArea.h
  109. PaintInvalidationTest.cpp
  110. PaintInvalidator.cpp
  111. PaintInvalidator.h
  112. PaintLayer.cpp
  113. PaintLayer.h
  114. PaintLayerClipper.cpp
  115. PaintLayerClipper.h
  116. PaintLayerClipperTest.cpp
  117. PaintLayerFragment.h
  118. PaintLayerPainter.cpp
  119. PaintLayerPainter.h
  120. PaintLayerPainterTest.cpp
  121. PaintLayerPaintingInfo.h
  122. PaintLayerResourceInfo.cpp
  123. PaintLayerResourceInfo.h
  124. PaintLayerScrollableArea.cpp
  125. PaintLayerScrollableArea.h
  126. PaintLayerScrollableAreaTest.cpp
  127. PaintLayerStackingNode.cpp
  128. PaintLayerStackingNode.h
  129. PaintLayerStackingNodeIterator.cpp
  130. PaintLayerStackingNodeIterator.h
  131. PaintLayerTest.cpp
  132. PaintPhase.cpp
  133. PaintPhase.h
  134. PaintPropertyTreeBuilder.cpp
  135. PaintPropertyTreeBuilder.h
  136. PaintPropertyTreeBuilderTest.cpp
  137. PaintPropertyTreeBuilderTest.h
  138. PaintPropertyTreePrinter.cpp
  139. PaintPropertyTreePrinter.h
  140. PaintPropertyTreePrinterTest.cpp
  141. PaintPropertyTreeUpdateTests.cpp
  142. PaintResult.h
  143. PaintTiming.cpp
  144. PaintTiming.h
  145. PartPainter.cpp
  146. PartPainter.h
  147. PrePaintTreeWalk.cpp
  148. PrePaintTreeWalk.h
  149. PrePaintTreeWalkTest.cpp
  151. ReplacedPainter.cpp
  152. ReplacedPainter.h
  153. RootInlineBoxPainter.cpp
  154. RootInlineBoxPainter.h
  155. RoundedInnerRectClipper.cpp
  156. RoundedInnerRectClipper.h
  157. ScrollableAreaPainter.cpp
  158. ScrollableAreaPainter.h
  159. ScrollbarManager.cpp
  160. ScrollbarManager.h
  161. ScrollbarPainter.cpp
  162. ScrollbarPainter.h
  163. ScrollRecorder.cpp
  164. ScrollRecorder.h
  165. StubChromeClientForSPv2.h
  166. SVGContainerPainter.cpp
  167. SVGContainerPainter.h
  168. SVGFilterPainter.cpp
  169. SVGFilterPainter.h
  170. SVGForeignObjectPainter.cpp
  171. SVGForeignObjectPainter.h
  172. SVGImagePainter.cpp
  173. SVGImagePainter.h
  174. SVGInlineFlowBoxPainter.cpp
  175. SVGInlineFlowBoxPainter.h
  176. SVGInlineTextBoxPainter.cpp
  177. SVGInlineTextBoxPainter.h
  178. SVGInlineTextBoxPainterTest.cpp
  179. SVGMaskPainter.cpp
  180. SVGMaskPainter.h
  181. SVGPaintContext.cpp
  182. SVGPaintContext.h
  183. SVGRootInlineBoxPainter.cpp
  184. SVGRootInlineBoxPainter.h
  185. SVGRootPainter.cpp
  186. SVGRootPainter.h
  187. SVGShapePainter.cpp
  188. SVGShapePainter.h
  189. SVGTextPainter.cpp
  190. SVGTextPainter.h
  191. TableCellPainter.cpp
  192. TableCellPainter.h
  193. TableCellPainterTest.cpp
  194. TablePainter.cpp
  195. TablePainter.h
  196. TablePaintInvalidator.cpp
  197. TablePaintInvalidator.h
  198. TableRowPainter.cpp
  199. TableRowPainter.h
  200. TableSectionPainter.cpp
  201. TableSectionPainter.h
  202. TextPainter.cpp
  203. TextPainter.h
  204. TextPainterTest.cpp
  205. ThemePainter.cpp
  206. ThemePainter.h
  207. ThemePainterDefault.cpp
  208. ThemePainterDefault.h
  209. ThemePainterMac.h
  211. Transform3DRecorder.cpp
  212. Transform3DRecorder.h
  213. TransformRecorder.cpp
  214. TransformRecorder.h
  215. VideoPainter.cpp
  216. VideoPainter.h
  217. VideoPainterTest.cpp
  218. ViewPainter.cpp
  219. ViewPainter.h
  220. ViewPaintInvalidator.cpp
  221. ViewPaintInvalidator.h


This directory contains implementation of painters of layout objects. It covers the following document lifecycle states:

  • PaintInvalidation (InPaintInvalidation and PaintInvalidationClean)
  • PrePaint (InPrePaint and PrePaintClean)
  • Paint (InPaint and PaintClean)


Stacked elements and stacking contexts

This chapter is basically a clarification of CSS 2.1 appendix E. Elaborate description of Stacking Contexts.

Note: we use ‘element’ instead of ‘object’ in this chapter to keep consistency with the spec. We use ‘object’ in other places in this document.

According to the documentation, we can have the following types of elements that are treated in different ways during painting:

  • Stacked objects: objects that are z-ordered in stacking contexts, including:

    • Stacking contexts: elements with non-auto z-indices or other properties that affect stacking e.g. transform, opacity, blend-mode.

    • Elements that are not real stacking contexts but are treated as stacking contexts but don't manage other stacked elements. Their z-ordering are managed by real stacking contexts. They are positioned elements with z-index: auto (E.2.8 in the documentation).

      They must be managed by the enclosing stacking context as stacked elements because z-index:auto and z-index:0 are considered equal for stacking context sorting and they may interleave by DOM order.

      The difference of a stacked element of this type from a real stacking context is that it doesn't manage z-ordering of stacked descendants. These descendants are managed by the parent stacking context of this stacked element.

    “Stacked element” is not defined as a formal term in the documentation, but we found it convenient to use this term to refer to any elements participating z-index ordering in stacking contexts.

    A stacked element is represented by a PaintLayerStackingNode associated with a PaintLayer. It‘s painted as self-painting PaintLayers by PaintLayerPainter by executing all of the steps of the painting algorithm explained in the documentation for the element. When painting a stacked element of the second type, we don’t paint its stacked descendants which are managed by the parent stacking context.

  • Non-stacked pseudo stacking contexts: elements that are not stacked, but paint their descendants (excluding any stacked contents) as if they created stacking contexts. This includes

    • inline blocks, inline tables, inline-level replaced elements (E. in the documentation)
    • non-positioned floating elements (E.2.5 in the documentation)
    • flex items
    • grid items
    • custom scrollbar parts

    They are painted by ObjectPainter::paintAllPhasesAtomically() which executes all of the steps of the painting algorithm explained in the documentation, except ignores any descendants which are positioned or have non-auto z-index (which is achieved by skipping descendants with self-painting layers).

  • Other normal elements.

Other glossaries

  • Paint container: the parent of an object for painting, as defined by CSS2.1 spec for painting. For regular objects, this is the parent in the DOM. For stacked objects, it's the containing stacking context-inducing object.

  • Paint container chain: the chain of paint ancestors between an element and the root of the page.

  • Compositing container: an implementation detail of Blink, which uses PaintLayers to represent some layout objects. It is the ancestor along the paint ancestor chain which has a PaintLayer. Implemented in PaintLayer::compositingContainer(). Think of it as skipping intermediate normal objects and going directly to the containing stacked object.

  • Compositing container chain: same as paint chain, but for compositing container.

  • Paint invalidation container: the nearest object on the compositing container chain which is composited.

  • Visual rect: the bounding box of all pixels that will be painted by a display item client.

Paint invalidation

Paint invalidation marks anything that need to be painted differently from the original cached painting.

Slimming paint v1

Though described in this document, most of the actual paint invalidation code is under Source/core/layout.

Paint invalidation is a document cycle stage after compositing update and before paint. During the previous stages, objects are marked for needing paint invalidation checking if needed by style change, layout change, compositing change, etc. In paint invalidation stage, we traverse the layout tree in pre-order, crossing frame boundaries, for marked subtrees and objects and send the following information to GraphicsLayers and PaintControllers:

  • invalidated display item clients: must invalidate all display item clients that will generate different display items.

  • paint invalidation rects: must cover all areas that will generate different pixels. They are generated based on visual rects of invalidated display item clients.


PaintInvalidationState is an optimization used during the paint invalidation phase. Before the paint invalidation tree walk, a root PaintInvalidationState is created for the root LayoutView. During the tree walk, one PaintInvalidationState is created for each visited object based on the PaintInvalidationState passed from the parent object. It tracks the following information to provide O(1) complexity access to them if possible:

  • Paint invalidation container: Since as indicated by the definitions in [Glossaries](#Other glossaries), the paint invalidation container for stacked objects can differ from normal objects, we have to track both separately. Here is an example:

    <div style="overflow: scroll">
        <div id=A style="position: absolute"></div>
        <div id=B></div>

    If the scroller is composited (for high-DPI screens for example), it is the paint invalidation container for div B, but not A.

  • Paint offset and clip rect: if possible, PaintInvalidationState accumulates paint offsets and overflow clipping rects from the paint invalidation container to provide O(1) complexity to map a point or a rect in current object‘s local space to paint invalidation container’s space. Because locations of objects are determined by their containing blocks, and the containing block for absolute-position objects differs from non-absolute, we track paint offsets and overflow clipping rects for absolute-position objects separately.

In cases that accurate accumulation of paint offsets and clipping rects is impossible, we will fall back to slow-path using LayoutObject::localToAncestorPoint() or LayoutObject::mapToVisualRectInAncestorSpace(). This includes the following cases:

  • An object has transform related property, is multi-column or has flipped blocks writing-mode, causing we can't simply accumulate paint offset for mapping a local rect to paint invalidation container;

  • An object has has filter (including filter induced by reflection), which needs to expand visual rect for descendants, because currently we don't include and filter extents into visual overflow;

  • For a fixed-position object we calculate its offset using LayoutObject::localToAncestorPoint(), but map for its descendants in fast-path if no other things prevent us from doing this;

  • Because we track paint offset from the normal paint invalidation container only, if we are going to use m_paintInvalidationContainerForStackedContents and it's different from the normal paint invalidation container, we have to force slow-path because the accumulated paint offset is not usable;

  • We also stop to track paint offset and clipping rect for absolute-position objects when m_paintInvalidationContainerForStackedContents becomes different from m_paintInvalidationContainer.

Paint invalidation of texts

Texts are painted by InlineTextBoxPainter using InlineTextBox as display item client. Text backgrounds and masks are painted by InlineTextFlowPainter using InlineFlowBox as display item client. We should invalidate these display item clients when their painting will change.

LayoutInlines and LayoutTexts are marked for full paint invalidation if needed when new style is set on them. During paint invalidation, we invalidate the InlineFlowBoxs directly contained by the LayoutInline in LayoutInline::invalidateDisplayItemClients() and InlineTextBoxs contained by the LayoutText in LayoutText::invalidateDisplayItemClients(). We don't need to traverse into the subtree of InlineFlowBoxs in LayoutInline::invalidateDisplayItemClients() because the descendant InlineFlowBoxs and InlineTextBoxs will be handled by their owning LayoutInlines and LayoutTexts, respectively, when changed style is propagated.

Specialty of ::first-line

::first-line pseudo style dynamically applies to all InlineBox's in the first line in the block having ::first-line style. The actual applied style is computed from the ::first-line style and other applicable styles.

If the first line contains any LayoutInline, we compute the style from the ::first-line style and the style of the LayoutInline and apply the computed style to the first line part of the LayoutInline. In blink's style implementation, the combined first line style of LayoutInline is identified with FIRST_LINE_INHERITED pseudo ID.

The normal paint invalidation of texts doesn't work for first line because

  • ComputedStyle::visualInvalidationDiff() can't detect first line style changes;
  • The normal paint invalidation is based on whole LayoutObject's, not aware of the first line.

We have a special path for first line style change: the style system informs the layout system when the computed first-line style changes through LayoutObject::firstLineStyleDidChange(). When this happens, we invalidate all InlineBoxes in the first line.

Slimming paint v2

TODO(wangxianzhu): add details

PrePaintTreeWalk (Slimming paint v2 only)

During InPrePaint document lifecycle state, this class is called to walk the whole layout tree, beginning from the root FrameView, across frame boundaries. We do the following during the tree walk:

  • Building paint property tree: creates paint property tree nodes for special things in the layout tree, including but not limit to: overflow clip, transform, fixed-pos, animation, mask, filter, etc. Also sets direct compositing reasons to be used later for compositing.

  • Paint invalidation: Not implemented yet. TODO(wangxianzhu): add details after it's implemented.

Paint result caching

PaintController holds the previous painting result as a cache of display items. If some painter would generate results same as those of the previous painting, we'll skip the painting and reuse the display items from cache.

Display item caching

When a painter would create a DrawingDisplayItem exactly the same as the display item created in the previous painting, we'll reuse the previous one instead of repainting it.

Subsequence caching

When possible, we enclose the display items that PaintLayerPainter::paintContents() generates (including display items generated by sublayers) in a pair of BeginSubsequence/EndSubsequence display items.

In a subsequence paint, if the layer would generate exactly the same display items, we'll get the whole subsequence from the cache instead of repainting them.

There are many conditions affecting

  • whether we need to generate subsequence for a PaintLayer;
  • whether we can use cached subsequence for a PaintLayer. See shouldCreateSubsequence() and shouldRepaintSubsequence() in PaintLayerPainter.cpp for the conditions.

Empty paint phase optimization

During painting, we walk the layout tree multiple times for multiple paint phases. Sometimes a layer contain nothing needing a certain paint phase and we can skip tree walk for such empty phases. Now we have optimized PaintPhaseDescendantBlockBackgroundsOnly, PaintPhaseDescendantOutlinesOnly and PaintPhaseFloat for empty paint phases.

During paint invalidation, we set the containing self-painting layer's needsPaintPhaseXXX flag if the object has something needing to be painted in the paint phase.

During painting, we check the flag before painting a paint phase and skip the tree walk if the flag is not set.

It‘s hard to clear a needsPaintPhaseXXX flag when a layer no longer needs the paint phase, so we never clear the flags. Instead, we use another set of flags (previousPaintPhaseXXXWasEmpty) to record if a painting of a phase actually produced nothing. We’ll skip the next painting of the phase if the flag is set, regardless of the corresponding needsPaintPhaseXXX flag. We will clear the previousPaintPhaseXXXWasEmpty flags when we paint with different clipping, scroll offset or interest rect from the previous paint.

We don‘t clear the previousPaintPhaseXXXWasEmpty flags when the layer is marked needsRepaint. Instead we clear the flag when the corresponding needsPaintPhaseXXX is set. This ensures that we won’t clear previousPaintPhaseXXXWasEmpty flags when unrelated things changed which won't cause the paint phases to become non-empty.

When layer structure changes, and we are not invalidate paint of the changed subtree, we need to manually update the needsPaintPhaseXXX flags. For example, if an object changes style and creates a self-painting-layer, we copy the flags from its containing self-painting layer to this layer, assuming that this layer needs all paint phases that its container self-painting layer needs.

We could update the needsPaintPhaseXXX flags in a separate tree walk, but that would regress performance of the first paint. For slimming paint v2, we can update the flags during the pre-painting tree walk to simplify the logics.