Changeset 238090 in webkit


Ignore:
Timestamp:
Nov 12, 2018, 9:14:05 AM (7 years ago)
Author:
Simon Fraser
Message:

Make compositing updates incremental
https://bugs.webkit.org/show_bug.cgi?id=90342

Reviewed by Antti Koivisto.

Source/WebCore:

Previously, updating compositing layers required two full RenderLayer tree traversals,
and all the work was done for every RenderLayer on each composting update. This could be expensive
on pages with lots of RenderLayers.

These changes make compositing updates more incremental. Compositing updates still require
two tree traversals. The first determines which RenderLayers need to be composited (of those which
weren't already made composited at style-change time), because of reasons that can only be determined
post-layout, and indirect reasons including overlap. The second traversal updates the configuration, geometry
and GraphicsLayer tree for the composited layers. Dependencies on both descendant and ancestor state make
it hard to fold these two traversals together.

In order to minimize the work done during these traversals, dirty bits are stored on RenderLayers,
and propagated to ancestor layers in paint order. There are two sets of bits: those related to the first
"compositing requirements" traversal, and those related to the second "update backing and hierarchy" traversal.
When a RenderLayer gets a dirty bit set, bits are propagated to ancestors to indicate that children need
to be visited.

Sadly entire subtrees can't be skipped during the "compositing requirements" traversal becaue we still have
to accumulate overlap rects, but RenderLayerCompositor::traverseUnchangedSubtree() is used to minimize
work in that case. Subtrees can be skipped in the "update backing and hierarchy" traveral. Entire traversals can
be skipped if no change has triggered the need for that traversal.

These changes fix a correctness issue where transform changes now trigger overlap re-evaluation, which causes
more layer geometry updates than before. This regressed the MotionMark "Focus" test, when geometry updates
triggered layer resizes as the filter blur radius changed, which then triggered repaints. This is fixed by
excluding composited filters from the composited bounds (but still taking them into account for overlap).

Care is taken to avoid triggering traversals in non-composited documents (tested by no-updates-in-non-composited-iframe.html).

Code to set the dirty bits is added in various places that change properties that compositing depends on.

These changes also subsume the patch in 176196; we now never consult properties that rely on layout from the
style change code path, and the only call stack for geometry updates is from the "update backing and hierarchy"
traversal, which is always a pre-order traversal.

Tests: compositing/geometry/stacking-context-change-layer-reparent.html

compositing/layer-creation/change-to-overlap.html
compositing/updates/no-updates-in-non-composited-iframe.html

  • html/canvas/WebGLRenderingContextBase.cpp:

(WebCore::WebGLRenderingContextBase::markContextChanged): Need to differentiate between a canvas becoming composited
for the first time, and its pixels changing with a new 'CanvasPixelsChanged' value.

  • page/FrameView.cpp:

(WebCore::FrameView::setViewportConstrainedObjectsNeedLayout):

  • page/Page.cpp:

(WebCore::Page::setPageScaleFactor):

  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::GraphicsLayerCA::updateBackdropFilters): If we just made a layer for backdrops, we need to update sublayers.

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::styleWillChange):

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::~RenderLayer):
(WebCore::RenderLayer::addChild):
(WebCore::RenderLayer::removeChild):
(WebCore::RenderLayer::shouldBeStackingContext const):
(WebCore::RenderLayer::stackingContext const):
(WebCore::RenderLayer::dirtyZOrderLists):
(WebCore::RenderLayer::dirtyNormalFlowList):
(WebCore::RenderLayer::updateNormalFlowList):
(WebCore::RenderLayer::rebuildZOrderLists):
(WebCore::RenderLayer::setAncestorsHaveCompositingDirtyFlag):
(WebCore::RenderLayer::contentChanged):
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::updateTransform):
(WebCore::RenderLayer::updateLayerPosition):
(WebCore::RenderLayer::enclosingCompositingLayer const):
(WebCore::RenderLayer::enclosingCompositingLayerForRepaint const):
(WebCore::RenderLayer::clippingRootForPainting const):
(WebCore::RenderLayer::scrollTo):
(WebCore::RenderLayer::updateCompositingLayersAfterScroll):
(WebCore::RenderLayer::updateScrollInfoAfterLayout):
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::hitTest):
(WebCore::RenderLayer::hitTestLayer):
(WebCore::RenderLayer::calculateClipRects const):
(WebCore::outputPaintOrderTreeLegend):
(WebCore::outputPaintOrderTreeRecursive):
(WebCore::compositingContainer): Deleted.

  • rendering/RenderLayer.h:

(WebCore::RenderLayer::clearZOrderLists):
(WebCore::RenderLayer::paintOrderParent const):

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateCompositedBounds):
(WebCore::RenderLayerBacking::updateAfterWidgetResize):
(WebCore::RenderLayerBacking::updateAfterLayout):
(WebCore::RenderLayerBacking::updateConfigurationAfterStyleChange):
(WebCore::RenderLayerBacking::updateConfiguration):
(WebCore::RenderLayerBacking::updateGeometry):
(WebCore::RenderLayerBacking::setRequiresBackgroundLayer):
(WebCore::RenderLayerBacking::updateMaskingLayer):
(WebCore::RenderLayerBacking::paintsContent const):
(WebCore::RenderLayerBacking::contentChanged):
(WebCore::RenderLayerBacking::setContentsNeedDisplay):
(WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
(WebCore::RenderLayerBacking::startAnimation):
(WebCore::RenderLayerBacking::animationFinished):
(WebCore::RenderLayerBacking::startTransition):
(WebCore::RenderLayerBacking::transitionFinished):
(WebCore::RenderLayerBacking::setCompositedBounds):

  • rendering/RenderLayerBacking.h:
  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::CompositingState::CompositingState):
(WebCore::RenderLayerCompositor::enableCompositingMode):
(WebCore::RenderLayerCompositor::cacheAcceleratedCompositingFlags):
(WebCore::RenderLayerCompositor::cacheAcceleratedCompositingFlagsAfterLayout):
(WebCore::RenderLayerCompositor::willRecalcStyle):
(WebCore::RenderLayerCompositor::didRecalcStyleWithNoPendingLayout):
(WebCore::RenderLayerCompositor::updateCompositingLayers):
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
(WebCore::RenderLayerCompositor::updateBackingAndHierarchy):
(WebCore::RenderLayerCompositor::appendDocumentOverlayLayers):
(WebCore::RenderLayerCompositor::layerBecameNonComposited):
(WebCore::RenderLayerCompositor::logLayerInfo):
(WebCore::clippingChanged):
(WebCore::styleAffectsLayerGeometry):
(WebCore::RenderLayerCompositor::layerStyleChanged):
(WebCore::RenderLayerCompositor::needsCompositingUpdateForStyleChangeOnNonCompositedLayer const):
(WebCore::RenderLayerCompositor::updateBacking):
(WebCore::RenderLayerCompositor::updateLayerCompositingState):
(WebCore::RenderLayerCompositor::layerWasAdded):
(WebCore::RenderLayerCompositor::layerWillBeRemoved):
(WebCore::RenderLayerCompositor::enclosingNonStackingClippingLayer const):
(WebCore::RenderLayerCompositor::computeExtent const):
(WebCore::RenderLayerCompositor::addToOverlapMap):
(WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
(WebCore::RenderLayerCompositor::rootLayerConfigurationChanged):
(WebCore::RenderLayerCompositor::parentFrameContentLayers):
(WebCore::RenderLayerCompositor::updateRootLayerPosition):
(WebCore::RenderLayerCompositor::needsToBeComposited const):
(WebCore::RenderLayerCompositor::requiresCompositingLayer const):
(WebCore::RenderLayerCompositor::requiresOwnBackingStore const):
(WebCore::RenderLayerCompositor::reasonsForCompositing const):
(WebCore::RenderLayerCompositor::clippedByAncestor const):
(WebCore::RenderLayerCompositor::requiresCompositingForAnimation const):
(WebCore::RenderLayerCompositor::requiresCompositingForTransform const):
(WebCore::RenderLayerCompositor::requiresCompositingForVideo const):
(WebCore::RenderLayerCompositor::requiresCompositingForFilters const):
(WebCore::RenderLayerCompositor::requiresCompositingForWillChange const):
(WebCore::RenderLayerCompositor::requiresCompositingForPlugin const):
(WebCore::RenderLayerCompositor::requiresCompositingForFrame const):
(WebCore::RenderLayerCompositor::requiresCompositingForScrollableFrame const):
(WebCore::RenderLayerCompositor::requiresCompositingForPosition const):
(WebCore::RenderLayerCompositor::requiresCompositingForOverflowScrolling const):
(WebCore::RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons):
(WebCore::RenderLayerCompositor::fixedLayerIntersectsViewport const):
(WebCore::RenderLayerCompositor::useCoordinatedScrollingForLayer const):
(WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
(WebCore::RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged):
(WebCore::operator<<):
(WebCore::RenderLayerCompositor::setCompositingLayersNeedRebuild): Deleted.
(WebCore::checkIfDescendantClippingContextNeedsUpdate): Deleted.
(WebCore::isScrollableOverflow): Deleted.
(WebCore::styleHasTouchScrolling): Deleted.
(WebCore::styleChangeRequiresLayerRebuild): Deleted.
(WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Deleted.
(WebCore::RenderLayerCompositor::rootFixedBackgroundsChanged): Deleted.
(WebCore::RenderLayerCompositor::updateLayerTreeGeometry): Deleted.
(WebCore::RenderLayerCompositor::updateCompositingDescendantGeometry): Deleted.

  • rendering/RenderLayerCompositor.h:
  • rendering/RenderTreeAsText.cpp:

(WebCore::writeLayers):

Source/WebKitLegacy/mac:

Fix spelling error.

  • WebView/WebView.mm:

(-[WebView _setMediaLayer:forPluginView:]):

LayoutTests:

Add some new tests for issues discovered during development.

Filter tests get new results because composited layer bounds are no longer affected
by pixel-moving filters.

  • compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt:
  • compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt:
  • compositing/filters/sw-shadow-overlaps-hw-layer-expected.txt:
  • compositing/filters/sw-shadow-overlaps-hw-shadow-expected.txt:
  • compositing/geometry/stacking-context-change-layer-reparent-expected.html: Added.
  • compositing/geometry/stacking-context-change-layer-reparent.html: Added.
  • compositing/layer-creation/change-to-overlap-expected.txt: Added.
  • compositing/layer-creation/change-to-overlap.html: Added.
  • compositing/updates/no-updates-in-non-composited-iframe-expected.txt: Added.
  • compositing/updates/no-updates-in-non-composited-iframe.html: Added.
  • compositing/updates/resources/non-composited.html: Added.
  • compositing/video/video-clip-change-src.html: This test was timing-sensitive; the behavior differed bases on whether we

happened to do a compositing flush between the first and second video load.

  • platform/mac-wk1/TestExpectations: Mark compositing/layer-creation/fixed-overlap-extent.html as flakey; it depends on the

timing of various AppKit-related things that aren't consistent.

Location:
trunk
Files:
7 added
22 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r238086 r238090  
     12018-11-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Make compositing updates incremental
     4        https://bugs.webkit.org/show_bug.cgi?id=90342
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Add some new tests for issues discovered during development.
     9       
     10        Filter tests get new results because composited layer bounds are no longer affected
     11        by pixel-moving filters.
     12
     13        * compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt:
     14        * compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt:
     15        * compositing/filters/sw-shadow-overlaps-hw-layer-expected.txt:
     16        * compositing/filters/sw-shadow-overlaps-hw-shadow-expected.txt:
     17        * compositing/geometry/stacking-context-change-layer-reparent-expected.html: Added.
     18        * compositing/geometry/stacking-context-change-layer-reparent.html: Added.
     19        * compositing/layer-creation/change-to-overlap-expected.txt: Added.
     20        * compositing/layer-creation/change-to-overlap.html: Added.
     21        * compositing/updates/no-updates-in-non-composited-iframe-expected.txt: Added.
     22        * compositing/updates/no-updates-in-non-composited-iframe.html: Added.
     23        * compositing/updates/resources/non-composited.html: Added.
     24        * compositing/video/video-clip-change-src.html: This test was timing-sensitive; the behavior differed bases on whether we
     25        happened to do a compositing flush between the first and second video load.
     26        * platform/mac-wk1/TestExpectations: Mark compositing/layer-creation/fixed-overlap-extent.html as flakey; it depends on the
     27        timing of various AppKit-related things that aren't consistent.
     28
    1292018-11-12  Jer Noble  <jer.noble@apple.com>
    230
  • trunk/LayoutTests/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt

    r225897 r238090  
    88      (children 2
    99        (GraphicsLayer
    10           (offsetFromRenderer width=-25 height=-25)
    11           (position 80.00 80.00)
    12           (anchor 0.60 0.60)
    13           (bounds 125.00 125.00)
     10          (position 105.00 105.00)
     11          (bounds 100.00 100.00)
     12          (contentsOpaque 1)
    1413          (drawsContent 1)
    1514        )
  • trunk/LayoutTests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt

    r225897 r238090  
    88      (children 2
    99        (GraphicsLayer
    10           (offsetFromRenderer width=-125 height=-125)
    11           (position 205.00 205.00)
    12           (anchor 0.78 0.78)
    13           (bounds 225.00 225.00)
     10          (offsetFromRenderer width=-100 height=-100)
     11          (position 230.00 230.00)
     12          (anchor 0.75 0.75)
     13          (bounds 200.00 200.00)
    1414          (drawsContent 1)
    1515        )
    1616        (GraphicsLayer
    17           (bounds 225.00 225.00)
     17          (bounds 200.00 200.00)
    1818          (drawsContent 1)
    1919        )
  • trunk/LayoutTests/compositing/filters/sw-shadow-overlaps-hw-layer-expected.txt

    r168244 r238090  
    1313        )
    1414        (GraphicsLayer
    15           (bounds 125.00 125.00)
     15          (bounds 100.00 100.00)
     16          (contentsOpaque 1)
    1617          (drawsContent 1)
    1718        )
  • trunk/LayoutTests/compositing/filters/sw-shadow-overlaps-hw-shadow-expected.txt

    r225897 r238090  
    88      (children 2
    99        (GraphicsLayer
    10           (offsetFromRenderer width=-25 height=-25)
    11           (position 105.00 105.00)
    12           (anchor 0.60 0.60)
    13           (bounds 125.00 125.00)
     10          (position 130.00 130.00)
     11          (bounds 100.00 100.00)
     12          (contentsOpaque 1)
    1413          (drawsContent 1)
    1514        )
    1615        (GraphicsLayer
    17           (bounds 125.00 125.00)
     16          (bounds 100.00 100.00)
     17          (contentsOpaque 1)
    1818          (drawsContent 1)
    1919        )
  • trunk/LayoutTests/compositing/layer-creation/change-to-overlap-expected.txt

    r238089 r238090  
    88      (children 2
    99        (GraphicsLayer
    10           (offsetFromRenderer width=-25 height=-25)
    11           (position 80.00 80.00)
    12           (anchor 0.60 0.60)
    13           (bounds 125.00 125.00)
    14           (drawsContent 1)
     10          (position 8.00 63.00)
     11          (bounds 320.00 170.00)
     12          (contentsOpaque 1)
    1513        )
    1614        (GraphicsLayer
    17           (bounds 100.00 100.00)
    18           (contentsOpaque 1)
     15          (position 5.00 5.00)
     16          (bounds 150.00 150.00)
    1917        )
    2018      )
  • trunk/LayoutTests/compositing/video/video-clip-change-src.html

    r177324 r238090  
    2222
    2323    function canplaythrough() {
    24         if (callback)
     24        if (!callback)
     25            return;
     26
     27        setTimeout(() => {
    2528            callback();
     29        }, 0);
    2630    }
    2731
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r238013 r238090  
    626626webkit.org/b/188357 legacy-animation-engine/compositing/layer-creation/animation-overlap-with-children.html [ Pass Failure ]
    627627
     628webkit.org/b/190648 compositing/layer-creation/fixed-overlap-extent.html [ Pass Failure ]
     629
    628630# <rdar://problem/42904780>
    629631[ Mojave+ Release ] imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/hkdf.https.worker.html [ Failure ]
  • trunk/Source/WebCore/ChangeLog

    r238089 r238090  
     12018-11-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Make compositing updates incremental
     4        https://bugs.webkit.org/show_bug.cgi?id=90342
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Previously, updating compositing layers required two full RenderLayer tree traversals,
     9        and all the work was done for every RenderLayer on each composting update. This could be expensive
     10        on pages with lots of RenderLayers.
     11
     12        These changes make compositing updates more incremental. Compositing updates still require
     13        two tree traversals. The first determines which RenderLayers need to be composited (of those which
     14        weren't already made composited at style-change time), because of reasons that can only be determined
     15        post-layout, and indirect reasons including overlap. The second traversal updates the configuration, geometry
     16        and GraphicsLayer tree for the composited layers. Dependencies on both descendant and ancestor state make
     17        it hard to fold these two traversals together.
     18
     19        In order to minimize the work done during these traversals, dirty bits are stored on RenderLayers,
     20        and propagated to ancestor layers in paint order. There are two sets of bits: those related to the first
     21        "compositing requirements" traversal, and those related to the second "update backing and hierarchy" traversal.
     22        When a RenderLayer gets a dirty bit set, bits are propagated to ancestors to indicate that children need
     23        to be visited.
     24
     25        Sadly entire subtrees can't be skipped during the "compositing requirements" traversal becaue we still have
     26        to accumulate overlap rects, but RenderLayerCompositor::traverseUnchangedSubtree() is used to minimize
     27        work in that case. Subtrees can be skipped in the "update backing and hierarchy" traveral. Entire traversals can
     28        be skipped if no change has triggered the need for that traversal.
     29       
     30        These changes fix a correctness issue where transform changes now trigger overlap re-evaluation, which causes
     31        more layer geometry updates than before. This regressed the MotionMark "Focus" test, when geometry updates
     32        triggered layer resizes as the filter blur radius changed, which then triggered repaints. This is fixed by
     33        excluding composited filters from the composited bounds (but still taking them into account for overlap).
     34
     35        Care is taken to avoid triggering traversals in non-composited documents (tested by no-updates-in-non-composited-iframe.html).
     36
     37        Code to set the dirty bits is added in various places that change properties that compositing depends on.
     38       
     39        These changes also subsume the patch in 176196; we now never consult properties that rely on layout from the
     40        style change code path, and the only call stack for geometry updates is from the "update backing and hierarchy"
     41        traversal, which is always a pre-order traversal.
     42
     43        Tests: compositing/geometry/stacking-context-change-layer-reparent.html
     44               compositing/layer-creation/change-to-overlap.html
     45               compositing/updates/no-updates-in-non-composited-iframe.html
     46
     47        * html/canvas/WebGLRenderingContextBase.cpp:
     48        (WebCore::WebGLRenderingContextBase::markContextChanged): Need to differentiate between a canvas becoming composited
     49        for the first time, and its pixels changing with a new 'CanvasPixelsChanged' value.
     50        * page/FrameView.cpp:
     51        (WebCore::FrameView::setViewportConstrainedObjectsNeedLayout):
     52        * page/Page.cpp:
     53        (WebCore::Page::setPageScaleFactor):
     54        * platform/graphics/ca/GraphicsLayerCA.cpp:
     55        (WebCore::GraphicsLayerCA::updateBackdropFilters): If we just made a layer for backdrops, we need to update sublayers.
     56        * rendering/RenderBox.cpp:
     57        (WebCore::RenderBox::styleWillChange):
     58        * rendering/RenderLayer.cpp:
     59        (WebCore::RenderLayer::RenderLayer):
     60        (WebCore::RenderLayer::~RenderLayer):
     61        (WebCore::RenderLayer::addChild):
     62        (WebCore::RenderLayer::removeChild):
     63        (WebCore::RenderLayer::shouldBeStackingContext const):
     64        (WebCore::RenderLayer::stackingContext const):
     65        (WebCore::RenderLayer::dirtyZOrderLists):
     66        (WebCore::RenderLayer::dirtyNormalFlowList):
     67        (WebCore::RenderLayer::updateNormalFlowList):
     68        (WebCore::RenderLayer::rebuildZOrderLists):
     69        (WebCore::RenderLayer::setAncestorsHaveCompositingDirtyFlag):
     70        (WebCore::RenderLayer::contentChanged):
     71        (WebCore::RenderLayer::updateLayerPositions):
     72        (WebCore::RenderLayer::updateTransform):
     73        (WebCore::RenderLayer::updateLayerPosition):
     74        (WebCore::RenderLayer::enclosingCompositingLayer const):
     75        (WebCore::RenderLayer::enclosingCompositingLayerForRepaint const):
     76        (WebCore::RenderLayer::clippingRootForPainting const):
     77        (WebCore::RenderLayer::scrollTo):
     78        (WebCore::RenderLayer::updateCompositingLayersAfterScroll):
     79        (WebCore::RenderLayer::updateScrollInfoAfterLayout):
     80        (WebCore::RenderLayer::paintLayerContents):
     81        (WebCore::RenderLayer::hitTest):
     82        (WebCore::RenderLayer::hitTestLayer):
     83        (WebCore::RenderLayer::calculateClipRects const):
     84        (WebCore::outputPaintOrderTreeLegend):
     85        (WebCore::outputPaintOrderTreeRecursive):
     86        (WebCore::compositingContainer): Deleted.
     87        * rendering/RenderLayer.h:
     88        (WebCore::RenderLayer::clearZOrderLists):
     89        (WebCore::RenderLayer::paintOrderParent const):
     90        * rendering/RenderLayerBacking.cpp:
     91        (WebCore::RenderLayerBacking::updateCompositedBounds):
     92        (WebCore::RenderLayerBacking::updateAfterWidgetResize):
     93        (WebCore::RenderLayerBacking::updateAfterLayout):
     94        (WebCore::RenderLayerBacking::updateConfigurationAfterStyleChange):
     95        (WebCore::RenderLayerBacking::updateConfiguration):
     96        (WebCore::RenderLayerBacking::updateGeometry):
     97        (WebCore::RenderLayerBacking::setRequiresBackgroundLayer):
     98        (WebCore::RenderLayerBacking::updateMaskingLayer):
     99        (WebCore::RenderLayerBacking::paintsContent const):
     100        (WebCore::RenderLayerBacking::contentChanged):
     101        (WebCore::RenderLayerBacking::setContentsNeedDisplay):
     102        (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
     103        (WebCore::RenderLayerBacking::startAnimation):
     104        (WebCore::RenderLayerBacking::animationFinished):
     105        (WebCore::RenderLayerBacking::startTransition):
     106        (WebCore::RenderLayerBacking::transitionFinished):
     107        (WebCore::RenderLayerBacking::setCompositedBounds):
     108        * rendering/RenderLayerBacking.h:
     109        * rendering/RenderLayerCompositor.cpp:
     110        (WebCore::RenderLayerCompositor::CompositingState::CompositingState):
     111        (WebCore::RenderLayerCompositor::enableCompositingMode):
     112        (WebCore::RenderLayerCompositor::cacheAcceleratedCompositingFlags):
     113        (WebCore::RenderLayerCompositor::cacheAcceleratedCompositingFlagsAfterLayout):
     114        (WebCore::RenderLayerCompositor::willRecalcStyle):
     115        (WebCore::RenderLayerCompositor::didRecalcStyleWithNoPendingLayout):
     116        (WebCore::RenderLayerCompositor::updateCompositingLayers):
     117        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
     118        (WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
     119        (WebCore::RenderLayerCompositor::updateBackingAndHierarchy):
     120        (WebCore::RenderLayerCompositor::appendDocumentOverlayLayers):
     121        (WebCore::RenderLayerCompositor::layerBecameNonComposited):
     122        (WebCore::RenderLayerCompositor::logLayerInfo):
     123        (WebCore::clippingChanged):
     124        (WebCore::styleAffectsLayerGeometry):
     125        (WebCore::RenderLayerCompositor::layerStyleChanged):
     126        (WebCore::RenderLayerCompositor::needsCompositingUpdateForStyleChangeOnNonCompositedLayer const):
     127        (WebCore::RenderLayerCompositor::updateBacking):
     128        (WebCore::RenderLayerCompositor::updateLayerCompositingState):
     129        (WebCore::RenderLayerCompositor::layerWasAdded):
     130        (WebCore::RenderLayerCompositor::layerWillBeRemoved):
     131        (WebCore::RenderLayerCompositor::enclosingNonStackingClippingLayer const):
     132        (WebCore::RenderLayerCompositor::computeExtent const):
     133        (WebCore::RenderLayerCompositor::addToOverlapMap):
     134        (WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
     135        (WebCore::RenderLayerCompositor::rootLayerConfigurationChanged):
     136        (WebCore::RenderLayerCompositor::parentFrameContentLayers):
     137        (WebCore::RenderLayerCompositor::updateRootLayerPosition):
     138        (WebCore::RenderLayerCompositor::needsToBeComposited const):
     139        (WebCore::RenderLayerCompositor::requiresCompositingLayer const):
     140        (WebCore::RenderLayerCompositor::requiresOwnBackingStore const):
     141        (WebCore::RenderLayerCompositor::reasonsForCompositing const):
     142        (WebCore::RenderLayerCompositor::clippedByAncestor const):
     143        (WebCore::RenderLayerCompositor::requiresCompositingForAnimation const):
     144        (WebCore::RenderLayerCompositor::requiresCompositingForTransform const):
     145        (WebCore::RenderLayerCompositor::requiresCompositingForVideo const):
     146        (WebCore::RenderLayerCompositor::requiresCompositingForFilters const):
     147        (WebCore::RenderLayerCompositor::requiresCompositingForWillChange const):
     148        (WebCore::RenderLayerCompositor::requiresCompositingForPlugin const):
     149        (WebCore::RenderLayerCompositor::requiresCompositingForFrame const):
     150        (WebCore::RenderLayerCompositor::requiresCompositingForScrollableFrame const):
     151        (WebCore::RenderLayerCompositor::requiresCompositingForPosition const):
     152        (WebCore::RenderLayerCompositor::requiresCompositingForOverflowScrolling const):
     153        (WebCore::RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons):
     154        (WebCore::RenderLayerCompositor::fixedLayerIntersectsViewport const):
     155        (WebCore::RenderLayerCompositor::useCoordinatedScrollingForLayer const):
     156        (WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
     157        (WebCore::RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged):
     158        (WebCore::operator<<):
     159        (WebCore::RenderLayerCompositor::setCompositingLayersNeedRebuild): Deleted.
     160        (WebCore::checkIfDescendantClippingContextNeedsUpdate): Deleted.
     161        (WebCore::isScrollableOverflow): Deleted.
     162        (WebCore::styleHasTouchScrolling): Deleted.
     163        (WebCore::styleChangeRequiresLayerRebuild): Deleted.
     164        (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Deleted.
     165        (WebCore::RenderLayerCompositor::rootFixedBackgroundsChanged): Deleted.
     166        (WebCore::RenderLayerCompositor::updateLayerTreeGeometry): Deleted.
     167        (WebCore::RenderLayerCompositor::updateCompositingDescendantGeometry): Deleted.
     168        * rendering/RenderLayerCompositor.h:
     169        * rendering/RenderTreeAsText.cpp:
     170        (WebCore::writeLayers):
     171
    11722018-11-12  Rob Buis  <rbuis@igalia.com>
    2173
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

    r237009 r238090  
    924924        m_markedCanvasDirty = true;
    925925        htmlCanvas()->clearCopiedImage();
    926         renderBox->contentChanged(CanvasChanged);
     926        renderBox->contentChanged(CanvasPixelsChanged);
    927927    } else {
    928928        if (!m_markedCanvasDirty) {
  • trunk/Source/WebCore/page/FrameView.cpp

    r238064 r238090  
    24102410        return;
    24112411
    2412     for (auto& renderer : *m_viewportConstrainedObjects)
     2412    for (auto& renderer : *m_viewportConstrainedObjects) {
    24132413        renderer->setNeedsLayout();
     2414        if (renderer->hasLayer()) {
     2415            auto* layer = downcast<RenderBoxModelObject>(*renderer).layer();
     2416            layer->setNeedsCompositingGeometryUpdate();
     2417        }
     2418    }
    24142419}
    24152420
  • trunk/Source/WebCore/page/Page.cpp

    r238049 r238090  
    880880
    881881    if (!m_settings->delegatesPageScaling()) {
    882         if (document->renderView())
    883             document->renderView()->setNeedsLayout();
     882        if (auto* renderView = document->renderView()) {
     883            renderView->setNeedsLayout();
     884            if (renderView->hasLayer() && renderView->layer()->isComposited())
     885                renderView->layer()->setNeedsCompositingGeometryUpdate();
     886        }
    884887
    885888        document->resolveStyle(Document::ResolveStyleType::Rebuild);
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r238070 r238090  
    21572157    }
    21582158
    2159     if (madeLayer)
     2159    if (madeLayer) {
    21602160        updateBackdropFiltersRect();
     2161        noteSublayersChanged(DontScheduleFlush);
     2162    }
    21612163}
    21622164
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r238001 r238090  
    262262            view().repaintRootContents();
    263263            if (oldStyle->hasEntirelyFixedBackground() != newStyle.hasEntirelyFixedBackground())
    264                 view().compositor().rootFixedBackgroundsChanged();
     264                view().compositor().rootLayerConfigurationChanged();
    265265        }
    266266       
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r238070 r238090  
    274274    , m_zOrderListsDirty(false)
    275275    , m_normalFlowListDirty(true)
     276    , m_hadNegativeZOrderList(false)
    276277    , m_inResizeMode(false)
    277278    , m_scrollDimensionsDirty(true)
     
    287288    , m_hasVisibleDescendant(false)
    288289    , m_registeredScrollableArea(false)
     290    , m_isFixedIntersectingViewport(false)
    289291    , m_3DTransformedDescendantStatusDirty(true)
    290292    , m_has3DTransformedDescendant(false)
     
    372374
    373375    // Layer and all its children should be removed from the tree before destruction.
    374     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(renderer().renderTreeBeingDestroyed() || !m_parent);
    375     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(renderer().renderTreeBeingDestroyed() || !m_first);
     376    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(renderer().renderTreeBeingDestroyed() || !parent());
     377    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(renderer().renderTreeBeingDestroyed() || !firstChild());
    376378}
    377379
     
    404406        setAncestorChainHasSelfPaintingLayerDescendant();
    405407
     408    if (compositor().inCompositingMode())
     409        setDescendantsNeedCompositingRequirementsTraversal();
     410
     411    if (child.hasDescendantNeedingCompositingRequirementsTraversal() || child.needsCompositingRequirementsTraversal())
     412        child.setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingRequirementsTraversal);
     413
     414    if (child.hasDescendantNeedingUpdateBackingOrHierarchyTraversal() || child.needsUpdateBackingOrHierarchyTraversal())
     415        child.setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal);
     416
    406417#if ENABLE(CSS_COMPOSITING)
    407418    if (child.hasBlendMode() || (child.hasNotIsolatedBlendingDescendants() && !child.isolatesBlending()))
     
    440451    if (oldChild.isSelfPaintingLayer() || oldChild.hasSelfPaintingLayerDescendant())
    441452        dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
     453
     454    if (compositor().inCompositingMode())
     455        setDescendantsNeedCompositingRequirementsTraversal();
    442456
    443457#if ENABLE(CSS_COMPOSITING)
     
    553567bool RenderLayer::shouldBeStackingContext() const
    554568{
    555     // Non-auto z-index always implies stacking context here, because StyleResolver::adjustRenderStyle already adjusts z-index
    556     // based on positioning and other criteria.
    557569    return !renderer().style().hasAutoZIndex() || isRenderViewLayer() || isForcedStackingContext();
    558570}
     
    601613}
    602614
     615RenderLayer* RenderLayer::stackingContext() const
     616{
     617    auto* layer = parent();
     618    while (layer && !layer->isStackingContext())
     619        layer = layer->parent();
     620
     621    ASSERT(!layer || layer->isStackingContext());
     622    return layer;
     623}
     624
    603625void RenderLayer::dirtyZOrderLists()
    604626{
    605     ASSERT(m_layerListMutationAllowed);
     627    ASSERT(layerListMutationAllowed());
    606628    ASSERT(isStackingContext());
    607629
     
    612634    m_zOrderListsDirty = true;
    613635
    614     if (!renderer().renderTreeBeingDestroyed())
    615         compositor().setCompositingLayersNeedRebuild();
     636    // FIXME: Ideally, we'd only dirty if the lists changed.
     637    if (hasCompositingDescendant())
     638        setNeedsCompositingPaintOrderChildrenUpdate();
    616639}
    617640
     
    624647void RenderLayer::dirtyNormalFlowList()
    625648{
    626     ASSERT(m_layerListMutationAllowed);
     649    ASSERT(layerListMutationAllowed());
    627650
    628651    if (m_normalFlowList)
     
    630653    m_normalFlowListDirty = true;
    631654
    632     if (!renderer().renderTreeBeingDestroyed())
    633         compositor().setCompositingLayersNeedRebuild();
     655    if (hasCompositingDescendant())
     656        setNeedsCompositingPaintOrderChildrenUpdate();
    634657}
    635658
     
    639662        return;
    640663
    641     ASSERT(m_layerListMutationAllowed);
     664    ASSERT(layerListMutationAllowed());
    642665
    643666    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
     
    655678void RenderLayer::rebuildZOrderLists()
    656679{
    657     ASSERT(m_layerListMutationAllowed);
     680    ASSERT(layerListMutationAllowed());
    658681    ASSERT(isDirtyStackingContext());
    659682    rebuildZOrderLists(m_posZOrderList, m_negZOrderList);
    660683    m_zOrderListsDirty = false;
     684   
     685    bool hasNegativeZOrderList = m_negZOrderList && m_negZOrderList->size();
     686    // Having negative z-order lists affect whether a compositing layer needs a foreground layer.
     687    // Ideally we'd only trigger this when having z-order children changes, but we blow away the old z-order
     688    // lists on dirtying so we don't know the old state.
     689    if (hasNegativeZOrderList != m_hadNegativeZOrderList) {
     690        m_hadNegativeZOrderList = hasNegativeZOrderList;
     691        if (isComposited())
     692            setNeedsCompositingConfigurationUpdate();
     693    }
    661694}
    662695
     
    703736                child->collectLayers(includeHiddenLayers, positiveZOrderList, negativeZOrderList);
    704737        }
     738    }
     739}
     740
     741void RenderLayer::setAncestorsHaveCompositingDirtyFlag(Compositing flag)
     742{
     743    for (auto* layer = paintOrderParent(); layer; layer = layer->paintOrderParent()) {
     744        if (layer->m_compositingDirtyBits.contains(flag))
     745            break;
     746        layer->m_compositingDirtyBits.add(flag);
    705747    }
    706748}
     
    767809void RenderLayer::contentChanged(ContentChangeType changeType)
    768810{
    769     if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged || changeType == ImageChanged) && compositor().updateLayerCompositingState(*this))
    770         compositor().setCompositingLayersNeedRebuild();
    771 
    772     if (m_backing)
    773         m_backing->contentChanged(changeType);
     811    if (changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged || (isComposited() && changeType == ImageChanged)) {
     812        setNeedsPostLayoutCompositingUpdate();
     813        setNeedsCompositingConfigurationUpdate();
     814    }
     815
     816    if (auto* backing = this->backing())
     817        backing->contentChanged(changeType);
    774818}
    775819
     
    881925        m_reflection->layout();
    882926
    883     // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
    884     bool isUpdateRoot = flags.contains(IsCompositingUpdateRoot);
    885     if (isComposited())
    886         flags.remove(IsCompositingUpdateRoot);
    887 
    888927    if (renderer().isInFlowRenderFragmentedFlow()) {
    889928        updatePagination();
     
    900939        child->updateLayerPositions(geometryMap, flags);
    901940
    902     if ((flags & UpdateCompositingLayers) && isComposited()) {
    903         OptionSet<RenderLayerBacking::UpdateAfterLayoutFlags> updateFlags;
    904         if (flags & NeedsFullRepaintInBacking)
    905             updateFlags.add(RenderLayerBacking::UpdateAfterLayoutFlags::NeedsFullRepaint);
    906         if (isUpdateRoot)
    907             updateFlags.add(RenderLayerBacking::UpdateAfterLayoutFlags::IsUpdateRoot);
    908         backing()->updateAfterLayout(updateFlags);
    909     }
    910        
    911941    // With all our children positioned, now update our marquee if we need to.
    912942    if (m_marquee) {
     
    917947        m_updatingMarqueePosition = oldUpdatingMarqueePosition;
    918948    }
     949
     950    if (renderer().isOutOfFlowPositioned() && renderer().style().position() == PositionType::Fixed && renderer().settings().acceleratedCompositingForFixedPositionEnabled()) {
     951        bool intersectsViewport = compositor().fixedLayerIntersectsViewport(*this);
     952        if (intersectsViewport != m_isFixedIntersectingViewport) {
     953            m_isFixedIntersectingViewport = intersectsViewport;
     954            setNeedsPostLayoutCompositingUpdate();
     955        }
     956    }
     957
     958    if (isComposited())
     959        backing()->updateAfterLayout(flags.contains(NeedsFullRepaintInBacking));
    919960
    920961    if (geometryMap)
     
    11411182    }
    11421183
    1143     if (had3DTransform != has3DTransform())
     1184    if (had3DTransform != has3DTransform()) {
    11441185        dirty3DTransformedDescendantStatus();
     1186        // Having a 3D transform affects whether enclosing perspective and preserve-3d layers composite, so trigger an update.
     1187        setNeedsPostLayoutCompositingUpdateOnAncestors();
     1188    }
    11451189}
    11461190
     
    15241568    positionOrOffsetChanged |= location() != localPoint;
    15251569    setLocation(localPoint);
     1570   
     1571    if (positionOrOffsetChanged && compositor().inCompositingMode()) {
     1572        if (isComposited())
     1573            setNeedsCompositingGeometryUpdate();
     1574        // This layer's position can affect the location of a composited descendant (which may be a sibling in z-order),
     1575        // so trigger a descendant walk from the paint-order parent.
     1576        if (auto* paintParent = paintOrderParent())
     1577            paintParent->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
     1578    }
     1579
    15261580    return positionOrOffsetChanged;
    15271581}
     
    15701624}
    15711625
    1572 RenderLayer* RenderLayer::stackingContext() const
    1573 {
    1574     RenderLayer* layer = parent();
    1575     while (layer && !layer->isStackingContext())
    1576         layer = layer->parent();
    1577 
    1578     ASSERT(!layer || layer->isStackingContext());
    1579     return layer;
    1580 }
    1581 
    15821626static inline bool isContainerForPositioned(RenderLayer& layer, PositionType position)
    15831627{
     
    16601704
    16611705    return curr;
    1662 }
    1663 
    1664 static inline const RenderLayer* compositingContainer(const RenderLayer& layer)
    1665 {
    1666     return layer.isNormalFlowOnly() ? layer.parent() : layer.stackingContext();
    16671706}
    16681707
     
    16881727        return const_cast<RenderLayer*>(this);
    16891728
    1690     for (const RenderLayer* curr = compositingContainer(*this); curr; curr = compositingContainer(*curr)) {
     1729    for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
    16911730        if (curr->isComposited())
    16921731            return const_cast<RenderLayer*>(curr);
     
    17011740        return const_cast<RenderLayer*>(this);
    17021741
    1703     for (const RenderLayer* curr = compositingContainer(*this); curr; curr = compositingContainer(*curr)) {
     1742    for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
    17041743        if (compositedWithOwnBackingStore(*curr))
    17051744            return const_cast<RenderLayer*>(curr);
     
    17901829            return const_cast<RenderLayer*>(current);
    17911830
    1792         current = compositingContainer(*current);
     1831        current = current->paintOrderParent();
    17931832        ASSERT(current);
    17941833        if (current->transform() || compositedWithOwnBackingStore(*current))
     
    23282367    if (m_scrollPosition == newPosition) {
    23292368#if PLATFORM(IOS_FAMILY)
    2330         if (m_requiresScrollBoundsOriginUpdate)
     2369        if (m_requiresScrollBoundsOriginUpdate) {
     2370            setNeedsCompositingGeometryUpdate();
    23312371            updateCompositingLayersAfterScroll();
     2372        }
    23322373#endif
    23332374        return;
     
    23542395            // in this case we're still updating their positions; we'll update compositing layers later
    23552396            // when that completes.
     2397            if (usesCompositedScrolling()) {
     2398                setNeedsCompositingGeometryUpdate();
     2399                setDescendantsNeedUpdateBackingAndHierarchyTraversal();
     2400            }
     2401
    23562402            updateCompositingLayersAfterScroll();
    23572403        }
     
    23762422
    23772423    bool requiresRepaint = true;
    2378     if (compositor().inCompositingMode() && usesCompositedScrolling())
     2424    if (compositor().inCompositingMode() && usesCompositedScrolling()) {
     2425        setNeedsCompositingGeometryUpdate();
     2426        setDescendantsNeedUpdateBackingAndHierarchyTraversal();
    23792427        requiresRepaint = false;
     2428    }
    23802429
    23812430    // Just schedule a full repaint of our object.
     
    25292578            if (usesCompositedScrolling())
    25302579                compositor().updateCompositingLayers(CompositingUpdateType::OnCompositedScroll, compositingAncestor);
    2531             else
     2580            else {
     2581                // FIXME: would be nice to only dirty layers whose positions were affected by scrolling.
     2582                compositingAncestor->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
    25322583                compositor().updateCompositingLayers(CompositingUpdateType::OnScroll, compositingAncestor);
     2584            }
    25332585        }
    25342586    }
     
    35193571        scrollToOffsetWithoutAnimation(IntPoint(scrollOffset()));
    35203572
    3521     // Composited scrolling may need to be enabled or disabled if the amount of overflow changed.
    3522     // FIXME: this should just dirty the layer and updateLayerPositions should do stuff.
    3523     if (compositor().updateLayerCompositingState(*this))
    3524         compositor().setCompositingLayersNeedRebuild();
     3573    if (isComposited())
     3574        setNeedsCompositingGeometryUpdate();
    35253575
    35263576    updateScrollSnapState();
     
    42004250        return;
    42014251
    4202     // Ensure our lists are up-to-date.
    42034252    updateLayerListsIfNeeded();
    42044253
     
    47934842    ASSERT(!renderer().view().needsLayout());
    47944843   
    4795     updateLayerListsIfNeeded();
    4796 
    47974844    ASSERT(!isRenderFragmentedFlow());
    47984845    LayoutRect hitTestArea = renderer().view().documentRect();
     
    49374984                                       const HitTestingTransformState* transformState, double* zOffset)
    49384985{
     4986    updateLayerListsIfNeeded();
     4987
    49394988    if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
    49404989        return nullptr;
     
    49605009
    49615010    // Ensure our lists and 3d status are up-to-date.
    4962     updateCompositingAndLayerListsIfNeeded();
    49635011    update3DTransformedDescendantStatus();
    49645012
     
    57295777}
    57305778
     5779LayoutRect RenderLayer::overlapBounds() const
     5780{
     5781    if (overlapBoundsIncludeChildren())
     5782        return calculateLayerBounds(this, { }, defaultCalculateLayerBoundsFlags() | IncludeFilterOutsets);
     5783   
     5784    return localBoundingBox();
     5785}
     5786
    57315787LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, OptionSet<CalculateLayerBoundsFlag> flags) const
    57325788{
     
    58105866        computeLayersUnion(*childLayer);
    58115867
    5812     // FIXME: We can optimize the size of the composited layers, by not enlarging
    5813     // filtered areas with the outsets if we know that the filter is going to render in hardware.
    5814     // https://bugs.webkit.org/show_bug.cgi?id=81239
    5815     if (flags & IncludeLayerFilterOutsets)
     5868    if (flags.contains(IncludeFilterOutsets) || (flags.contains(IncludePaintedFilterOutsets) && paintsWithFilters()))
    58165869        renderer().style().filterOutsets().expandRect(unionBounds);
    58175870
     
    59586011    // This function should not be called when layer-lists are dirty.
    59596012    // It is somehow getting triggered during style update.
    5960     if (m_zOrderListsDirty || m_normalFlowListDirty)
     6013    if (zOrderListsDirty() || normalFlowListDirty())
    59616014        return false;
    59626015
     
    60006053    }
    60016054    return false;
    6002 }
    6003 
    6004 void RenderLayer::updateCompositingAndLayerListsIfNeeded()
    6005 {
    6006     if (compositor().inCompositingMode()) {
    6007         if (isDirtyStackingContext() || m_normalFlowListDirty)
    6008             compositor().updateCompositingLayers(CompositingUpdateType::OnHitTest, this);
    6009         return;
    6010     }
    6011 
    6012     updateLayerListsIfNeeded();
    60136055}
    60146056
     
    65856627{
    65866628    stream.nextLine();
    6587     stream << "(S)tacking Context, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited\n"
    6588         "Dirty (z)-lists, Dirty (n)ormal flow lists";
     6629    stream << "(S)tacking Context, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited\n"
     6630        "Dirty (z)-lists, Dirty (n)ormal flow lists\n"
     6631        "Descendant needs overlap (t)raversal, Descendant needs (b)acking or hierarchy update, All descendants need (r)equirements traversal, All (s)ubsequent layers need requirements traversal, All descendants need (h)ierarchy traversal\n"
     6632        "Needs compositing paint order update on (s)ubsequent layers, Needs compositing paint (o)rder children update, "
     6633        "Needs post-(l)ayout update, Needs compositing (g)eometry update, (k)ids need geometry update, Needs compositing (c)onfig update, Needs compositing layer conne(x)ion update";
    65896634    stream.nextLine();
    65906635}
     
    66036648    stream << (layer.renderer().hasOverflowClip() ? "O" : "-");
    66046649    stream << (layer.isTransparent() ? "A" : "-");
     6650    stream << (layer.hasBlendMode() ? "B" : "-");
     6651    stream << (layer.isolatesBlending() ? "I" : "-");
    66056652    stream << (layer.renderer().hasTransformRelatedProperty() ? "T" : "-");
    66066653    stream << (layer.hasFilter() ? "F" : "-");
     
    66136660    stream << (layer.normalFlowListDirty() ? "n" : "-");
    66146661
     6662    stream << " ";
     6663
     6664    stream << (layer.hasDescendantNeedingCompositingRequirementsTraversal() ? "t" : "-");
     6665    stream << (layer.hasDescendantNeedingUpdateBackingOrHierarchyTraversal() ? "b" : "-");
     6666    stream << (layer.descendantsNeedCompositingRequirementsTraversal() ? "r" : "-");
     6667    stream << (layer.subsequentLayersNeedCompositingRequirementsTraversal() ? "s" : "-");
     6668    stream << (layer.descendantsNeedUpdateBackingAndHierarchyTraversal() ? "h" : "-");
     6669
     6670    stream << " ";
     6671
     6672    stream << (layer.needsCompositingPaintOrderChildrenUpdate() ? "o" : "-");
     6673    stream << (layer.needsPostLayoutCompositingUpdate() ? "l" : "-");
     6674    stream << (layer.needsCompositingGeometryUpdate() ? "g" : "-");
     6675    stream << (layer.childrenNeedCompositingGeometryUpdate() ? "k" : "-");
     6676    stream << (layer.needsCompositingConfigurationUpdate() ? "c" : "-");
     6677    stream << (layer.needsCompositingLayerConnection() ? "x" : "-");
     6678
     6679    stream << " ";
     6680
    66156681    outputIdent(stream, depth);
    66166682
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r237266 r238090  
    179179    RenderLayer* enclosingStackingContext() { return isStackingContext() ? this : stackingContext(); }
    180180
     181    RenderLayer* paintOrderParent() const;
     182
    181183    void dirtyNormalFlowList();
    182184    void dirtyZOrderLists();
     
    185187    bool normalFlowListDirty() const { return m_normalFlowListDirty; }
    186188    bool zOrderListsDirty() const { return m_zOrderListsDirty; }
     189
     190#if !ASSERT_DISABLED
     191    bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
     192    void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }
     193#endif
     194
     195private:
     196    // These flags propagate in paint order (z-order tree).
     197    enum class Compositing {
     198        HasDescendantNeedingRequirementsTraversal           = 1 << 0, // Need to do the overlap-testing tree walk because hierarchy or geometry changed.
     199        HasDescendantNeedingBackingOrHierarchyTraversal     = 1 << 1, // Need to update geometry, configuration and update the GraphicsLayer tree.
     200
     201        // Things that trigger HasDescendantNeedingRequirementsTraversal
     202        NeedsPaintOrderChildrenUpdate                       = 1 << 2, // The paint order children of this layer changed (gained/lost child, order change).
     203        NeedsPostLayoutUpdate                               = 1 << 3, // Needs compositing to be re-evaluated after layout (it depends on geometry).
     204        DescendantsNeedRequirementsTraversal                = 1 << 4, // Something changed that forces computeCompositingRequirements to traverse all descendant layers.
     205        SubsequentLayersNeedRequirementsTraversal           = 1 << 5, // Something changed that forces computeCompositingRequirements to traverse all layers later in paint order.
     206
     207        // Things that trigger HasDescendantNeedingBackingOrHierarchyTraversal
     208        NeedsGeometryUpdate                                 = 1 << 6, // This layer needs a geometry update.
     209        NeedsConfigurationUpdate                            = 1 << 7, // This layer needs a configuration update (updating its internal compositing hierarchy).
     210        NeedsLayerConnection                                = 1 << 8, // This layer needs hookup with its parents or children.
     211        ChildrenNeedGeometryUpdate                          = 1 << 9, // This layer's composited children needs a geometry update.
     212        DescendantsNeedBackingAndHierarchyTraversal         = 1 << 10, // Something changed that forces us to traverse all descendant layers in updateBackingAndHierarchy.
     213    };
     214
     215    static constexpr OptionSet<Compositing> computeCompositingRequirementsFlags()
     216    {
     217        return {
     218            Compositing::NeedsPaintOrderChildrenUpdate,
     219            Compositing::NeedsPostLayoutUpdate,
     220            Compositing::DescendantsNeedRequirementsTraversal,
     221            Compositing::SubsequentLayersNeedRequirementsTraversal,
     222        };
     223    }
     224
     225    static constexpr OptionSet<Compositing> updateBackingOrHierarchyFlags()
     226    {
     227        return {
     228            Compositing::NeedsLayerConnection,
     229            Compositing::NeedsGeometryUpdate,
     230            Compositing::NeedsConfigurationUpdate,
     231            Compositing::ChildrenNeedGeometryUpdate,
     232            Compositing::DescendantsNeedBackingAndHierarchyTraversal,
     233        };
     234    }
     235
     236    void setAncestorsHaveCompositingDirtyFlag(Compositing);
     237
     238public:
     239    bool hasDescendantNeedingCompositingRequirementsTraversal() const { return m_compositingDirtyBits.contains(Compositing::HasDescendantNeedingRequirementsTraversal); }
     240    bool hasDescendantNeedingUpdateBackingOrHierarchyTraversal() const { return m_compositingDirtyBits.contains(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal); }
     241
     242    bool needsCompositingPaintOrderChildrenUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsPaintOrderChildrenUpdate); }
     243    bool needsPostLayoutCompositingUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsPostLayoutUpdate); }
     244    bool descendantsNeedCompositingRequirementsTraversal() const { return m_compositingDirtyBits.contains(Compositing::DescendantsNeedRequirementsTraversal); }
     245    bool subsequentLayersNeedCompositingRequirementsTraversal() const { return m_compositingDirtyBits.contains(Compositing::SubsequentLayersNeedRequirementsTraversal); }
     246
     247    bool needsCompositingLayerConnection() const { return m_compositingDirtyBits.contains(Compositing::NeedsLayerConnection); }
     248    bool needsCompositingGeometryUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsGeometryUpdate); }
     249    bool needsCompositingConfigurationUpdate() const { return m_compositingDirtyBits.contains(Compositing::NeedsConfigurationUpdate); }
     250    bool childrenNeedCompositingGeometryUpdate() const { return m_compositingDirtyBits.contains(Compositing::ChildrenNeedGeometryUpdate); }
     251    bool descendantsNeedUpdateBackingAndHierarchyTraversal() const { return m_compositingDirtyBits.contains(Compositing::DescendantsNeedBackingAndHierarchyTraversal); }
     252
     253    template<Compositing V>
     254    void setRequirementsTraversalDirtyBit()
     255    {
     256        m_compositingDirtyBits.add(V);
     257        setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingRequirementsTraversal);
     258    }
     259
     260    void setNeedsCompositingPaintOrderChildrenUpdate() { setRequirementsTraversalDirtyBit<Compositing::NeedsPaintOrderChildrenUpdate>(); }
     261    void setNeedsPostLayoutCompositingUpdate() { setRequirementsTraversalDirtyBit<Compositing::NeedsPostLayoutUpdate>(); }
     262    void setDescendantsNeedCompositingRequirementsTraversal() { setRequirementsTraversalDirtyBit<Compositing::DescendantsNeedRequirementsTraversal>(); }
     263    void setSubsequentLayersNeedCompositingRequirementsTraversal() { setRequirementsTraversalDirtyBit<Compositing::SubsequentLayersNeedRequirementsTraversal>(); }
     264
     265    void setNeedsPostLayoutCompositingUpdateOnAncestors() { setAncestorsHaveCompositingDirtyFlag(Compositing::NeedsPostLayoutUpdate); }
     266
     267    template<Compositing V>
     268    void setBackingAndHierarchyTraversalDirtyBit()
     269    {
     270        m_compositingDirtyBits.add(V);
     271        setAncestorsHaveCompositingDirtyFlag(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal);
     272    }
     273
     274    void setNeedsCompositingLayerConnection() { setBackingAndHierarchyTraversalDirtyBit<Compositing::NeedsLayerConnection>(); }
     275    void setNeedsCompositingGeometryUpdate() { setBackingAndHierarchyTraversalDirtyBit<Compositing::NeedsGeometryUpdate>(); }
     276    void setNeedsCompositingConfigurationUpdate() { setBackingAndHierarchyTraversalDirtyBit<Compositing::NeedsConfigurationUpdate>(); }
     277    void setChildrenNeedCompositingGeometryUpdate() { setBackingAndHierarchyTraversalDirtyBit<Compositing::ChildrenNeedGeometryUpdate>(); }
     278    void setDescendantsNeedUpdateBackingAndHierarchyTraversal() { setBackingAndHierarchyTraversalDirtyBit<Compositing::DescendantsNeedBackingAndHierarchyTraversal>(); }
     279
     280    void setNeedsCompositingGeometryUpdateOnAncestors() { setAncestorsHaveCompositingDirtyFlag(Compositing::NeedsGeometryUpdate); }
     281
     282    bool needsCompositingRequirementsTraversal() const { return m_compositingDirtyBits.containsAny(computeCompositingRequirementsFlags()); }
     283    void clearCompositingRequirementsTraversalState()
     284    {
     285        m_compositingDirtyBits.remove(Compositing::HasDescendantNeedingRequirementsTraversal);
     286        m_compositingDirtyBits.remove(computeCompositingRequirementsFlags());
     287    }
     288
     289    bool needsUpdateBackingOrHierarchyTraversal() const { return m_compositingDirtyBits.containsAny(updateBackingOrHierarchyFlags()); }
     290    void clearUpdateBackingOrHierarchyTraversalState()
     291    {
     292        m_compositingDirtyBits.remove(Compositing::HasDescendantNeedingBackingOrHierarchyTraversal);
     293        m_compositingDirtyBits.remove(updateBackingOrHierarchyFlags());
     294    }
     295
     296    bool needsAnyCompositingTraversal() const { return !m_compositingDirtyBits.isEmpty(); }
     297    void clearCompositingPaintOrderState() { m_compositingDirtyBits = { }; }
    187298
    188299    class LayerList {
     
    244355    // Update our normal and z-index lists.
    245356    void updateLayerListsIfNeeded();
     357    void updateDescendantDependentFlags();
     358    bool descendantDependentFlagsAreDirty() const
     359    {
     360        return m_visibleDescendantStatusDirty || m_visibleContentStatusDirty || m_hasSelfPaintingLayerDescendantDirty
     361#if ENABLE(CSS_COMPOSITING)
     362            || m_hasNotIsolatedBlendingDescendantsStatusDirty
     363#endif
     364        ;
     365    }
    246366
    247367    void repaintIncludingDescendants();
     
    275395
    276396    const IntSize& size() const { return m_layerSize; }
    277     void setSize(const IntSize& size) { m_layerSize = size; }
     397    void setSize(const IntSize& size) { m_layerSize = size; } // Only public for RenderTreeAsText.
    278398
    279399    LayoutRect rect() const { return LayoutRect(location(), size()); }
     
    385505        CheckForRepaint                 = 1 << 0,
    386506        NeedsFullRepaintInBacking       = 1 << 1,
    387         IsCompositingUpdateRoot         = 1 << 2,
    388         UpdateCompositingLayers         = 1 << 3,
    389         UpdatePagination                = 1 << 4,
    390         SeenTransformedLayer            = 1 << 5,
    391         Seen3DTransformedLayer          = 1 << 6,
     507        UpdatePagination                = 1 << 2,
     508        SeenTransformedLayer            = 1 << 3,
     509        Seen3DTransformedLayer          = 1 << 4,
    392510    };
    393     static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint, IsCompositingUpdateRoot, UpdateCompositingLayers }; }
     511    static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint }; }
    394512
    395513    void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, OptionSet<UpdateLayerPositionsFlag>);
     
    570688        IncludeSelfTransform                    = 1 << 0,
    571689        UseLocalClipRectIfPossible              = 1 << 1,
    572         IncludeLayerFilterOutsets               = 1 << 2,
    573         ExcludeHiddenDescendants                = 1 << 3,
    574         DontConstrainForMask                    = 1 << 4,
    575         IncludeCompositedDescendants            = 1 << 5,
    576         UseFragmentBoxesExcludingCompositing    = 1 << 6,
    577         UseFragmentBoxesIncludingCompositing    = 1 << 7,
    578 
     690        IncludeFilterOutsets                    = 1 << 2,
     691        IncludePaintedFilterOutsets             = 1 << 3,
     692        ExcludeHiddenDescendants                = 1 << 4,
     693        DontConstrainForMask                    = 1 << 5,
     694        IncludeCompositedDescendants            = 1 << 6,
     695        UseFragmentBoxesExcludingCompositing    = 1 << 7,
     696        UseFragmentBoxesIncludingCompositing    = 1 << 8,
    579697    };
    580     static constexpr OptionSet<CalculateLayerBoundsFlag> defaultCalculateLayerBoundsFlags() { return { IncludeSelfTransform, UseLocalClipRectIfPossible, IncludeLayerFilterOutsets, UseFragmentBoxesExcludingCompositing }; }
     698    static constexpr OptionSet<CalculateLayerBoundsFlag> defaultCalculateLayerBoundsFlags() { return { IncludeSelfTransform, UseLocalClipRectIfPossible, IncludePaintedFilterOutsets, UseFragmentBoxesExcludingCompositing }; }
    581699
    582700    // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known.
     
    590708
    591709    // Bounds used for layer overlap testing in RenderLayerCompositor.
    592     LayoutRect overlapBounds() const { return overlapBoundsIncludeChildren() ? calculateLayerBounds(this, LayoutSize()) : localBoundingBox(); }
     710    LayoutRect overlapBounds() const;
    593711   
    594712    // Takes transform animations into account, returning true if they could be cheaply computed.
     
    709827    bool requiresFullLayerImageForFilters() const;
    710828
    711 #if !ASSERT_DISABLED
    712     bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
    713     void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }
    714 #endif
    715 
    716829    Element* enclosingElement() const;
    717830
     
    732845    {
    733846        ASSERT(isRenderFragmentedFlow());
    734         return m_zOrderListsDirty || m_normalFlowListDirty;
     847        return zOrderListsDirty() || normalFlowListDirty();
    735848    }
    736849
     
    797910    ClipRects* clipRects(const ClipRectsContext&) const;
    798911
    799 
    800912    void setAncestorChainHasSelfPaintingLayerDescendant();
    801913    void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
     
    835947
    836948    LayoutPoint renderBoxLocation() const { return is<RenderBox>(renderer()) ? downcast<RenderBox>(renderer()).location() : LayoutPoint(); }
    837 
    838     void updateCompositingAndLayerListsIfNeeded();
    839949
    840950    bool setupFontSubpixelQuantization(GraphicsContext&, bool& didQuantizeFonts);
     
    9581068    void setAncestorChainHasVisibleDescendant();
    9591069
    960     void updateDescendantDependentFlags();
    961 
    9621070    bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
    9631071
     
    10371145    bool overflowControlsIntersectRect(const IntRect& localRect) const;
    10381146
    1039     // The bitfields are up here so they will fall into the padding from ScrollableArea on 64-bit.
     1147    OptionSet<Compositing> m_compositingDirtyBits;
    10401148
    10411149    const bool m_isRenderViewLayer : 1;
     
    10471155    bool m_zOrderListsDirty : 1;
    10481156    bool m_normalFlowListDirty: 1;
     1157    bool m_hadNegativeZOrderList : 1;
    10491158
    10501159    // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop.
     
    10711180    bool m_hasVisibleDescendant : 1;
    10721181    bool m_registeredScrollableArea : 1;
     1182    bool m_isFixedIntersectingViewport : 1;
    10731183
    10741184    bool m_3DTransformedDescendantStatusDirty : 1;
     
    11761286{
    11771287    ASSERT(!isStackingContext());
    1178     ASSERT(m_layerListMutationAllowed);
     1288    ASSERT(layerListMutationAllowed());
    11791289
    11801290    m_posZOrderList = nullptr;
     
    11941304
    11951305    rebuildZOrderLists();
     1306}
     1307
     1308inline RenderLayer* RenderLayer::paintOrderParent() const
     1309{
     1310    return m_isNormalFlowOnly ? m_parent : stackingContext();
    11961311}
    11971312
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r238070 r238090  
    592592}
    593593
    594 void RenderLayerBacking::updateCompositedBounds()
     594bool RenderLayerBacking::updateCompositedBounds()
    595595{
    596596    LayoutRect layerBounds = m_owningLayer.calculateLayerBounds(&m_owningLayer, LayoutSize(), RenderLayer::defaultCalculateLayerBoundsFlags() | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
     
    627627        m_artificiallyInflatedBounds = false;
    628628
    629     setCompositedBounds(layerBounds);
     629    return setCompositedBounds(layerBounds);
    630630}
    631631
     
    634634    if (!is<RenderWidget>(renderer()))
    635635        return;
     636
    636637    if (auto* innerCompositor = RenderLayerCompositor::frameContentsCompositor(&downcast<RenderWidget>(renderer()))) {
    637638        innerCompositor->frameViewDidChangeSize();
     
    640641}
    641642
    642 void RenderLayerBacking::updateAfterLayout(OptionSet<UpdateAfterLayoutFlags> flags)
     643void RenderLayerBacking::updateAfterLayout(bool needsFullRepaint)
    643644{
    644645    LOG(Compositing, "RenderLayerBacking %p updateAfterLayout (layer %p)", this, &m_owningLayer);
    645646
    646     if (!compositor().compositingLayersNeedRebuild()) {
    647         // Calling updateGeometry() here gives incorrect results, because the
    648         // position of this layer's GraphicsLayer depends on the position of our compositing
    649         // ancestor's GraphicsLayer. That cannot be determined until all the descendant
    650         // RenderLayers of that ancestor have been processed via updateLayerPositions().
    651         //
    652         // The solution is to update compositing children of this layer here,
    653         // via updateCompositingChildrenGeometry().
    654         updateCompositedBounds();
    655         compositor().updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer);
    656        
    657         if (flags.contains(UpdateAfterLayoutFlags::IsUpdateRoot)) {
    658             updateGeometry();
    659             updateAfterDescendants();
    660             compositor().updateRootLayerPosition();
    661             auto* stackingContext = m_owningLayer.enclosingStackingContext();
    662             if (!compositor().compositingLayersNeedRebuild() && stackingContext && (stackingContext != &m_owningLayer))
    663                 compositor().updateCompositingDescendantGeometry(*stackingContext, *stackingContext);
    664         }
    665     }
    666    
    667     if (flags.contains(UpdateAfterLayoutFlags::NeedsFullRepaint) && canIssueSetNeedsDisplay())
     647    // This is the main trigger for layout changing layer geometry, but we have to do the work again in updateBackingAndHierarchy()
     648    // when we know the final compositing hierarchy. We can't just set dirty bits from RenderLayer::setSize() because that doesn't
     649    // take overflow into account.
     650    if (updateCompositedBounds()) {
     651        m_owningLayer.setNeedsCompositingGeometryUpdate();
     652        // This layer's geometry affects those of its children.
     653        m_owningLayer.setChildrenNeedCompositingGeometryUpdate();
     654    }
     655   
     656    if (needsFullRepaint && canIssueSetNeedsDisplay())
    668657        setContentsNeedDisplay();
    669658}
    670659
    671 bool RenderLayerBacking::updateConfiguration()
    672 {
    673     m_owningLayer.updateDescendantDependentFlags();
    674     m_owningLayer.updateZOrderLists();
    675 
    676     bool layerConfigChanged = false;
    677     setBackgroundLayerPaintsFixedRootBackground(compositor().needsFixedRootBackgroundLayer(m_owningLayer));
    678    
    679     // The background layer is currently only used for fixed root backgrounds.
    680     if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground || m_requiresBackgroundLayer))
    681         layerConfigChanged = true;
    682 
    683     if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
    684         layerConfigChanged = true;
    685    
    686     bool needsDescendantsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
    687 
    688     if (!renderer().view().needsLayout()) {
    689         bool usesCompositedScrolling = m_owningLayer.hasTouchScrollableOverflow();
    690 
    691         // Our scrolling layer will clip.
    692         if (usesCompositedScrolling)
    693             needsDescendantsClippingLayer = false;
    694 
    695         if (updateScrollingLayers(usesCompositedScrolling))
    696             layerConfigChanged = true;
    697 
    698         if (updateDescendantClippingLayer(needsDescendantsClippingLayer))
    699             layerConfigChanged = true;
    700     }
    701 
    702     if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
    703         layerConfigChanged = true;
    704 
    705     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
    706         layerConfigChanged = true;
    707 
    708     if (layerConfigChanged)
    709         updateInternalHierarchy();
    710 
    711     if (auto* flatteningLayer = tileCacheFlatteningLayer()) {
    712         if (layerConfigChanged || flatteningLayer->parent() != m_graphicsLayer.get())
    713             m_graphicsLayer->addChild(*flatteningLayer);
    714     }
    715 
     660// This can only update things that don't require up-to-date layout.
     661void RenderLayerBacking::updateConfigurationAfterStyleChange()
     662{
    716663    updateMaskingLayer(renderer().hasMask(), renderer().hasClipPath());
    717 
    718     updateChildClippingStrategy(needsDescendantsClippingLayer);
    719664
    720665    if (m_owningLayer.hasReflection()) {
     
    726671        m_graphicsLayer->setReplicatedByLayer(nullptr);
    727672
     673    // FIXME: do we care if opacity is animating?
     674    auto& style = renderer().style();
     675    updateOpacity(style);
     676    updateFilters(style);
     677
     678#if ENABLE(FILTERS_LEVEL_2)
     679    updateBackdropFilters(style);
     680#endif
     681#if ENABLE(CSS_COMPOSITING)
     682    updateBlendMode(style);
     683#endif
     684    updateCustomAppearance(style);
     685}
     686
     687bool RenderLayerBacking::updateConfiguration()
     688{
     689    ASSERT(!m_owningLayer.normalFlowListDirty());
     690    ASSERT(!m_owningLayer.zOrderListsDirty());
     691    ASSERT(!renderer().view().needsLayout());
     692
     693    bool layerConfigChanged = false;
     694
     695    setBackgroundLayerPaintsFixedRootBackground(compositor().needsFixedRootBackgroundLayer(m_owningLayer));
     696
     697    if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground || m_requiresBackgroundLayer))
     698        layerConfigChanged = true;
     699
     700    if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
     701        layerConfigChanged = true;
     702   
     703    // This requires descendants to have been updated.
     704    bool needsDescendantsClippingLayer = compositor().clipsCompositingDescendants(m_owningLayer);
     705    bool usesCompositedScrolling = m_owningLayer.hasTouchScrollableOverflow();
     706
     707    // Our scrolling layer will clip.
     708    if (usesCompositedScrolling)
     709        needsDescendantsClippingLayer = false;
     710
     711    if (updateScrollingLayers(usesCompositedScrolling))
     712        layerConfigChanged = true;
     713
     714    if (updateDescendantClippingLayer(needsDescendantsClippingLayer))
     715        layerConfigChanged = true;
     716
     717    // clippedByAncestor() does a tree walk.
     718    if (updateAncestorClippingLayer(compositor().clippedByAncestor(m_owningLayer)))
     719        layerConfigChanged = true;
     720
     721    // Requires layout.
     722    if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
     723        layerConfigChanged = true;
     724
     725    if (layerConfigChanged)
     726        updateInternalHierarchy();
     727
     728    if (auto* flatteningLayer = tileCacheFlatteningLayer()) {
     729        if (layerConfigChanged || flatteningLayer->parent() != m_graphicsLayer.get())
     730            m_graphicsLayer->addChild(*flatteningLayer);
     731    }
     732
     733    updateMaskingLayer(renderer().hasMask(), renderer().hasClipPath());
     734
     735    updateChildClippingStrategy(needsDescendantsClippingLayer);
     736
     737    if (m_owningLayer.hasReflection()) {
     738        if (m_owningLayer.reflectionLayer()->backing()) {
     739            auto* reflectionLayer = m_owningLayer.reflectionLayer()->backing()->graphicsLayer();
     740            m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
     741        }
     742    } else
     743        m_graphicsLayer->setReplicatedByLayer(nullptr);
     744
    728745    PaintedContentsInfo contentsInfo(*this);
    729746
     747    // Requires layout.
    730748    if (!m_owningLayer.isRenderViewLayer()) {
    731749        bool didUpdateContentsRect = false;
     
    734752        updateRootLayerConfiguration();
    735753   
     754    // Requires layout.
    736755    if (contentsInfo.isDirectlyCompositedImage())
    737756        updateImageContents(contentsInfo);
     
    753772        auto* mediaElement = downcast<HTMLMediaElement>(renderer().element());
    754773        m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer(), GraphicsLayer::ContentsLayerPurpose::Media);
     774        // Requires layout.
    755775        resetContentsRect();
    756776    }
     
    761781        if (auto* context = canvas->renderingContext())
    762782            m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer(), GraphicsLayer::ContentsLayerPurpose::Canvas);
     783
    763784        layerConfigChanged = true;
    764785    }
    765786#endif
    766     if (is<RenderWidget>(renderer()))
    767         layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(&downcast<RenderWidget>(renderer()));
     787    if (is<RenderWidget>(renderer()) && RenderLayerCompositor::parentFrameContentLayers(&downcast<RenderWidget>(renderer()))) {
     788        m_owningLayer.setNeedsCompositingGeometryUpdate();
     789        layerConfigChanged = true;
     790    }
    768791
    769792    return layerConfigChanged;
     
    895918}
    896919
     920// FIXME: See if we need this now that updateGeometry() is always called in post-order traversal.
    897921LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const
    898922{
     
    945969void RenderLayerBacking::updateGeometry()
    946970{
    947     // If we haven't built z-order lists yet, wait until later.
    948     if (m_owningLayer.isStackingContext() && m_owningLayer.m_zOrderListsDirty)
    949         return;
     971    ASSERT(!m_owningLayer.normalFlowListDirty());
     972    ASSERT(!m_owningLayer.zOrderListsDirty());
     973    ASSERT(!m_owningLayer.descendantDependentFlagsAreDirty());
     974    ASSERT(!renderer().view().needsLayout());
    950975
    951976    const RenderStyle& style = renderer().style();
     
    9791004    updateBlendMode(style);
    9801005#endif
    981     m_owningLayer.updateDescendantDependentFlags();
    9821006
    9831007    // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
     
    10201044    }
    10211045
    1022     // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordidate system which is not necessarily
     1046    // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordinate system which is not necessarily
    10231047    // the same as the ancestor graphics layer.
    10241048    OffsetFromRenderer primaryGraphicsLayerOffsetFromRenderer;
     
    14421466void RenderLayerBacking::setRequiresBackgroundLayer(bool requiresBackgroundLayer)
    14431467{
     1468    if (requiresBackgroundLayer == m_requiresBackgroundLayer)
     1469        return;
     1470
    14441471    m_requiresBackgroundLayer = requiresBackgroundLayer;
     1472    m_owningLayer.setNeedsCompositingConfigurationUpdate();
    14451473}
    14461474
     
    16551683            layerChanged = true;
    16561684            m_graphicsLayer->setMaskLayer(m_maskLayer.copyRef());
     1685            // We need a geometry update to size the new mask layer.
     1686            m_owningLayer.setNeedsCompositingGeometryUpdate();
    16571687        }
    16581688    } else if (m_maskLayer) {
     
    19862016bool RenderLayerBacking::paintsContent(RenderLayer::PaintedContentRequest& request) const
    19872017{
     2018    m_owningLayer.updateDescendantDependentFlags();
     2019
    19882020    bool paintsContent = false;
    19892021
     
    22172249
    22182250    if ((changeType == BackgroundImageChanged) && canDirectlyCompositeBackgroundBackgroundImage(renderer().style()))
    2219         updateGeometry();
    2220 
    2221     if ((changeType == MaskImageChanged) && m_maskLayer) {
    2222         // The composited layer bounds relies on box->maskClipRect(), which changes
    2223         // when the mask image becomes available.
    2224         updateAfterLayout(UpdateAfterLayoutFlags::IsUpdateRoot);
    2225     }
     2251        m_owningLayer.setNeedsCompositingConfigurationUpdate();
     2252
     2253    if ((changeType == MaskImageChanged) && m_maskLayer)
     2254        m_owningLayer.setNeedsCompositingConfigurationUpdate();
    22262255
    22272256#if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
     
    23942423    ASSERT(!paintsIntoCompositedAncestor());
    23952424
     2425    // Use the repaint as a trigger to re-evaluate direct compositing (which is never used on the root layer).
     2426    if (!m_owningLayer.isRenderViewLayer())
     2427        m_owningLayer.setNeedsCompositingConfigurationUpdate();
     2428
    23962429    auto& frameView = renderer().view().frameView();
    23972430    if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
     
    24272460{
    24282461    ASSERT(!paintsIntoCompositedAncestor());
     2462   
     2463    // Use the repaint as a trigger to re-evaluate direct compositing (which is never used on the root layer).
     2464    if (!m_owningLayer.isRenderViewLayer())
     2465        m_owningLayer.setNeedsCompositingConfigurationUpdate();
    24292466
    24302467    FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
     
    27722809#endif
    27732810
     2811    if (didAnimate)
     2812        m_owningLayer.setNeedsPostLayoutCompositingUpdate();
     2813
    27742814    return didAnimate;
    27752815}
     
    27882828{
    27892829    m_graphicsLayer->removeAnimation(animationName);
     2830    m_owningLayer.setNeedsPostLayoutCompositingUpdate();
    27902831}
    27912832
     
    28552896#endif
    28562897
     2898    if (didAnimate)
     2899        m_owningLayer.setNeedsPostLayoutCompositingUpdate();
     2900
    28572901    return didAnimate;
    28582902}
     
    28682912{
    28692913    AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
    2870     if (animatedProperty != AnimatedPropertyInvalid)
     2914    if (animatedProperty != AnimatedPropertyInvalid) {
    28712915        m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
     2916        m_owningLayer.setNeedsPostLayoutCompositingUpdate();
     2917    }
    28722918}
    28732919
     
    29052951}
    29062952
    2907 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
    2908 {
     2953bool RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
     2954{
     2955    if (bounds == m_compositedBounds)
     2956        return false;
     2957
    29092958    m_compositedBounds = bounds;
     2959    return true;
    29102960}
    29112961
  • trunk/Source/WebCore/rendering/RenderLayerBacking.h

    r237266 r238090  
    6666    RenderLayer& owningLayer() const { return m_owningLayer; }
    6767
    68     enum class UpdateAfterLayoutFlags {
    69         NeedsFullRepaint    = 1 << 0,
    70         IsUpdateRoot        = 1 << 1
    71     };
    72     void updateAfterLayout(OptionSet<UpdateAfterLayoutFlags>);
    73    
     68    void updateConfigurationAfterStyleChange();
     69
    7470    // Returns true if layer configuration changed.
    7571    bool updateConfiguration();
     
    8379    // Update contents and clipping structure.
    8480    void updateDrawsContent();
     81   
     82    void updateAfterLayout(bool needsFullRepaint);
    8583   
    8684    GraphicsLayer* graphicsLayer() const { return m_graphicsLayer.get(); }
     
    178176
    179177    LayoutRect compositedBounds() const;
    180     void setCompositedBounds(const LayoutRect&);
    181     void updateCompositedBounds();
     178    // Returns true if changed.
     179    bool setCompositedBounds(const LayoutRect&);
     180    // Returns true if changed.
     181    bool updateCompositedBounds();
    182182   
    183183    void updateAfterWidgetResize();
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r238070 r238090  
    221221    CompositingState(RenderLayer* compAncestor, bool testOverlap = true)
    222222        : compositingAncestor(compAncestor)
    223         , subtreeIsCompositing(false)
    224223        , testingOverlap(testOverlap)
    225         , ancestorHasTransformAnimation(false)
    226 #if ENABLE(CSS_COMPOSITING)
    227         , hasNotIsolatedCompositedBlendingDescendants(false)
    228 #endif
    229 #if ENABLE(TREE_DEBUGGING)
    230         , depth(0)
    231 #endif
    232224    {
    233225    }
     
    237229        , subtreeIsCompositing(other.subtreeIsCompositing)
    238230        , testingOverlap(other.testingOverlap)
     231        , fullPaintOrderTraversalRequired(other.fullPaintOrderTraversalRequired)
     232        , descendantsRequireCompositingUpdate(other.descendantsRequireCompositingUpdate)
    239233        , ancestorHasTransformAnimation(other.ancestorHasTransformAnimation)
    240234#if ENABLE(CSS_COMPOSITING)
     
    248242   
    249243    RenderLayer* compositingAncestor;
    250     bool subtreeIsCompositing;
    251     bool testingOverlap;
    252     bool ancestorHasTransformAnimation;
     244    bool subtreeIsCompositing { false };
     245    bool testingOverlap { true };
     246    bool fullPaintOrderTraversalRequired { false };
     247    bool descendantsRequireCompositingUpdate { false };
     248    bool ancestorHasTransformAnimation { false };
    253249#if ENABLE(CSS_COMPOSITING)
    254     bool hasNotIsolatedCompositedBlendingDescendants;
     250    bool hasNotIsolatedCompositedBlendingDescendants { false };
    255251#endif
    256252#if ENABLE(TREE_DEBUGGING)
    257     int depth;
     253    int depth { 0 };
    258254#endif
    259255};
     
    300296        } else
    301297            destroyRootLayer();
     298       
     299       
     300        m_renderView.layer()->setNeedsPostLayoutCompositingUpdate();
    302301    }
    303302}
     
    326325   
    327326    if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showDebugBorders != m_showDebugBorders || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode) {
    328         setCompositingLayersNeedRebuild();
    329         m_layerNeedsCompositingUpdate = true;
     327        if (auto* rootLayer = m_renderView.layer()) {
     328            rootLayer->setNeedsCompositingConfigurationUpdate();
     329            rootLayer->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
     330        }
    330331    }
    331332
     
    350351   
    351352    if (updateCompositingPolicy())
    352         setCompositingLayersNeedRebuild();
     353        rootRenderLayer().setDescendantsNeedCompositingRequirementsTraversal();
    353354}
    354355
     
    360361        return;
    361362
    362     bool forceCompositingMode = m_hasAcceleratedCompositing && m_renderView.settings().forceCompositingMode() && requiresCompositingForScrollableFrame();
     363    RequiresCompositingData queryData;
     364    bool forceCompositingMode = m_hasAcceleratedCompositing && m_renderView.settings().forceCompositingMode() && requiresCompositingForScrollableFrame(queryData);
    363365    if (forceCompositingMode != m_forceCompositingMode) {
    364366        m_forceCompositingMode = forceCompositingMode;
    365         setCompositingLayersNeedRebuild();
     367        rootRenderLayer().setDescendantsNeedCompositingRequirementsTraversal();
    366368    }
    367369}
     
    388390}
    389391
    390 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
    391 {
    392     if (inCompositingMode())
    393         m_compositingLayersNeedRebuild = needRebuild;
    394 }
    395 
    396392void RenderLayerCompositor::willRecalcStyle()
    397393{
    398     m_layerNeedsCompositingUpdate = false;
    399394    cacheAcceleratedCompositingFlags();
    400395}
     
    402397bool RenderLayerCompositor::didRecalcStyleWithNoPendingLayout()
    403398{
    404     if (!m_layerNeedsCompositingUpdate)
    405         return false;
    406    
    407399    return updateCompositingLayers(CompositingUpdateType::AfterStyleChange);
    408400}
     
    652644}
    653645
     646// Returns true on a successful update.
    654647bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
    655648{
    656649    LOG_WITH_STREAM(Compositing, stream << "RenderLayerCompositor " << this << " updateCompositingLayers " << updateType << " root " << updateRoot);
     650
     651#if !LOG_DISABLED
     652    if (compositingLogEnabled())
     653        showPaintOrderTree(m_renderView.layer());
     654#endif
    657655
    658656    if (updateType == CompositingUpdateType::AfterStyleChange || updateType == CompositingUpdateType::AfterLayout)
     
    668666
    669667    // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
     668    // This happens when m_updateCompositingLayersTimer fires before layout is updated.
    670669    if (m_renderView.needsLayout())
    671670        return false;
     
    674673        enableCompositingMode(true);
    675674
    676     if (!m_reevaluateCompositingAfterLayout && !m_compositing)
    677         return false;
    678 
     675    updateRoot = &rootRenderLayer();
     676
     677    if (updateType == CompositingUpdateType::OnScroll || updateType == CompositingUpdateType::OnCompositedScroll) {
     678        // Scrolling can affect overlap. FIXME: avoid for page scrolling.
     679        updateRoot->setDescendantsNeedCompositingRequirementsTraversal();
     680    }
     681
     682    if (!updateRoot->hasDescendantNeedingCompositingRequirementsTraversal() && !m_compositing) {
     683        LOG_WITH_STREAM(Compositing, stream << " no compositing work to do");
     684        return true;
     685    }
     686
     687    if (!updateRoot->needsAnyCompositingTraversal()) {
     688        LOG_WITH_STREAM(Compositing, stream << " updateRoot has no dirty child and doesn't need update");
     689        return true;
     690    }
     691
     692    bool isFullUpdate = true;
    679693    ++m_compositingUpdateCount;
    680694
     
    682696
    683697    SetForScope<bool> postLayoutChange(m_inPostLayoutUpdate, true);
    684    
    685     bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout;
    686     bool needGeometryUpdate = false;
    687     bool needRootLayerConfigurationUpdate = m_rootLayerConfigurationNeedsUpdate;
    688 
    689     switch (updateType) {
    690     case CompositingUpdateType::AfterStyleChange:
    691     case CompositingUpdateType::AfterLayout:
    692     case CompositingUpdateType::OnHitTest:
    693         checkForHierarchyUpdate = true;
    694         break;
    695     case CompositingUpdateType::OnScroll:
    696     case CompositingUpdateType::OnCompositedScroll:
    697         checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
    698         needGeometryUpdate = true;
    699         break;
    700     }
    701 
    702     if (!checkForHierarchyUpdate && !needGeometryUpdate && !needRootLayerConfigurationUpdate)
    703         return false;
    704 
    705     bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
    706     bool isFullUpdate = !updateRoot;
    707 
    708     // Only clear the flag if we're updating the entire hierarchy.
    709     m_compositingLayersNeedRebuild = false;
    710     m_rootLayerConfigurationNeedsUpdate = false;
    711     updateRoot = &rootRenderLayer();
    712 
    713     if (isFullUpdate && updateType == CompositingUpdateType::AfterLayout)
    714         m_reevaluateCompositingAfterLayout = false;
    715 
    716     LOG(Compositing, " checkForHierarchyUpdate %d, needGeometryUpdate %d", checkForHierarchyUpdate, needHierarchyUpdate);
    717698
    718699#if !LOG_DISABLED
     
    722703        startTime = MonotonicTime::now();
    723704    }
    724 #endif
    725 
    726     if (checkForHierarchyUpdate) {
    727         // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
    728         // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
    729         CompositingState compState(updateRoot);
    730         bool layersChanged = false;
    731         bool saw3DTransform = false;
    732         OverlapMap overlapTestRequestMap;
    733         computeCompositingRequirements(nullptr, *updateRoot, overlapTestRequestMap, compState, layersChanged, saw3DTransform);
    734         needHierarchyUpdate |= layersChanged;
    735     }
    736 
    737 #if !LOG_DISABLED
    738     if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
     705
     706    if (compositingLogEnabled()) {
    739707        m_obligateCompositedLayerCount = 0;
    740708        m_secondaryCompositedLayerCount = 0;
     
    748716#endif
    749717
    750     if (needHierarchyUpdate) {
    751         // Update the hierarchy of the compositing layers.
     718    // FIXME: optimize root-only update.
     719    if (updateRoot->hasDescendantNeedingCompositingRequirementsTraversal() || updateRoot->needsCompositingRequirementsTraversal()) {
     720        CompositingState compositingState(updateRoot);
     721        OverlapMap overlapMap;
     722
     723        bool descendantHas3DTransform = false;
     724        computeCompositingRequirements(nullptr, rootRenderLayer(), overlapMap, compositingState, descendantHas3DTransform);
     725    }
     726
     727    LOG(Compositing, "\nRenderLayerCompositor::updateCompositingLayers - mid");
     728#if !LOG_DISABLED
     729    if (compositingLogEnabled())
     730        showPaintOrderTree(m_renderView.layer());
     731#endif
     732
     733    if (updateRoot->hasDescendantNeedingUpdateBackingOrHierarchyTraversal() || updateRoot->needsUpdateBackingOrHierarchyTraversal()) {
    752734        Vector<Ref<GraphicsLayer>> childList;
    753         rebuildCompositingLayerTree(*updateRoot, childList, 0);
     735        updateBackingAndHierarchy(*updateRoot, childList);
    754736
    755737        // Host the document layer in the RenderView's root layer.
     
    763745                m_rootContentLayer->setChildren(WTFMove(childList));
    764746        }
    765        
     747   
    766748        reattachSubframeScrollLayers();
    767     } else if (needGeometryUpdate) {
    768         // We just need to do a geometry update. This is only used for position:fixed scrolling;
    769         // most of the time, geometry is updated via RenderLayer::styleChanged().
    770         updateLayerTreeGeometry(*updateRoot, 0);
    771         ASSERT(!isFullUpdate || !m_subframeScrollLayersNeedReattach);
    772     } else if (needRootLayerConfigurationUpdate)
    773         m_renderView.layer()->backing()->updateConfiguration();
    774    
     749    }
     750
    775751#if !LOG_DISABLED
    776     if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
     752    if (compositingLogEnabled()) {
    777753        MonotonicTime endTime = MonotonicTime::now();
    778754        LOG(Compositing, "Total layers   primary   secondary   obligatory backing (KB)   secondary backing(KB)   total backing (KB)  update time (ms)\n");
     
    783759    }
    784760#endif
    785     ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
    786 
    787     if (!hasAcceleratedCompositing())
     761
     762    // FIXME: Only do if dirty.
     763    updateRootLayerPosition();
     764
     765#if !LOG_DISABLED
     766    if (compositingLogEnabled()) {
     767        LOG(Compositing, "RenderLayerCompositor::updateCompositingLayers - post");
     768        showPaintOrderTree(m_renderView.layer());
     769        LOG(Compositing, "RenderLayerCompositor::updateCompositingLayers - GraphicsLayers post");
     770        showGraphicsLayerTree(m_rootContentLayer.get());
     771    }
     772#endif
     773
     774    InspectorInstrumentation::layerTreeDidChange(&page());
     775
     776    return true;
     777}
     778
     779void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, bool& descendantHas3DTransform)
     780{
     781    if (!layer.hasDescendantNeedingCompositingRequirementsTraversal() && !layer.needsCompositingRequirementsTraversal() && !compositingState.fullPaintOrderTraversalRequired && !compositingState.descendantsRequireCompositingUpdate) {
     782        traverseUnchangedSubtree(ancestorLayer, layer, overlapMap, compositingState, descendantHas3DTransform);
     783        return;
     784    }
     785
     786    LOG(Compositing, "%*p computeCompositingRequirements", 12 + compositingState.depth * 2, &layer);
     787
     788    // FIXME: maybe we can avoid updating all remaining layers in paint order.
     789    compositingState.fullPaintOrderTraversalRequired |= layer.needsCompositingRequirementsTraversal();
     790    compositingState.descendantsRequireCompositingUpdate |= layer.descendantsNeedCompositingRequirementsTraversal();
     791
     792    layer.updateDescendantDependentFlags();
     793    layer.updateLayerListsIfNeeded();
     794
     795    layer.setHasCompositingDescendant(false);
     796
     797    // We updated compositing for direct reasons in layerStyleChanged(). Here, check for compositing that can only be evaluated after layout.
     798    RequiresCompositingData queryData;
     799    bool willBeComposited = layer.isComposited();
     800    if (layer.needsPostLayoutCompositingUpdate() || compositingState.fullPaintOrderTraversalRequired || compositingState.descendantsRequireCompositingUpdate) {
     801        layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::None);
     802        willBeComposited = needsToBeComposited(layer, queryData);
     803    }
     804
     805    compositingState.fullPaintOrderTraversalRequired |= layer.subsequentLayersNeedCompositingRequirementsTraversal();
     806
     807    OverlapExtent layerExtent;
     808    // Use the fact that we're composited as a hint to check for an animating transform.
     809    // FIXME: Maybe needsToBeComposited() should return a bitmask of reasons, to avoid the need to recompute things.
     810    if (willBeComposited && !layer.isRenderViewLayer())
     811        layerExtent.hasTransformAnimation = isRunningTransformAnimation(layer.renderer());
     812
     813    bool respectTransforms = !layerExtent.hasTransformAnimation;
     814    overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer, respectTransforms);
     815
     816    RenderLayer::IndirectCompositingReason compositingReason = compositingState.subtreeIsCompositing ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None;
     817
     818    // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
     819    if (!willBeComposited && !overlapMap.isEmpty() && compositingState.testingOverlap) {
     820        computeExtent(overlapMap, layer, layerExtent);
     821        // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
     822        compositingReason = overlapMap.overlapsLayers(layerExtent.bounds) ? RenderLayer::IndirectCompositingReason::Overlap : RenderLayer::IndirectCompositingReason::None;
     823    }
     824
     825#if ENABLE(VIDEO)
     826    // Video is special. It's the only RenderLayer type that can both have
     827    // RenderLayer children and whose children can't use its backing to render
     828    // into. These children (the controls) always need to be promoted into their
     829    // own layers to draw on top of the accelerated video.
     830    if (compositingState.compositingAncestor && compositingState.compositingAncestor->renderer().isVideo())
     831        compositingReason = RenderLayer::IndirectCompositingReason::Overlap;
     832#endif
     833
     834    if (compositingReason != RenderLayer::IndirectCompositingReason::None)
     835        layer.setIndirectCompositingReason(compositingReason);
     836
     837    // Check if the computed indirect reason will force the layer to become composited.
     838    if (!willBeComposited && layer.mustCompositeForIndirectReasons() && canBeComposited(layer))
     839        willBeComposited = true;
     840
     841    // The children of this layer don't need to composite, unless there is
     842    // a compositing layer among them, so start by inheriting the compositing
     843    // ancestor with subtreeIsCompositing set to false.
     844    CompositingState childState(compositingState);
     845    childState.subtreeIsCompositing = false;
     846#if ENABLE(CSS_COMPOSITING)
     847    childState.hasNotIsolatedCompositedBlendingDescendants = false;
     848#endif
     849
     850    if (willBeComposited) {
     851        // Tell the parent it has compositing descendants.
     852        compositingState.subtreeIsCompositing = true;
     853        // This layer now acts as the ancestor for kids.
     854        childState.compositingAncestor = &layer;
     855
     856        overlapMap.pushCompositingContainer();
     857        // This layer is going to be composited, so children can safely ignore the fact that there's an
     858        // animation running behind this layer, meaning they can rely on the overlap map testing again.
     859        childState.testingOverlap = true;
     860
     861        computeExtent(overlapMap, layer, layerExtent);
     862        childState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;
     863        // Too hard to compute animated bounds if both us and some ancestor is animating transform.
     864        layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
     865    }
     866
     867#if !ASSERT_DISABLED
     868    LayerListMutationDetector mutationChecker(layer);
     869#endif
     870
     871    bool anyDescendantHas3DTransform = false;
     872
     873    for (auto* childLayer : layer.negativeZOrderLayers()) {
     874        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
     875
     876        // If we have to make a layer for this child, make one now so we can have a contents layer
     877        // (since we need to ensure that the -ve z-order child renders underneath our contents).
     878        if (!willBeComposited && childState.subtreeIsCompositing) {
     879            // make layer compositing
     880            layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer);
     881            childState.compositingAncestor = &layer;
     882            overlapMap.pushCompositingContainer();
     883            // This layer is going to be composited, so children can safely ignore the fact that there's an
     884            // animation running behind this layer, meaning they can rely on the overlap map testing again
     885            childState.testingOverlap = true;
     886            willBeComposited = true;
     887        }
     888    }
     889   
     890    for (auto* childLayer : layer.normalFlowLayers())
     891        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
     892
     893    for (auto* childLayer : layer.positiveZOrderLayers())
     894        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
     895
     896    // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
     897    if (layer.isRenderViewLayer()) {
     898        if (inCompositingMode() && m_hasAcceleratedCompositing)
     899            willBeComposited = true;
     900    }
     901   
     902    // All layers (even ones that aren't being composited) need to get added to
     903    // the overlap map. Layers that do not composite will draw into their
     904    // compositing ancestor's backing, and so are still considered for overlap.
     905    // FIXME: When layerExtent has taken animation bounds into account, we also know that the bounds
     906    // include descendants, so we don't need to add them all to the overlap map.
     907    if (childState.compositingAncestor && !childState.compositingAncestor->isRenderViewLayer())
     908        addToOverlapMap(overlapMap, layer, layerExtent);
     909
     910#if ENABLE(CSS_COMPOSITING)
     911    layer.setHasNotIsolatedCompositedBlendingDescendants(childState.hasNotIsolatedCompositedBlendingDescendants);
     912    ASSERT(!layer.hasNotIsolatedCompositedBlendingDescendants() || layer.hasNotIsolatedBlendingDescendants());
     913#endif
     914    // Now check for reasons to become composited that depend on the state of descendant layers.
     915    RenderLayer::IndirectCompositingReason indirectCompositingReason;
     916    if (!willBeComposited && canBeComposited(layer)
     917        && requiresCompositingForIndirectReason(layer.renderer(), childState.subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
     918        layer.setIndirectCompositingReason(indirectCompositingReason);
     919        childState.compositingAncestor = &layer;
     920        overlapMap.pushCompositingContainer();
     921        addToOverlapMapRecursive(overlapMap, layer);
     922        willBeComposited = true;
     923    }
     924   
     925    if (layer.reflectionLayer()) {
     926        // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
     927        layer.reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None);
     928    }
     929
     930    // Subsequent layers in the parent stacking context also need to composite.
     931    compositingState.subtreeIsCompositing |= childState.subtreeIsCompositing;
     932    compositingState.fullPaintOrderTraversalRequired |= childState.fullPaintOrderTraversalRequired;
     933
     934    // Set the flag to say that this layer has compositing children.
     935    layer.setHasCompositingDescendant(childState.subtreeIsCompositing);
     936
     937    // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that again.
     938    bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer);
     939
     940    // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
     941    // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
     942    // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
     943    if ((!childState.testingOverlap && !isCompositedClippingLayer) || layerExtent.knownToBeHaveExtentUncertainty())
     944        compositingState.testingOverlap = false;
     945   
     946    if (isCompositedClippingLayer) {
     947        if (!willBeComposited) {
     948            childState.compositingAncestor = &layer;
     949            overlapMap.pushCompositingContainer();
     950            addToOverlapMapRecursive(overlapMap, layer);
     951            willBeComposited = true;
     952        }
     953    }
     954
     955#if ENABLE(CSS_COMPOSITING)
     956    if ((willBeComposited && layer.hasBlendMode())
     957        || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
     958        compositingState.hasNotIsolatedCompositedBlendingDescendants = true;
     959#endif
     960
     961    if (childState.compositingAncestor == &layer && !layer.isRenderViewLayer())
     962        overlapMap.popCompositingContainer();
     963
     964    // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
     965    // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
     966    // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
     967    RequiresCompositingData rootLayerQueryData;
     968    if (layer.isRenderViewLayer() && !childState.subtreeIsCompositing && !requiresCompositingLayer(layer, rootLayerQueryData) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
     969        // Don't drop out of compositing on iOS, because we may flash. See <rdar://problem/8348337>.
     970#if !PLATFORM(IOS_FAMILY)
    788971        enableCompositingMode(false);
    789 
    790     // Inform the inspector that the layer tree has changed.
    791     InspectorInstrumentation::layerTreeDidChange(&page());
    792 
    793     return true;
     972        willBeComposited = false;
     973#endif
     974    }
     975   
     976    ASSERT(willBeComposited == needsToBeComposited(layer, queryData));
     977
     978    // Create or destroy backing here. However, we can't update geometry because layers above us may become composited
     979    // during post-order traversal (e.g. for clipping).
     980    if (updateBacking(layer, queryData, CompositingChangeRepaintNow, willBeComposited ? BackingRequired::Yes : BackingRequired::No)) {
     981        layer.setNeedsCompositingLayerConnection();
     982        // Child layers need to get a geometry update to recompute their position. FIXME: Ideally we'd only dirty direct children.
     983        layer.setDescendantsNeedUpdateBackingAndHierarchyTraversal();
     984        // The composited bounds of enclosing layers depends on which descendants are composited, so they need a geometry update.
     985        layer.setNeedsCompositingGeometryUpdateOnAncestors();
     986    }
     987
     988    if (layer.reflectionLayer() && updateLayerCompositingState(*layer.reflectionLayer(), queryData, CompositingChangeRepaintNow))
     989        layer.setNeedsCompositingLayerConnection();
     990
     991    descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform();
     992   
     993    // FIXME: clarify needsCompositingPaintOrderChildrenUpdate. If a composited layer gets a new ancestor, it needs geometry computations.
     994    if (layer.needsCompositingPaintOrderChildrenUpdate()) {
     995        layer.setChildrenNeedCompositingGeometryUpdate();
     996        layer.setNeedsCompositingLayerConnection();
     997    }
     998
     999    LOG(Compositing, "%*p computeCompositingRequirements - willBeComposited %d", 12 + compositingState.depth * 2, &layer, willBeComposited);
     1000
     1001    layer.clearCompositingRequirementsTraversalState();
     1002   
     1003    overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
     1004}
     1005
     1006// We have to traverse unchanged layers to fill in the overlap map.
     1007void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, bool& descendantHas3DTransform)
     1008{
     1009    ASSERT(!compositingState.fullPaintOrderTraversalRequired);
     1010    ASSERT(!layer.hasDescendantNeedingCompositingRequirementsTraversal());
     1011    ASSERT(!layer.needsCompositingRequirementsTraversal());
     1012
     1013    LOG(Compositing, "%*p traverseUnchangedSubtree", 12 + compositingState.depth * 2, &layer);
     1014
     1015    layer.updateDescendantDependentFlags();
     1016    layer.updateLayerListsIfNeeded();
     1017
     1018    bool layerIsComposited = layer.isComposited();
     1019
     1020    OverlapExtent layerExtent;
     1021    if (layerIsComposited && !layer.isRenderViewLayer())
     1022        layerExtent.hasTransformAnimation = isRunningTransformAnimation(layer.renderer());
     1023
     1024    bool respectTransforms = !layerExtent.hasTransformAnimation;
     1025    overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer, respectTransforms);
     1026
     1027    // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
     1028    if (!layerIsComposited && !overlapMap.isEmpty() && compositingState.testingOverlap)
     1029        computeExtent(overlapMap, layer, layerExtent);
     1030
     1031    CompositingState childState(compositingState);
     1032    childState.subtreeIsCompositing = false;
     1033#if ENABLE(CSS_COMPOSITING)
     1034    childState.hasNotIsolatedCompositedBlendingDescendants = false;
     1035#endif
     1036
     1037    if (layerIsComposited) {
     1038        // Tell the parent it has compositing descendants.
     1039        compositingState.subtreeIsCompositing = true;
     1040        // This layer now acts as the ancestor for kids.
     1041        childState.compositingAncestor = &layer;
     1042
     1043        overlapMap.pushCompositingContainer();
     1044        // This layer is going to be composited, so children can safely ignore the fact that there's an
     1045        // animation running behind this layer, meaning they can rely on the overlap map testing again.
     1046        childState.testingOverlap = true;
     1047
     1048        computeExtent(overlapMap, layer, layerExtent);
     1049        childState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;
     1050        // Too hard to compute animated bounds if both us and some ancestor is animating transform.
     1051        layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
     1052    }
     1053
     1054#if !ASSERT_DISABLED
     1055    LayerListMutationDetector mutationChecker(layer);
     1056#endif
     1057
     1058    bool anyDescendantHas3DTransform = false;
     1059
     1060    for (auto* childLayer : layer.negativeZOrderLayers()) {
     1061        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
     1062        if (childState.subtreeIsCompositing)
     1063            ASSERT(layerIsComposited);
     1064    }
     1065   
     1066    for (auto* childLayer : layer.normalFlowLayers())
     1067        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
     1068
     1069    for (auto* childLayer : layer.positiveZOrderLayers())
     1070        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
     1071
     1072    // All layers (even ones that aren't being composited) need to get added to
     1073    // the overlap map. Layers that do not composite will draw into their
     1074    // compositing ancestor's backing, and so are still considered for overlap.
     1075    // FIXME: When layerExtent has taken animation bounds into account, we also know that the bounds
     1076    // include descendants, so we don't need to add them all to the overlap map.
     1077    if (childState.compositingAncestor && !childState.compositingAncestor->isRenderViewLayer())
     1078        addToOverlapMap(overlapMap, layer, layerExtent);
     1079
     1080    // Subsequent layers in the parent stacking context also need to composite.
     1081    if (childState.subtreeIsCompositing)
     1082        compositingState.subtreeIsCompositing = true;
     1083
     1084    // Set the flag to say that this layer has compositing children.
     1085    ASSERT(layer.hasCompositingDescendant() == childState.subtreeIsCompositing);
     1086
     1087    // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that again.
     1088    bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer);
     1089
     1090    // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
     1091    // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
     1092    // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
     1093    if ((!childState.testingOverlap && !isCompositedClippingLayer) || layerExtent.knownToBeHaveExtentUncertainty())
     1094        compositingState.testingOverlap = false;
     1095   
     1096    if (isCompositedClippingLayer)
     1097        ASSERT(layerIsComposited);
     1098
     1099#if ENABLE(CSS_COMPOSITING)
     1100    if ((layerIsComposited && layer.hasBlendMode())
     1101        || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
     1102        compositingState.hasNotIsolatedCompositedBlendingDescendants = true;
     1103#endif
     1104
     1105    if (childState.compositingAncestor == &layer && !layer.isRenderViewLayer())
     1106        overlapMap.popCompositingContainer();
     1107
     1108    descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform();
     1109
     1110    ASSERT(!layer.needsCompositingRequirementsTraversal());
     1111
     1112    overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
     1113}
     1114
     1115void RenderLayerCompositor::updateBackingAndHierarchy(RenderLayer& layer, Vector<Ref<GraphicsLayer>>& childLayersOfEnclosingLayer, OptionSet<UpdateLevel> updateLevel, int depth)
     1116{
     1117    layer.updateDescendantDependentFlags();
     1118    layer.updateLayerListsIfNeeded();
     1119
     1120    bool layerNeedsUpdate = !updateLevel.isEmpty();
     1121    if (layer.descendantsNeedUpdateBackingAndHierarchyTraversal())
     1122        updateLevel.add(UpdateLevel::AllDescendants);
     1123
     1124    auto* layerBacking = layer.backing();
     1125    if (layerBacking) {
     1126        updateLevel.remove(UpdateLevel::CompositedChildren);
     1127
     1128        // We updated the composited bounds in RenderLayerBacking::updateAfterLayout(), but it may have changed
     1129        // based on which descendants are now composited.
     1130        if (layerBacking->updateCompositedBounds()) {
     1131            layer.setNeedsCompositingGeometryUpdate();
     1132            // Our geometry can affect descendants.
     1133            updateLevel.add(UpdateLevel::CompositedChildren);
     1134        }
     1135       
     1136        if (layerNeedsUpdate || layer.needsCompositingConfigurationUpdate()) {
     1137            if (layerBacking->updateConfiguration()) {
     1138                layerNeedsUpdate = true; // We also need to update geometry.
     1139                layer.setNeedsCompositingLayerConnection();
     1140            }
     1141
     1142            layerBacking->updateDebugIndicators(m_showDebugBorders, m_showRepaintCounter);
     1143        }
     1144       
     1145        if (layerNeedsUpdate || layer.needsCompositingGeometryUpdate())
     1146            layerBacking->updateGeometry();
     1147
     1148        if (auto* reflection = layer.reflectionLayer()) {
     1149            if (auto* reflectionBacking = reflection->backing()) {
     1150                reflectionBacking->updateCompositedBounds();
     1151                reflectionBacking->updateGeometry();
     1152                reflectionBacking->updateAfterDescendants();
     1153            }
     1154        }
     1155
     1156        if (!layer.parent())
     1157            updateRootLayerPosition();
     1158
     1159#if !LOG_DISABLED
     1160        logLayerInfo(layer, "updateBackingAndHierarchy", depth);
     1161#else
     1162        UNUSED_PARAM(depth);
     1163#endif
     1164    }
     1165
     1166    if (layer.childrenNeedCompositingGeometryUpdate())
     1167        updateLevel.add(UpdateLevel::CompositedChildren);
     1168
     1169    // If this layer has backing, then we are collecting its children, otherwise appending
     1170    // to the compositing child list of an enclosing layer.
     1171    Vector<Ref<GraphicsLayer>> layerChildren;
     1172    auto& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
     1173    // FIXME: why the !layerBacking check?
     1174    bool requireDescendantTraversal = !layerBacking || layer.needsCompositingLayerConnection() || layer.hasDescendantNeedingUpdateBackingOrHierarchyTraversal() || !updateLevel.isEmpty();
     1175
     1176#if !ASSERT_DISABLED
     1177    LayerListMutationDetector mutationChecker(layer);
     1178#endif
     1179   
     1180    if (requireDescendantTraversal) {
     1181        for (auto* renderLayer : layer.negativeZOrderLayers())
     1182            updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
     1183
     1184            // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
     1185        if (layer.negativeZOrderLayers().size()) {
     1186            if (layerBacking && layerBacking->foregroundLayer())
     1187                childList.append(*layerBacking->foregroundLayer());
     1188        }
     1189
     1190        for (auto* renderLayer : layer.normalFlowLayers())
     1191            updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
     1192       
     1193        for (auto* renderLayer : layer.positiveZOrderLayers())
     1194            updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
     1195    }
     1196
     1197    if (layerBacking) {
     1198        if (requireDescendantTraversal) {
     1199            bool parented = false;
     1200            if (is<RenderWidget>(layer.renderer()))
     1201                parented = parentFrameContentLayers(&downcast<RenderWidget>(layer.renderer()));
     1202
     1203            if (!parented)
     1204                layerBacking->parentForSublayers()->setChildren(WTFMove(layerChildren));
     1205
     1206            // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
     1207            // Otherwise, the overflow control layers are normal children.
     1208            if (!layerBacking->hasClippingLayer() && !layerBacking->hasScrollingLayer()) {
     1209                if (auto* overflowControlLayer = layerBacking->layerForHorizontalScrollbar())
     1210                    layerBacking->parentForSublayers()->addChild(*overflowControlLayer);
     1211
     1212                if (auto* overflowControlLayer = layerBacking->layerForVerticalScrollbar())
     1213                    layerBacking->parentForSublayers()->addChild(*overflowControlLayer);
     1214
     1215                if (auto* overflowControlLayer = layerBacking->layerForScrollCorner())
     1216                    layerBacking->parentForSublayers()->addChild(*overflowControlLayer);
     1217            }
     1218        }
     1219
     1220        childLayersOfEnclosingLayer.append(*layerBacking->childForSuperlayers());
     1221
     1222        layerBacking->updateAfterDescendants(); // FIXME: validate.
     1223    }
     1224   
     1225    layer.clearUpdateBackingOrHierarchyTraversalState();
    7941226}
    7951227
     
    8131245
    8141246#if !LOG_DISABLED
    815 void RenderLayerCompositor::logLayerInfo(const RenderLayer& layer, int depth)
     1247void RenderLayerCompositor::logLayerInfo(const RenderLayer& layer, const char* phase, int depth)
    8161248{
    8171249    if (!compositingLogEnabled())
     
    8191251
    8201252    auto* backing = layer.backing();
    821     if (requiresCompositingLayer(layer) || layer.isRenderViewLayer()) {
     1253    RequiresCompositingData queryData;
     1254    if (requiresCompositingLayer(layer, queryData) || layer.isRenderViewLayer()) {
    8221255        ++m_obligateCompositedLayerCount;
    8231256        m_obligatoryBackingStoreBytes += backing->backingStoreMemoryEstimate();
     
    8831316    logString.append(layer.name());
    8841317
     1318    logString.appendLiteral(" - ");
     1319    logString.append(phase);
     1320
    8851321    LOG(Compositing, "%s", logString.toString().utf8().data());
    8861322}
    8871323#endif
    8881324
    889 static bool checkIfDescendantClippingContextNeedsUpdate(const RenderLayer& layer, bool isClipping)
    890 {
    891     for (auto* child = layer.firstChild(); child; child = child->nextSibling()) {
    892         auto* backing = child->backing();
    893         if (backing && (isClipping || backing->hasAncestorClippingLayer()))
    894             return true;
    895 
    896         if (checkIfDescendantClippingContextNeedsUpdate(*child, isClipping))
    897             return true;
    898     }
    899     return false;
    900 }
    901 
    902 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
    903 static bool isScrollableOverflow(Overflow overflow)
    904 {
    905     return overflow == Overflow::Scroll || overflow == Overflow::Auto;
    906 }
    907 
    908 static bool styleHasTouchScrolling(const RenderStyle& style)
    909 {
    910     return style.useTouchOverflowScrolling() && (isScrollableOverflow(style.overflowX()) || isScrollableOverflow(style.overflowY()));
    911 }
    912 #endif
    913 
    914 static bool styleChangeRequiresLayerRebuild(const RenderLayer& layer, const RenderStyle& oldStyle, const RenderStyle& newStyle)
    915 {
    916     // Clip can affect ancestor compositing bounds, so we need recompute overlap when it changes on a non-composited layer.
    917     // FIXME: we should avoid doing this for all clip changes.
    918     if (oldStyle.clip() != newStyle.clip() || oldStyle.hasClip() != newStyle.hasClip())
    919         return true;
    920 
    921     // FIXME: need to check everything that we consult to avoid backing store here: webkit.org/b/138383
    922     if (!oldStyle.opacity() != !newStyle.opacity()) {
    923         auto* repaintContainer = layer.renderer().containerForRepaint();
    924         if (auto* ancestorBacking = repaintContainer ? repaintContainer->layer()->backing() : nullptr) {
    925             if (static_cast<bool>(newStyle.opacity()) != ancestorBacking->graphicsLayer()->drawsContent())
    926                 return true;
    927         }
    928     }
    929 
    930     // When overflow changes, composited layers may need to update their ancestorClipping layers.
    931     if (!layer.isComposited() && (oldStyle.overflowX() != newStyle.overflowX() || oldStyle.overflowY() != newStyle.overflowY()) && layer.stackingContext()->hasCompositingDescendant())
    932         return true;
    933    
    934 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
    935     if (styleHasTouchScrolling(oldStyle) != styleHasTouchScrolling(newStyle))
    936         return true;
    937 #endif
    938 
    939     // Compositing layers keep track of whether they are clipped by any of the ancestors.
    940     // When the current layer's clipping behaviour changes, we need to propagate it to the descendants.
    941     bool wasClipping = oldStyle.hasClip() || oldStyle.overflowX() != Overflow::Visible || oldStyle.overflowY() != Overflow::Visible;
    942     bool isClipping = newStyle.hasClip() || newStyle.overflowX() != Overflow::Visible || newStyle.overflowY() != Overflow::Visible;
    943     if (isClipping != wasClipping) {
    944         if (checkIfDescendantClippingContextNeedsUpdate(layer, isClipping))
    945             return true;
    946     }
    947 
    948     return false;
     1325static bool clippingChanged(const RenderStyle& oldStyle, const RenderStyle& newStyle)
     1326{
     1327    return oldStyle.overflowX() != newStyle.overflowX() || oldStyle.overflowY() != newStyle.overflowY()
     1328        || oldStyle.hasClip() != newStyle.hasClip() || oldStyle.clip() != newStyle.clip();
     1329}
     1330
     1331static bool styleAffectsLayerGeometry(const RenderStyle& style)
     1332{
     1333    return style.hasClip() || style.clipPath() || style.hasBorderRadius();
    9491334}
    9501335
     
    9541339        return;
    9551340
    956     const RenderStyle& newStyle = layer.renderer().style();
    957     if (updateLayerCompositingState(layer) || (oldStyle && styleChangeRequiresLayerRebuild(layer, *oldStyle, newStyle))) {
    958         setCompositingLayersNeedRebuild();
    959         m_layerNeedsCompositingUpdate = true;
    960         return;
    961     }
    962 
    963     if (layer.isComposited()) {
    964         // FIXME: updating geometry here is potentially harmful, because layout is not up-to-date.
    965         layer.backing()->updateGeometry();
    966         layer.backing()->updateAfterDescendants();
    967         m_layerNeedsCompositingUpdate = true;
    968         return;
    969     }
    970 
    971     if (needsCompositingUpdateForStyleChangeOnNonCompositedLayer(layer, oldStyle))
    972         m_layerNeedsCompositingUpdate = true;
     1341    // Create or destroy backing here so that code that runs during layout can reliably use isComposited() (though this
     1342    // is only true for layers composited for direct reasons).
     1343    // Also, it allows us to avoid a tree walk in updateCompositingLayers() when no layer changed its compositing state.
     1344    RequiresCompositingData queryData;
     1345    queryData.layoutUpToDate = LayoutUpToDate::No;
     1346   
     1347    bool layerChanged = updateBacking(layer, queryData, CompositingChangeRepaintNow);
     1348    if (layerChanged) {
     1349        layer.setNeedsCompositingLayerConnection();
     1350        layer.setSubsequentLayersNeedCompositingRequirementsTraversal();
     1351        // Ancestor layers that composited for indirect reasons (things listed in styleChangeMayAffectIndirectCompositingReasons()) need to get updated.
     1352        // This could be optimized by only setting this flag on layers with the relevant styles.
     1353        layer.setNeedsPostLayoutCompositingUpdateOnAncestors();
     1354    }
     1355   
     1356    if (queryData.reevaluateAfterLayout)
     1357        layer.setNeedsPostLayoutCompositingUpdate();
     1358
     1359    if (diff >= StyleDifference::LayoutPositionedMovementOnly && inCompositingMode()) {
     1360        layer.setNeedsPostLayoutCompositingUpdate();
     1361        layer.setNeedsCompositingGeometryUpdate();
     1362    }
     1363
     1364    auto* backing = layer.backing();
     1365    if (!backing)
     1366        return;
     1367
     1368    backing->updateConfigurationAfterStyleChange();
     1369
     1370    const auto& newStyle = layer.renderer().style();
     1371
     1372    if (diff >= StyleDifference::Repaint) {
     1373        // Visibility change may affect geometry of the enclosing composited layer.
     1374        if (oldStyle && oldStyle->visibility() != newStyle.visibility())
     1375            layer.setNeedsCompositingGeometryUpdate();
     1376       
     1377        // We'll get a diff of Repaint when things like clip-path change; these might affect layer or inner-layer geometry.
     1378        if (layer.isComposited() && oldStyle) {
     1379            if (styleAffectsLayerGeometry(*oldStyle) || styleAffectsLayerGeometry(newStyle))
     1380                layer.setNeedsCompositingGeometryUpdate();
     1381        }
     1382    }
     1383
     1384    if (diff == StyleDifference::RecompositeLayer && oldStyle) {
     1385        if (oldStyle->transform() != newStyle.transform()) {
     1386            // FIXME: transform changes really need to trigger layout. See RenderElement::adjustStyleDifference().
     1387            layer.setNeedsPostLayoutCompositingUpdate();
     1388            layer.setNeedsCompositingGeometryUpdate();
     1389        }
     1390    }
     1391
     1392    if (diff >= StyleDifference::Layout) {
     1393        // FIXME: only set flags here if we know we have a composited descendant, but we might not know at this point.
     1394        if (oldStyle && clippingChanged(*oldStyle, newStyle)) {
     1395            if (layer.isStackingContext()) {
     1396                layer.setNeedsPostLayoutCompositingUpdate(); // Layer needs to become composited if it has composited descendants.
     1397                layer.setNeedsCompositingConfigurationUpdate(); // If already composited, layer needs to create/destroy clipping layer.
     1398            } else {
     1399                // Descendant (in containing block order) compositing layers need to re-evaluate their clipping,
     1400                // but they might be siblings in z-order so go up to our stacking context.
     1401                if (auto* stackingContext = layer.stackingContext())
     1402                    stackingContext->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
     1403            }
     1404        }
     1405
     1406        // These properties trigger compositing if some descendant is composited.
     1407        if (oldStyle && styleChangeMayAffectIndirectCompositingReasons(*oldStyle, newStyle))
     1408            layer.setNeedsPostLayoutCompositingUpdate();
     1409
     1410        layer.setNeedsCompositingGeometryUpdate();
     1411    }
    9731412}
    9741413
     
    9881427
    9891428    // We don't have any direct reasons for this style change to affect layer composition. Test if it might affect things indirectly.
    990     if (styleChangeMayAffectIndirectCompositingReasons(layer.renderer(), *oldStyle))
     1429    if (styleChangeMayAffectIndirectCompositingReasons(*oldStyle, newStyle))
    9911430        return true;
    9921431
     
    10061445}
    10071446
     1447// FIXME: remove and never ask questions about reflection layers.
    10081448static RenderLayerModelObject& rendererForCompositingTests(const RenderLayer& layer)
    10091449{
     
    10221462}
    10231463
    1024 bool RenderLayerCompositor::updateBacking(RenderLayer& layer, CompositingChangeRepaint shouldRepaint, BackingRequired backingRequired)
     1464bool RenderLayerCompositor::updateBacking(RenderLayer& layer, RequiresCompositingData& queryData, CompositingChangeRepaint shouldRepaint, BackingRequired backingRequired)
    10251465{
    10261466    bool layerChanged = false;
    1027     RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
    1028 
    10291467    if (backingRequired == BackingRequired::Unknown)
    1030         backingRequired = needsToBeComposited(layer, &viewportConstrainedNotCompositedReason) ? BackingRequired::Yes : BackingRequired::No;
     1468        backingRequired = needsToBeComposited(layer, queryData) ? BackingRequired::Yes : BackingRequired::No;
    10311469    else {
    10321470        // Need to fetch viewportConstrainedNotCompositedReason, but without doing all the work that needsToBeComposited does.
    1033         requiresCompositingForPosition(rendererForCompositingTests(layer), layer, &viewportConstrainedNotCompositedReason);
     1471        requiresCompositingForPosition(rendererForCompositingTests(layer), layer, queryData);
    10341472    }
    10351473
     
    10621500            if (layer.parent())
    10631501                layer.computeRepaintRectsIncludingDescendants();
     1502           
     1503            layer.setNeedsCompositingGeometryUpdate();
     1504            layer.setNeedsCompositingConfigurationUpdate();
     1505            layer.setNeedsCompositingPaintOrderChildrenUpdate();
    10641506
    10651507            layerChanged = true;
     
    11121554    // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
    11131555    if (layer.renderer().isFixedPositioned()) {
    1114         if (layer.viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
    1115             layer.setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
     1556        if (layer.viewportConstrainedNotCompositedReason() != queryData.nonCompositedForPositionReason) {
     1557            layer.setViewportConstrainedNotCompositedReason(queryData.nonCompositedForPositionReason);
    11161558            layerChanged = true;
    11171559        }
     
    11291571}
    11301572
    1131 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer& layer, CompositingChangeRepaint shouldRepaint)
    1132 {
    1133     bool layerChanged = updateBacking(layer, shouldRepaint);
     1573bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer& layer, RequiresCompositingData& queryData, CompositingChangeRepaint shouldRepaint)
     1574{
     1575    bool layerChanged = updateBacking(layer, queryData, shouldRepaint);
    11341576
    11351577    // See if we need content or clipping layers. Methods called here should assume
     
    11781620}
    11791621
     1622// FIXME: remove.
    11801623void RenderLayerCompositor::layerWasAdded(RenderLayer&, RenderLayer&)
    11811624{
    1182     setCompositingLayersNeedRebuild();
    11831625}
    11841626
     
    11891631
    11901632    removeFromScrollCoordinatedLayers(child);
    1191     repaintInCompositedAncestor(child, child.backing()->compositedBounds());
     1633    repaintInCompositedAncestor(child, child.backing()->compositedBounds()); // FIXME: do via dirty bits?
    11921634
    11931635    setCompositingParent(child, nullptr);
    1194     setCompositingLayersNeedRebuild();
     1636    child.setNeedsCompositingLayerConnection();
    11951637}
    11961638
     
    12801722    if (ancestorLayer)
    12811723        overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
    1282 }
    1283 
    1284 //  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
    1285 //  For the z-order children of a compositing layer:
    1286 //      If a child layers has a compositing layer, then all subsequent layers must
    1287 //      be compositing in order to render above that layer.
    1288 //
    1289 //      If a child in the negative z-order list is compositing, then the layer itself
    1290 //      must be compositing so that its contents render over that child.
    1291 //      This implies that its positive z-index children must also be compositing.
    1292 //
    1293 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, bool& layersChanged, bool& descendantHas3DTransform)
    1294 {
    1295     layer.updateDescendantDependentFlags();
    1296     layer.updateLayerListsIfNeeded();
    1297 
    1298     // Clear the flag
    1299     layer.setHasCompositingDescendant(false);
    1300     layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::None);
    1301 
    1302     // Check if the layer needs to be composited for direct reasons (e.g. 3D transform).
    1303     bool willBeComposited = needsToBeComposited(layer);
    1304 
    1305     OverlapExtent layerExtent;
    1306     // Use the fact that we're composited as a hint to check for an animating transform.
    1307     // FIXME: Maybe needsToBeComposited() should return a bitmask of reasons, to avoid the need to recompute things.
    1308     if (willBeComposited && !layer.isRenderViewLayer())
    1309         layerExtent.hasTransformAnimation = isRunningTransformAnimation(layer.renderer());
    1310 
    1311     bool respectTransforms = !layerExtent.hasTransformAnimation;
    1312     overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer, respectTransforms);
    1313 
    1314     RenderLayer::IndirectCompositingReason compositingReason = compositingState.subtreeIsCompositing ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None;
    1315 
    1316     // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
    1317     if (!willBeComposited && !overlapMap.isEmpty() && compositingState.testingOverlap) {
    1318         computeExtent(overlapMap, layer, layerExtent);
    1319         // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
    1320         compositingReason = overlapMap.overlapsLayers(layerExtent.bounds) ? RenderLayer::IndirectCompositingReason::Overlap : RenderLayer::IndirectCompositingReason::None;
    1321     }
    1322 
    1323 #if ENABLE(VIDEO)
    1324     // Video is special. It's the only RenderLayer type that can both have
    1325     // RenderLayer children and whose children can't use its backing to render
    1326     // into. These children (the controls) always need to be promoted into their
    1327     // own layers to draw on top of the accelerated video.
    1328     if (compositingState.compositingAncestor && compositingState.compositingAncestor->renderer().isVideo())
    1329         compositingReason = RenderLayer::IndirectCompositingReason::Overlap;
    1330 #endif
    1331 
    1332     layer.setIndirectCompositingReason(compositingReason);
    1333 
    1334     // Check if the computed indirect reason will force the layer to become composited.
    1335     if (!willBeComposited && layer.mustCompositeForIndirectReasons() && canBeComposited(layer))
    1336         willBeComposited = true;
    1337     ASSERT(willBeComposited == needsToBeComposited(layer));
    1338 
    1339     // The children of this layer don't need to composite, unless there is
    1340     // a compositing layer among them, so start by inheriting the compositing
    1341     // ancestor with subtreeIsCompositing set to false.
    1342     CompositingState childState(compositingState);
    1343     childState.subtreeIsCompositing = false;
    1344 #if ENABLE(CSS_COMPOSITING)
    1345     childState.hasNotIsolatedCompositedBlendingDescendants = false;
    1346 #endif
    1347 
    1348     if (willBeComposited) {
    1349         // Tell the parent it has compositing descendants.
    1350         compositingState.subtreeIsCompositing = true;
    1351         // This layer now acts as the ancestor for kids.
    1352         childState.compositingAncestor = &layer;
    1353 
    1354         overlapMap.pushCompositingContainer();
    1355         // This layer is going to be composited, so children can safely ignore the fact that there's an
    1356         // animation running behind this layer, meaning they can rely on the overlap map testing again.
    1357         childState.testingOverlap = true;
    1358 
    1359         computeExtent(overlapMap, layer, layerExtent);
    1360         childState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;
    1361         // Too hard to compute animated bounds if both us and some ancestor is animating transform.
    1362         layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
    1363     }
    1364 
    1365 #if !ASSERT_DISABLED
    1366     LayerListMutationDetector mutationChecker(layer);
    1367 #endif
    1368 
    1369     bool anyDescendantHas3DTransform = false;
    1370 
    1371     for (auto* renderLayer : layer.negativeZOrderLayers()) {
    1372         computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
    1373 
    1374         // If we have to make a layer for this child, make one now so we can have a contents layer
    1375         // (since we need to ensure that the -ve z-order child renders underneath our contents).
    1376         if (!willBeComposited && childState.subtreeIsCompositing) {
    1377             // make layer compositing
    1378             layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer);
    1379             childState.compositingAncestor = &layer;
    1380             overlapMap.pushCompositingContainer();
    1381             // This layer is going to be composited, so children can safely ignore the fact that there's an
    1382             // animation running behind this layer, meaning they can rely on the overlap map testing again
    1383             childState.testingOverlap = true;
    1384             willBeComposited = true;
    1385         }
    1386     }
    1387    
    1388     for (auto* renderLayer : layer.normalFlowLayers())
    1389         computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
    1390 
    1391     for (auto* renderLayer : layer.positiveZOrderLayers())
    1392         computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
    1393 
    1394     // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
    1395     if (layer.isRenderViewLayer()) {
    1396         if (inCompositingMode() && m_hasAcceleratedCompositing)
    1397             willBeComposited = true;
    1398     }
    1399    
    1400     ASSERT(willBeComposited == needsToBeComposited(layer));
    1401 
    1402     // All layers (even ones that aren't being composited) need to get added to
    1403     // the overlap map. Layers that do not composite will draw into their
    1404     // compositing ancestor's backing, and so are still considered for overlap.
    1405     // FIXME: When layerExtent has taken animation bounds into account, we also know that the bounds
    1406     // include descendants, so we don't need to add them all to the overlap map.
    1407     if (childState.compositingAncestor && !childState.compositingAncestor->isRenderViewLayer())
    1408         addToOverlapMap(overlapMap, layer, layerExtent);
    1409 
    1410 #if ENABLE(CSS_COMPOSITING)
    1411     layer.setHasNotIsolatedCompositedBlendingDescendants(childState.hasNotIsolatedCompositedBlendingDescendants);
    1412     ASSERT(!layer.hasNotIsolatedCompositedBlendingDescendants() || layer.hasNotIsolatedBlendingDescendants());
    1413 #endif
    1414     // Now check for reasons to become composited that depend on the state of descendant layers.
    1415     RenderLayer::IndirectCompositingReason indirectCompositingReason;
    1416     if (!willBeComposited && canBeComposited(layer)
    1417         && requiresCompositingForIndirectReason(layer.renderer(), childState.subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
    1418         layer.setIndirectCompositingReason(indirectCompositingReason);
    1419         childState.compositingAncestor = &layer;
    1420         overlapMap.pushCompositingContainer();
    1421         addToOverlapMapRecursive(overlapMap, layer);
    1422         willBeComposited = true;
    1423     }
    1424    
    1425     ASSERT(willBeComposited == needsToBeComposited(layer));
    1426     if (layer.reflectionLayer()) {
    1427         // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
    1428         layer.reflectionLayer()->setIndirectCompositingReason(willBeComposited ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None);
    1429     }
    1430 
    1431     // Subsequent layers in the parent stacking context also need to composite.
    1432     if (childState.subtreeIsCompositing)
    1433         compositingState.subtreeIsCompositing = true;
    1434 
    1435     // Set the flag to say that this layer has compositing children.
    1436     layer.setHasCompositingDescendant(childState.subtreeIsCompositing);
    1437 
    1438     // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that again.
    1439     bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer);
    1440 
    1441     // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
    1442     // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
    1443     // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
    1444     if ((!childState.testingOverlap && !isCompositedClippingLayer) || layerExtent.knownToBeHaveExtentUncertainty())
    1445         compositingState.testingOverlap = false;
    1446    
    1447     if (isCompositedClippingLayer) {
    1448         if (!willBeComposited) {
    1449             childState.compositingAncestor = &layer;
    1450             overlapMap.pushCompositingContainer();
    1451             addToOverlapMapRecursive(overlapMap, layer);
    1452             willBeComposited = true;
    1453          }
    1454     }
    1455 
    1456 #if ENABLE(CSS_COMPOSITING)
    1457     if ((willBeComposited && layer.hasBlendMode())
    1458         || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
    1459         compositingState.hasNotIsolatedCompositedBlendingDescendants = true;
    1460 #endif
    1461 
    1462     if (childState.compositingAncestor == &layer && !layer.isRenderViewLayer())
    1463         overlapMap.popCompositingContainer();
    1464 
    1465     // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
    1466     // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
    1467     // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
    1468     if (layer.isRenderViewLayer() && !childState.subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
    1469         // Don't drop out of compositing on iOS, because we may flash. See <rdar://problem/8348337>.
    1470 #if !PLATFORM(IOS_FAMILY)
    1471         enableCompositingMode(false);
    1472         willBeComposited = false;
    1473 #endif
    1474     }
    1475    
    1476     ASSERT(willBeComposited == needsToBeComposited(layer));
    1477 
    1478     // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree().
    1479     if (updateBacking(layer, CompositingChangeRepaintNow, willBeComposited ? BackingRequired::Yes : BackingRequired::No))
    1480         layersChanged = true;
    1481 
    1482     if (layer.reflectionLayer() && updateLayerCompositingState(*layer.reflectionLayer(), CompositingChangeRepaintNow))
    1483         layersChanged = true;
    1484 
    1485     descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform();
    1486 
    1487     overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
    14881724}
    14891725
     
    15251761#endif
    15261762
    1527 void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer& layer, Vector<Ref<GraphicsLayer>>& childLayersOfEnclosingLayer, int depth)
    1528 {
    1529     // Make the layer compositing if necessary, and set up clipping and content layers.
    1530     // Note that we can only do work here that is independent of whether the descendant layers
    1531     // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
    1532 
    1533     auto* layerBacking = layer.backing();
    1534     if (layerBacking) {
    1535         // The compositing state of all our children has been updated already, so now
    1536         // we can compute and cache the composited bounds for this layer.
    1537         layerBacking->updateCompositedBounds();
    1538 
    1539         if (auto* reflection = layer.reflectionLayer()) {
    1540             if (reflection->backing())
    1541                 reflection->backing()->updateCompositedBounds();
    1542         }
    1543 
    1544         if (layerBacking->updateConfiguration())
    1545             layerBacking->updateDebugIndicators(m_showDebugBorders, m_showRepaintCounter);
    1546        
    1547         layerBacking->updateGeometry();
    1548 
    1549         if (!layer.parent())
    1550             updateRootLayerPosition();
    1551 
    1552 #if !LOG_DISABLED
    1553         logLayerInfo(layer, depth);
    1554 #else
    1555         UNUSED_PARAM(depth);
    1556 #endif
    1557     }
    1558 
    1559     // If this layer has backing, then we are collecting its children, otherwise appending
    1560     // to the compositing child list of an enclosing layer.
    1561     Vector<Ref<GraphicsLayer>> layerChildren;
    1562     auto& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
    1563 
    1564 #if !ASSERT_DISABLED
    1565     LayerListMutationDetector mutationChecker(layer);
    1566 #endif
    1567 
    1568     for (auto* renderLayer : layer.negativeZOrderLayers())
    1569         rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
    1570 
    1571     // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
    1572     if (layer.negativeZOrderLayers().size()) {
    1573         if (layerBacking && layerBacking->foregroundLayer())
    1574             childList.append(*layerBacking->foregroundLayer());
    1575     }
    1576    
    1577     for (auto* renderLayer : layer.normalFlowLayers())
    1578         rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
    1579    
    1580     for (auto* renderLayer : layer.positiveZOrderLayers())
    1581         rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
    1582 
    1583     if (layerBacking) {
    1584         bool parented = false;
    1585         if (is<RenderWidget>(layer.renderer()))
    1586             parented = parentFrameContentLayers(&downcast<RenderWidget>(layer.renderer()));
    1587 
    1588         if (!parented)
    1589             layerBacking->parentForSublayers()->setChildren(WTFMove(layerChildren));
    1590 
    1591         // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
    1592         // Otherwise, the overflow control layers are normal children.
    1593         if (!layerBacking->hasClippingLayer() && !layerBacking->hasScrollingLayer()) {
    1594             if (auto* overflowControlLayer = layerBacking->layerForHorizontalScrollbar())
    1595                 layerBacking->parentForSublayers()->addChild(*overflowControlLayer);
    1596 
    1597             if (auto* overflowControlLayer = layerBacking->layerForVerticalScrollbar())
    1598                 layerBacking->parentForSublayers()->addChild(*overflowControlLayer);
    1599 
    1600             if (auto* overflowControlLayer = layerBacking->layerForScrollCorner())
    1601                 layerBacking->parentForSublayers()->addChild(*overflowControlLayer);
    1602         }
    1603 
    1604         childLayersOfEnclosingLayer.append(*layerBacking->childForSuperlayers());
    1605     }
    1606    
    1607     if (auto* layerBacking = layer.backing())
    1608         layerBacking->updateAfterDescendants();
    1609 }
    1610 
    16111763void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
    16121764{
     
    16891841}
    16901842
    1691 void RenderLayerCompositor::rootFixedBackgroundsChanged()
     1843void RenderLayerCompositor::rootLayerConfigurationChanged()
    16921844{
    16931845    auto* renderViewBacking = m_renderView.layer()->backing();
    1694     if (renderViewBacking && renderViewBacking->isFrameLayerWithTiledBacking())
    1695         setCompositingLayersNeedRebuild();
     1846    if (renderViewBacking && renderViewBacking->isFrameLayerWithTiledBacking()) {
     1847        m_renderView.layer()->setNeedsCompositingConfigurationUpdate();
     1848        scheduleCompositingLayerUpdate();
     1849    }
    16961850}
    16971851
     
    17811935        hostingLayer->addChild(*rootLayer);
    17821936    }
     1937    // FIXME: Why always return true and not just when the layers changed?
    17831938    return true;
    1784 }
    1785 
    1786 // This just updates layer geometry without changing the hierarchy.
    1787 void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer& layer, int depth)
    1788 {
    1789     if (auto* layerBacking = layer.backing()) {
    1790         // The compositing state of all our children has been updated already, so now
    1791         // we can compute and cache the composited bounds for this layer.
    1792         layerBacking->updateCompositedBounds();
    1793 
    1794         if (auto* reflection = layer.reflectionLayer()) {
    1795             if (reflection->backing())
    1796                 reflection->backing()->updateCompositedBounds();
    1797         }
    1798 
    1799         layerBacking->updateConfiguration();
    1800         layerBacking->updateGeometry();
    1801 
    1802         if (!layer.parent())
    1803             updateRootLayerPosition();
    1804 
    1805 #if !LOG_DISABLED
    1806         logLayerInfo(layer, depth);
    1807 #else
    1808         UNUSED_PARAM(depth);
    1809 #endif
    1810     }
    1811 
    1812 #if !ASSERT_DISABLED
    1813     LayerListMutationDetector mutationChecker(layer);
    1814 #endif
    1815 
    1816     for (auto* renderLayer : layer.negativeZOrderLayers())
    1817         updateLayerTreeGeometry(*renderLayer, depth + 1);
    1818 
    1819     for (auto* renderLayer : layer.normalFlowLayers())
    1820         updateLayerTreeGeometry(*renderLayer, depth + 1);
    1821    
    1822     for (auto* renderLayer : layer.positiveZOrderLayers())
    1823         updateLayerTreeGeometry(*renderLayer, depth + 1);
    1824 
    1825     if (auto* layerBacking = layer.backing())
    1826         layerBacking->updateAfterDescendants();
    1827 }
    1828 
    1829 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
    1830 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer& compositingAncestor, RenderLayer& layer)
    1831 {
    1832     if (&layer != &compositingAncestor) {
    1833         if (auto* layerBacking = layer.backing()) {
    1834             layerBacking->updateCompositedBounds();
    1835 
    1836             if (auto* reflection = layer.reflectionLayer()) {
    1837                 if (reflection->backing())
    1838                     reflection->backing()->updateCompositedBounds();
    1839             }
    1840 
    1841             layerBacking->updateGeometry();
    1842             layerBacking->updateAfterDescendants();
    1843             return;
    1844         }
    1845     }
    1846 
    1847     if (layer.reflectionLayer())
    1848         updateCompositingDescendantGeometry(compositingAncestor, *layer.reflectionLayer());
    1849 
    1850     if (!layer.hasCompositingDescendant())
    1851         return;
    1852 
    1853 #if !ASSERT_DISABLED
    1854     LayerListMutationDetector mutationChecker(layer);
    1855 #endif
    1856    
    1857     for (auto* renderLayer : layer.negativeZOrderLayers())
    1858         updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
    1859 
    1860     for (auto* renderLayer : layer.normalFlowLayers())
    1861         updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
    1862    
    1863     for (auto* renderLayer : layer.positiveZOrderLayers())
    1864         updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
    1865    
    1866     if (&layer != &compositingAncestor) {
    1867         if (auto* layerBacking = layer.backing())
    1868             layerBacking->updateAfterDescendants();
    1869     }
    18701939}
    18711940
     
    19732042
    19742043#if ENABLE(RUBBER_BANDING)
    1975     if (m_contentShadowLayer) {
     2044    if (m_contentShadowLayer && m_rootContentLayer) {
    19762045        m_contentShadowLayer->setPosition(m_rootContentLayer->position());
    19772046        m_contentShadowLayer->setSize(m_rootContentLayer->size());
     
    19902059}
    19912060
    1992 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
     2061bool RenderLayerCompositor::needsToBeComposited(const RenderLayer& layer, RequiresCompositingData& queryData) const
    19932062{
    19942063    if (!canBeComposited(layer))
    19952064        return false;
    19962065
    1997     return requiresCompositingLayer(layer, viewportConstrainedNotCompositedReason) || layer.mustCompositeForIndirectReasons() || (inCompositingMode() && layer.isRenderViewLayer());
     2066    return requiresCompositingLayer(layer, queryData) || layer.mustCompositeForIndirectReasons() || (inCompositingMode() && layer.isRenderViewLayer());
    19982067}
    19992068
    20002069// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
    20012070// Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
    2002 // static
    2003 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
     2071// FIXME: is clipsCompositingDescendants() an intrinsic reason?
     2072bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, RequiresCompositingData& queryData) const
    20042073{
    20052074    auto& renderer = rendererForCompositingTests(layer);
     
    20092078        || requiresCompositingForAnimation(renderer)
    20102079        || clipsCompositingDescendants(*renderer.layer())
    2011         || requiresCompositingForPosition(renderer, *renderer.layer(), viewportConstrainedNotCompositedReason)
     2080        || requiresCompositingForPosition(renderer, *renderer.layer(), queryData)
    20122081        || requiresCompositingForCanvas(renderer)
    20132082        || requiresCompositingForFilters(renderer)
     
    20152084        || requiresCompositingForBackfaceVisibility(renderer)
    20162085        || requiresCompositingForVideo(renderer)
    2017         || requiresCompositingForFrame(renderer)
    2018         || requiresCompositingForPlugin(renderer)
    2019         || requiresCompositingForOverflowScrolling(*renderer.layer());
     2086        || requiresCompositingForFrame(renderer, queryData)
     2087        || requiresCompositingForPlugin(renderer, queryData)
     2088        || requiresCompositingForOverflowScrolling(*renderer.layer(), queryData);
    20202089}
    20212090
     
    20652134        return true;
    20662135
     2136    RequiresCompositingData queryData;
    20672137    if (layer.isRenderViewLayer()
    20682138        || layer.transform() // note: excludes perspective and transformStyle3D.
    20692139        || requiresCompositingForAnimation(renderer)
    2070         || requiresCompositingForPosition(renderer, layer)
     2140        || requiresCompositingForPosition(renderer, layer, queryData)
    20712141        || requiresCompositingForCanvas(renderer)
    20722142        || requiresCompositingForFilters(renderer)
     
    20742144        || requiresCompositingForBackfaceVisibility(renderer)
    20752145        || requiresCompositingForVideo(renderer)
    2076         || requiresCompositingForFrame(renderer)
    2077         || requiresCompositingForPlugin(renderer)
    2078         || requiresCompositingForOverflowScrolling(layer)
     2146        || requiresCompositingForFrame(renderer, queryData)
     2147        || requiresCompositingForPlugin(renderer, queryData)
     2148        || requiresCompositingForOverflowScrolling(layer, queryData)
    20792149        || renderer.isTransparent()
    20802150        || renderer.hasMask()
     
    21062176        return reasons;
    21072177
     2178    RequiresCompositingData queryData;
     2179
    21082180    auto& renderer = rendererForCompositingTests(layer);
    21092181
     
    21152187    else if (requiresCompositingForCanvas(renderer))
    21162188        reasons.add(CompositingReason::Canvas);
    2117     else if (requiresCompositingForPlugin(renderer))
     2189    else if (requiresCompositingForPlugin(renderer, queryData))
    21182190        reasons.add(CompositingReason::Plugin);
    2119     else if (requiresCompositingForFrame(renderer))
     2191    else if (requiresCompositingForFrame(renderer, queryData))
    21202192        reasons.add(CompositingReason::IFrame);
    21212193
     
    21352207        reasons.add(CompositingReason::WillChange);
    21362208
    2137     if (requiresCompositingForPosition(renderer, *renderer.layer()))
     2209    if (requiresCompositingForPosition(renderer, *renderer.layer(), queryData))
    21382210        reasons.add(renderer.isFixedPositioned() ? CompositingReason::PositionFixed : CompositingReason::PositionSticky);
    21392211
    2140     if (requiresCompositingForOverflowScrolling(*renderer.layer()))
     2212    if (requiresCompositingForOverflowScrolling(*renderer.layer(), queryData))
    21412213        reasons.add(CompositingReason::OverflowScrollingTouch);
    21422214
     
    22822354// Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
    22832355// but a sibling in the z-order hierarchy.
     2356// FIXME: can we do this without a tree walk?
    22842357bool RenderLayerCompositor::clippedByAncestor(RenderLayer& layer) const
    22852358{
    2286     if (!layer.isComposited() || !layer.parent())
    2287         return false;
    2288 
     2359    ASSERT(layer.isComposited());
     2360    if (!layer.parent())
     2361        return false;
     2362
     2363    // On first pass in WK1, the root may not have become composited yet.
    22892364    auto* compositingAncestor = layer.ancestorCompositingLayer();
    22902365    if (!compositingAncestor)
     
    23242399}
    23252400
    2326 bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
    2327 {
    2328     if (isMainFrameCompositor())
    2329         return false;
    2330 
    2331 #if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
    2332     if (!m_renderView.settings().asyncFrameScrollingEnabled())
    2333         return false;
    2334 #endif
    2335 
    2336     if (!(m_compositingTriggers & ChromeClient::ScrollableNonMainFrameTrigger))
    2337         return false;
    2338 
    2339     // Need this done first to determine overflow.
    2340     ASSERT(!m_renderView.needsLayout());
    2341     return m_renderView.frameView().isScrollable();
     2401bool RenderLayerCompositor::requiresCompositingForAnimation(RenderLayerModelObject& renderer) const
     2402{
     2403    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
     2404        return false;
     2405
     2406    if (auto* element = renderer.element()) {
     2407        if (auto* timeline = element->document().existingTimeline()) {
     2408            if (timeline->runningAnimationsForElementAreAllAccelerated(*element))
     2409                return true;
     2410        }
     2411    }
     2412
     2413    if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
     2414        return false;
     2415
     2416    const AnimationBase::RunningState activeAnimationState = AnimationBase::Running | AnimationBase::Paused;
     2417    auto& animController = renderer.animation();
     2418    return (animController.isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity, activeAnimationState)
     2419        && (inCompositingMode() || (m_compositingTriggers & ChromeClient::AnimatedOpacityTrigger)))
     2420        || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyFilter, activeAnimationState)
     2421#if ENABLE(FILTERS_LEVEL_2)
     2422        || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitBackdropFilter, activeAnimationState)
     2423#endif
     2424        || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyTransform, activeAnimationState);
    23422425}
    23432426
     
    23592442        if (renderer.style().transform().has3DOperation() && renderer.hasFilter())
    23602443            return true;
    2361         return !renderer.style().transform().isRepresentableIn2D();
     2444        return renderer.style().transform().isRepresentableIn2D() ? false : true;
    23622445    }
    23632446    return false;
     
    23932476
    23942477    auto& video = downcast<RenderVideo>(renderer);
    2395     return (video.requiresImmediateCompositing() || video.shouldDisplayVideo()) && canAccelerateVideoRendering(video);
     2478    if ((video.requiresImmediateCompositing() || video.shouldDisplayVideo()) && canAccelerateVideoRendering(video))
     2479        return true;
    23962480#else
    23972481    UNUSED_PARAM(renderer);
     2482#endif
    23982483    return false;
    2399 #endif
    24002484}
    24012485
     
    24252509}
    24262510
    2427 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderLayerModelObject& renderer) const
     2511bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject& renderer) const
     2512{
     2513#if ENABLE(FILTERS_LEVEL_2)
     2514    if (renderer.hasBackdropFilter())
     2515        return true;
     2516#endif
     2517
     2518    if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
     2519        return false;
     2520
     2521    return renderer.hasFilter();
     2522}
     2523
     2524bool RenderLayerCompositor::requiresCompositingForWillChange(RenderLayerModelObject& renderer) const
     2525{
     2526    if (!renderer.style().willChange() || !renderer.style().willChange()->canTriggerCompositing())
     2527        return false;
     2528
     2529#if ENABLE(FULLSCREEN_API)
     2530    // FIXME: does this require layout?
     2531    if (renderer.layer() && isDescendantOfFullScreenLayer(*renderer.layer()) == FullScreenDescendant::No)
     2532        return false;
     2533#endif
     2534
     2535    if (m_compositingPolicy == CompositingPolicy::Conservative)
     2536        return false;
     2537
     2538    if (is<RenderBox>(renderer))
     2539        return true;
     2540
     2541    return renderer.style().willChange()->canTriggerCompositingOnInline();
     2542}
     2543
     2544bool RenderLayerCompositor::requiresCompositingForPlugin(RenderLayerModelObject& renderer, RequiresCompositingData& queryData) const
    24282545{
    24292546    if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
     
    24342551        return false;
    24352552
    2436     m_reevaluateCompositingAfterLayout = true;
    2437    
    24382553    auto& pluginRenderer = downcast<RenderWidget>(renderer);
    24392554    if (pluginRenderer.style().visibility() != Visibility::Visible)
     
    24412556
    24422557    // If we can't reliably know the size of the plugin yet, don't change compositing state.
    2443     if (pluginRenderer.needsLayout())
     2558    if (queryData.layoutUpToDate == LayoutUpToDate::No) {
     2559        queryData.reevaluateAfterLayout = true;
    24442560        return pluginRenderer.isComposited();
     2561    }
    24452562
    24462563    // Don't go into compositing mode if height or width are zero, or size is 1x1.
    24472564    IntRect contentBox = snappedIntRect(pluginRenderer.contentBoxRect());
    2448     return contentBox.height() * contentBox.width() > 1;
    2449 }
    2450 
    2451 bool RenderLayerCompositor::requiresCompositingForFrame(RenderLayerModelObject& renderer) const
     2565    return (contentBox.height() * contentBox.width() > 1);
     2566}
     2567
     2568bool RenderLayerCompositor::requiresCompositingForFrame(RenderLayerModelObject& renderer, RequiresCompositingData& queryData) const
    24522569{
    24532570    if (!is<RenderWidget>(renderer))
     
    24612578        return false;
    24622579
    2463     m_reevaluateCompositingAfterLayout = true;
    2464 
    2465     // If we can't reliably know the size of the iframe yet, don't change compositing state.
    2466     if (!frameRenderer.parent() || frameRenderer.needsLayout())
     2580    if (queryData.layoutUpToDate == LayoutUpToDate::No) {
     2581        queryData.reevaluateAfterLayout = true;
    24672582        return frameRenderer.isComposited();
    2468    
     2583    }
     2584
    24692585    // Don't go into compositing mode if height or width are zero.
    24702586    return !snappedIntRect(frameRenderer.contentBoxRect()).isEmpty();
    24712587}
    24722588
    2473 bool RenderLayerCompositor::requiresCompositingForAnimation(RenderLayerModelObject& renderer) const
    2474 {
    2475     if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
    2476         return false;
    2477 
    2478     if (auto* element = renderer.element()) {
    2479         if (auto* timeline = element->document().existingTimeline()) {
    2480             if (timeline->runningAnimationsForElementAreAllAccelerated(*element))
    2481                 return true;
    2482         }
    2483     }
    2484 
    2485     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
    2486         return false;
    2487 
    2488     const AnimationBase::RunningState activeAnimationState = AnimationBase::Running | AnimationBase::Paused;
    2489     auto& animController = renderer.animation();
    2490     return (animController.isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity, activeAnimationState)
    2491             && (inCompositingMode() || (m_compositingTriggers & ChromeClient::AnimatedOpacityTrigger)))
    2492             || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyFilter, activeAnimationState)
    2493 #if ENABLE(FILTERS_LEVEL_2)
    2494             || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitBackdropFilter, activeAnimationState)
    2495 #endif
    2496             || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyTransform, activeAnimationState);
    2497 }
    2498 
     2589bool RenderLayerCompositor::requiresCompositingForScrollableFrame(RequiresCompositingData& queryData) const
     2590{
     2591    if (isMainFrameCompositor())
     2592        return false;
     2593
     2594#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
     2595    if (!m_renderView.settings().asyncFrameScrollingEnabled())
     2596        return false;
     2597#endif
     2598
     2599    if (!(m_compositingTriggers & ChromeClient::ScrollableNonMainFrameTrigger))
     2600        return false;
     2601
     2602    if (queryData.layoutUpToDate == LayoutUpToDate::No) {
     2603        queryData.reevaluateAfterLayout = true;
     2604        return m_renderView.isComposited();
     2605    }
     2606
     2607    return m_renderView.frameView().isScrollable();
     2608}
     2609
     2610bool RenderLayerCompositor::requiresCompositingForPosition(RenderLayerModelObject& renderer, const RenderLayer& layer, RequiresCompositingData& queryData) const
     2611{
     2612    // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
     2613    // opacity, transform) can get their own composited layer. A stacking context is required otherwise
     2614    // z-index and clipping will be broken.
     2615    if (!renderer.isPositioned())
     2616        return false;
     2617   
     2618#if ENABLE(FULLSCREEN_API)
     2619    if (isDescendantOfFullScreenLayer(layer) == FullScreenDescendant::No)
     2620        return false;
     2621#endif
     2622
     2623    auto position = renderer.style().position();
     2624    bool isFixed = renderer.isOutOfFlowPositioned() && position == PositionType::Fixed;
     2625    if (isFixed && !layer.isStackingContext())
     2626        return false;
     2627   
     2628    bool isSticky = renderer.isInFlowPositioned() && position == PositionType::Sticky;
     2629    if (!isFixed && !isSticky)
     2630        return false;
     2631
     2632    // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
     2633    if (!m_renderView.settings().acceleratedCompositingForFixedPositionEnabled())
     2634        return false;
     2635
     2636    if (isSticky)
     2637        return isAsyncScrollableStickyLayer(layer);
     2638
     2639    if (queryData.layoutUpToDate == LayoutUpToDate::No) {
     2640        queryData.reevaluateAfterLayout = true;
     2641        return layer.isComposited();
     2642    }
     2643
     2644    auto container = renderer.container();
     2645    ASSERT(container);
     2646
     2647    // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
     2648    // They will stay fixed wrt the container rather than the enclosing frame.j
     2649    if (container != &m_renderView) {
     2650        queryData.nonCompositedForPositionReason = RenderLayer::NotCompositedForNonViewContainer;
     2651        return false;
     2652    }
     2653
     2654    bool paintsContent = layer.isVisuallyNonEmpty() || layer.hasVisibleDescendant();
     2655    if (!paintsContent) {
     2656        queryData.nonCompositedForPositionReason = RenderLayer::NotCompositedForNoVisibleContent;
     2657        return false;
     2658    }
     2659
     2660    bool intersectsViewport = fixedLayerIntersectsViewport(layer);
     2661    if (!intersectsViewport) {
     2662        queryData.nonCompositedForPositionReason = RenderLayer::NotCompositedForBoundsOutOfView;
     2663        LOG_WITH_STREAM(Compositing, stream << "Layer " << &layer << " is outside the viewport");
     2664        return false;
     2665    }
     2666
     2667    return true;
     2668}
     2669
     2670bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer& layer, RequiresCompositingData& queryData) const
     2671{
     2672#if PLATFORM(IOS_FAMILY)
     2673    if (!layer.canUseAcceleratedTouchScrolling())
     2674        return false;
     2675
     2676    if (queryData.layoutUpToDate == LayoutUpToDate::No) {
     2677        queryData.reevaluateAfterLayout = true;
     2678        return layer.isComposited();
     2679    }
     2680
     2681    return layer.hasTouchScrollableOverflow();
     2682#else
     2683    UNUSED_PARAM(layer);
     2684    UNUSED_PARAM(queryData);
     2685    return false;
     2686#endif
     2687}
     2688
     2689// FIXME: why doesn't this handle the clipping cases?
    24992690bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerModelObject& renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
    25002691{
     
    25262717}
    25272718
    2528 bool RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons(const RenderLayerModelObject& renderer, const RenderStyle& oldStyle)
    2529 {
    2530     auto& style = renderer.style();
    2531     if (RenderElement::createsGroupForStyle(style) != RenderElement::createsGroupForStyle(oldStyle))
     2719bool RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons(const RenderStyle& oldStyle, const RenderStyle& newStyle)
     2720{
     2721    if (RenderElement::createsGroupForStyle(newStyle) != RenderElement::createsGroupForStyle(oldStyle))
    25322722        return true;
    2533     if (style.isolation() != oldStyle.isolation())
     2723    if (newStyle.isolation() != oldStyle.isolation())
    25342724        return true;
    2535     if (style.hasTransform() != oldStyle.hasTransform())
     2725    if (newStyle.hasTransform() != oldStyle.hasTransform())
    25362726        return true;
    2537     if (style.boxReflect() != oldStyle.boxReflect())
     2727    if (newStyle.boxReflect() != oldStyle.boxReflect())
    25382728        return true;
    2539     if (style.transformStyle3D() != oldStyle.transformStyle3D())
     2729    if (newStyle.transformStyle3D() != oldStyle.transformStyle3D())
    25402730        return true;
    2541     if (style.hasPerspective() != oldStyle.hasPerspective())
     2731    if (newStyle.hasPerspective() != oldStyle.hasPerspective())
    25422732        return true;
    25432733
    25442734    return false;
    2545 }
    2546 
    2547 bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject& renderer) const
    2548 {
    2549 #if ENABLE(FILTERS_LEVEL_2)
    2550     if (renderer.hasBackdropFilter())
    2551         return true;
    2552 #endif
    2553 
    2554     if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
    2555         return false;
    2556 
    2557     return renderer.hasFilter();
    2558 }
    2559 
    2560 bool RenderLayerCompositor::requiresCompositingForWillChange(RenderLayerModelObject& renderer) const
    2561 {
    2562     if (!renderer.style().willChange() || !renderer.style().willChange()->canTriggerCompositing())
    2563         return false;
    2564 
    2565 #if ENABLE(FULLSCREEN_API)
    2566     if (renderer.layer() && isDescendantOfFullScreenLayer(*renderer.layer()) == FullScreenDescendant::No)
    2567         return false;
    2568 #endif
    2569 
    2570     if (m_compositingPolicy == CompositingPolicy::Conservative)
    2571         return false;
    2572 
    2573     if (is<RenderBox>(renderer))
    2574         return true;
    2575 
    2576     return renderer.style().willChange()->canTriggerCompositingOnInline();
    25772735}
    25782736
     
    26252783}
    26262784
    2627 bool RenderLayerCompositor::useCoordinatedScrollingForLayer(const RenderLayer& layer) const
    2628 {
    2629     if (layer.isRenderViewLayer() && hasCoordinatedScrolling())
    2630         return true;
    2631 
    2632     return layer.hasTouchScrollableOverflow();
    2633 }
    2634 
    2635 bool RenderLayerCompositor::requiresCompositingForPosition(RenderLayerModelObject& renderer, const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
    2636 {
    2637     // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
    2638     // opacity, transform) can get their own composited layer. A stacking context is required otherwise
    2639     // z-index and clipping will be broken.
    2640     if (!renderer.isPositioned())
    2641         return false;
    2642    
    2643 #if ENABLE(FULLSCREEN_API)
    2644     if (isDescendantOfFullScreenLayer(layer) == FullScreenDescendant::No)
    2645         return false;
    2646 #endif
    2647 
    2648     auto position = renderer.style().position();
    2649     bool isFixed = renderer.isOutOfFlowPositioned() && position == PositionType::Fixed;
    2650     if (isFixed && !layer.isStackingContext())
    2651         return false;
    2652    
    2653     bool isSticky = renderer.isInFlowPositioned() && position == PositionType::Sticky;
    2654     if (!isFixed && !isSticky)
    2655         return false;
    2656 
    2657     // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
    2658     if (!m_renderView.settings().acceleratedCompositingForFixedPositionEnabled())
    2659         return false;
    2660 
    2661     if (isSticky)
    2662         return isAsyncScrollableStickyLayer(layer);
    2663 
    2664     auto container = renderer.container();
    2665     // If the renderer is not hooked up yet then we have to wait until it is.
    2666     if (!container) {
    2667         m_reevaluateCompositingAfterLayout = true;
    2668         return false;
    2669     }
    2670 
    2671     // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
    2672     // They will stay fixed wrt the container rather than the enclosing frame.
    2673     if (container != &m_renderView) {
    2674         if (viewportConstrainedNotCompositedReason)
    2675             *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
    2676         return false;
    2677     }
    2678    
    2679     // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
    2680     if (!m_inPostLayoutUpdate) {
    2681         m_reevaluateCompositingAfterLayout = true;
    2682         return layer.isComposited();
    2683     }
    2684 
    2685     bool paintsContent = layer.isVisuallyNonEmpty() || layer.hasVisibleDescendant();
    2686     if (!paintsContent) {
    2687         if (viewportConstrainedNotCompositedReason)
    2688             *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
    2689         return false;
    2690     }
     2785bool RenderLayerCompositor::fixedLayerIntersectsViewport(const RenderLayer& layer) const
     2786{
     2787    ASSERT(layer.renderer().style().position() == PositionType::Fixed);
    26912788
    26922789    // Fixed position elements that are invisible in the current view don't get their own layer.
     
    26982795        viewBounds = m_renderView.frameView().rectForFixedPositionLayout();
    26992796
    2700     LayoutRect layerBounds = layer.calculateLayerBounds(&layer, LayoutSize(), { RenderLayer::UseLocalClipRectIfPossible, RenderLayer::IncludeLayerFilterOutsets, RenderLayer::UseFragmentBoxesExcludingCompositing,
     2797    LayoutRect layerBounds = layer.calculateLayerBounds(&layer, LayoutSize(), { RenderLayer::UseLocalClipRectIfPossible, RenderLayer::IncludeFilterOutsets, RenderLayer::UseFragmentBoxesExcludingCompositing,
    27012798        RenderLayer::ExcludeHiddenDescendants, RenderLayer::DontConstrainForMask, RenderLayer::IncludeCompositedDescendants });
    27022799    // Map to m_renderView to ignore page scale.
    27032800    FloatRect absoluteBounds = layer.renderer().localToContainerQuad(FloatRect(layerBounds), &m_renderView).boundingBox();
    2704     if (!viewBounds.intersects(enclosingIntRect(absoluteBounds))) {
    2705         if (viewportConstrainedNotCompositedReason)
    2706             *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
    2707         LOG_WITH_STREAM(Compositing, stream << "Layer " << &layer << " bounds " << absoluteBounds << " outside visible rect " << viewBounds);
    2708         return false;
    2709     }
    2710    
    2711     return true;
    2712 }
    2713 
    2714 bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer& layer) const
    2715 {
    2716 #if PLATFORM(IOS_FAMILY)
    2717     if (!layer.canUseAcceleratedTouchScrolling())
    2718         return false;
    2719 
    2720     if (!m_inPostLayoutUpdate) {
    2721         m_reevaluateCompositingAfterLayout = true;
    2722         return layer.isComposited();
    2723     }
     2801    return viewBounds.intersects(enclosingIntRect(absoluteBounds));
     2802}
     2803
     2804bool RenderLayerCompositor::useCoordinatedScrollingForLayer(const RenderLayer& layer) const
     2805{
     2806    if (layer.isRenderViewLayer() && hasCoordinatedScrolling())
     2807        return true;
    27242808
    27252809    return layer.hasTouchScrollableOverflow();
    2726 #else
    2727     UNUSED_PARAM(layer);
    2728     return false;
    2729 #endif
    27302810}
    27312811
     
    31193199
    31203200    bool hadFixedBackground = oldStyle && oldStyle->hasEntirelyFixedBackground();
    3121     if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground()) {
    3122         setCompositingLayersNeedRebuild();
    3123         scheduleCompositingLayerUpdate();
    3124     }
     3201    if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground())
     3202        rootLayerConfigurationChanged();
    31253203}
    31263204
     
    31393217    bool extendedBackgroundColorChanged = m_rootExtendedBackgroundColor != extendedBackgroundColor;
    31403218
    3141     LOG(Compositing, "RenderLayerCompositor %p rootBackgroundColorOrTransparencyChanged. isTransparent=%d, transparencyChanged=%d, backgroundColorChanged=%d, extendedBackgroundColorChanged=%d", this, isTransparent, transparencyChanged, backgroundColorChanged, extendedBackgroundColorChanged);
    31423219    if (!transparencyChanged && !backgroundColorChanged && !extendedBackgroundColorChanged)
    31433220        return;
     3221
     3222    LOG(Compositing, "RenderLayerCompositor %p rootBackgroundColorOrTransparencyChanged. isTransparent=%d", this, isTransparent);
    31443223
    31453224    m_viewBackgroundIsTransparent = isTransparent;
     
    31613240    }
    31623241   
    3163     setRootLayerConfigurationNeedsUpdate();
    3164     scheduleCompositingLayerUpdate();
     3242    rootLayerConfigurationChanged();
    31653243}
    31663244
     
    40654143    case CompositingUpdateType::AfterStyleChange: ts << "after style change"; break;
    40664144    case CompositingUpdateType::AfterLayout: ts << "after layout"; break;
    4067     case CompositingUpdateType::OnHitTest: ts << "on hit test"; break;
    40684145    case CompositingUpdateType::OnScroll: ts << "on scroll"; break;
    40694146    case CompositingUpdateType::OnCompositedScroll: ts << "on composited scroll"; break;
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.h

    r238070 r238090  
    5050    AfterStyleChange,
    5151    AfterLayout,
    52     OnHitTest,
    5352    OnScroll,
    5453    OnCompositedScroll
     
    111110    bool canRender3DTransforms() const;
    112111
    113     // Called when the layer hierarchy needs to be updated (compositing layers have been
    114     // created, destroyed or re-parented).
    115     void setCompositingLayersNeedRebuild(bool needRebuild = true);
    116     bool compositingLayersNeedRebuild() const { return m_compositingLayersNeedRebuild; }
    117    
    118112    void willRecalcStyle();
    119113
     
    142136    // Update the compositing state of the given layer. Returns true if that state changed.
    143137    enum CompositingChangeRepaint { CompositingChangeRepaintNow, CompositingChangeWillRepaintLater };
    144     bool updateLayerCompositingState(RenderLayer&, CompositingChangeRepaint = CompositingChangeRepaintNow);
    145 
    146     // Update the geometry for compositing children of compositingAncestor.
    147     void updateCompositingDescendantGeometry(RenderLayer& compositingAncestor, RenderLayer&);
    148    
     138    enum class LayoutUpToDate {
     139        Yes, No
     140    };
     141
     142    struct RequiresCompositingData {
     143        LayoutUpToDate layoutUpToDate { LayoutUpToDate::Yes };
     144        RenderLayer::ViewportConstrainedNotCompositedReason nonCompositedForPositionReason { RenderLayer::NoNotCompositedReason };
     145        bool reevaluateAfterLayout { false };
     146    };
     147
     148    bool updateLayerCompositingState(RenderLayer&, RequiresCompositingData&, CompositingChangeRepaint = CompositingChangeRepaintNow);
     149
    149150    // Whether layer's backing needs a graphics layer to do clipping by an ancestor (non-stacking-context parent with overflow).
    150151    bool clippedByAncestor(RenderLayer&) const;
     
    154155    // Whether the given layer needs an extra 'contents' layer.
    155156    bool needsContentsCompositingLayer(const RenderLayer&) const;
     157
     158    bool fixedLayerIntersectsViewport(const RenderLayer&) const;
    156159
    157160    bool supportsFixedRootBackgroundCompositing() const;
     
    235238    void frameViewDidAddOrRemoveScrollbars();
    236239    void frameViewDidLayout();
    237     void rootFixedBackgroundsChanged();
     240    void rootLayerConfigurationChanged();
    238241
    239242    void scrollingLayerDidChange(RenderLayer&);
     
    296299    void setTracksRepaints(bool tracksRepaints) { m_isTrackingRepaints = tracksRepaints; }
    297300
    298 
    299     void setShouldReevaluateCompositingAfterLayout() { m_reevaluateCompositingAfterLayout = true; }
    300 
    301301    bool viewHasTransparentBackground(Color* backgroundColor = nullptr) const;
    302302
     
    347347
    348348    // Whether the given RL needs a compositing layer.
    349     bool needsToBeComposited(const RenderLayer&, RenderLayer::ViewportConstrainedNotCompositedReason* = nullptr) const;
     349    bool needsToBeComposited(const RenderLayer&, RequiresCompositingData&) const;
    350350    // Whether the layer has an intrinsic need for compositing layer.
    351     bool requiresCompositingLayer(const RenderLayer&, RenderLayer::ViewportConstrainedNotCompositedReason* = nullptr) const;
     351    bool requiresCompositingLayer(const RenderLayer&, RequiresCompositingData&) const;
    352352    // Whether the layer could ever be composited.
    353353    bool canBeComposited(const RenderLayer&) const;
     
    356356    // Make or destroy the backing for this layer; returns true if backing changed.
    357357    enum class BackingRequired { No, Yes, Unknown };
    358     bool updateBacking(RenderLayer&, CompositingChangeRepaint shouldRepaint, BackingRequired = BackingRequired::Unknown);
     358    bool updateBacking(RenderLayer&, RequiresCompositingData&, CompositingChangeRepaint shouldRepaint, BackingRequired = BackingRequired::Unknown);
    359359
    360360    void clearBackingForLayerIncludingDescendants(RenderLayer&);
     
    369369    void updateCompositingLayersTimerFired();
    370370
    371     // Returns true if any layer's compositing changed
    372     void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer&, OverlapMap&, CompositingState&, bool& layersChanged, bool& descendantHas3DTransform);
    373 
     371    void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer&, OverlapMap&, CompositingState&, bool& descendantHas3DTransform);
     372    void traverseUnchangedSubtree(RenderLayer* ancestorLayer, RenderLayer&, OverlapMap&, CompositingState&, bool& descendantHas3DTransform);
     373
     374    enum class UpdateLevel {
     375        AllDescendants          = 1 << 0,
     376        CompositedChildren      = 1 << 1,
     377    };
    374378    // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
    375     void rebuildCompositingLayerTree(RenderLayer&, Vector<Ref<GraphicsLayer>>& childGraphicsLayersOfEnclosingLayer, int depth);
    376 
    377     // Recurses down the tree, updating layer geometry only.
    378     void updateLayerTreeGeometry(RenderLayer&, int depth);
    379    
    380     // Hook compositing layers together
     379    void updateBackingAndHierarchy(RenderLayer&, Vector<Ref<GraphicsLayer>>& childGraphicsLayersOfEnclosingLayer, OptionSet<UpdateLevel> = { }, int depth = 0);
     380
    381381    void setCompositingParent(RenderLayer& childLayer, RenderLayer* parentLayer);
    382382    void removeCompositedChildren(RenderLayer&);
     
    418418#endif
    419419
     420    // Non layout-dependent
    420421    bool requiresCompositingForAnimation(RenderLayerModelObject&) const;
    421422    bool requiresCompositingForTransform(RenderLayerModelObject&) const;
     
    423424    bool requiresCompositingForVideo(RenderLayerModelObject&) const;
    424425    bool requiresCompositingForCanvas(RenderLayerModelObject&) const;
    425     bool requiresCompositingForPlugin(RenderLayerModelObject&) const;
    426     bool requiresCompositingForFrame(RenderLayerModelObject&) const;
    427426    bool requiresCompositingForFilters(RenderLayerModelObject&) const;
    428427    bool requiresCompositingForWillChange(RenderLayerModelObject&) const;
    429     bool requiresCompositingForScrollableFrame() const;
    430     bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RenderLayer::ViewportConstrainedNotCompositedReason* = nullptr) const;
    431     bool requiresCompositingForOverflowScrolling(const RenderLayer&) const;
     428
     429    // Layout-dependent
     430    bool requiresCompositingForPlugin(RenderLayerModelObject&, RequiresCompositingData&) const;
     431    bool requiresCompositingForFrame(RenderLayerModelObject&, RequiresCompositingData&) const;
     432    bool requiresCompositingForScrollableFrame(RequiresCompositingData&) const;
     433    bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RequiresCompositingData&) const;
     434    bool requiresCompositingForOverflowScrolling(const RenderLayer&, RequiresCompositingData&) const;
     435
    432436    bool requiresCompositingForIndirectReason(RenderLayerModelObject&, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
    433     static bool styleChangeMayAffectIndirectCompositingReasons(const RenderLayerModelObject& renderer, const RenderStyle& oldStyle);
     437
     438    static bool styleChangeMayAffectIndirectCompositingReasons(const RenderStyle& oldStyle, const RenderStyle& newStyle);
    434439
    435440    void updateCustomLayersAfterFlush();
     
    470475#if !LOG_DISABLED
    471476    const char* logReasonsForCompositing(const RenderLayer&);
    472     void logLayerInfo(const RenderLayer&, int depth);
     477    void logLayerInfo(const RenderLayer&, const char*, int depth);
    473478#endif
    474479
     
    476481    bool isMainFrameCompositor() const;
    477482   
    478     void setRootLayerConfigurationNeedsUpdate() { m_rootLayerConfigurationNeedsUpdate = true; }
    479 
    480483private:
    481484    RenderView& m_renderView;
     
    493496    bool m_displayListDrawingEnabled { false };
    494497
    495     // When true, we have to wait until layout has happened before we can decide whether to enter compositing mode,
    496     // because only then do we know the final size of plugins and iframes.
    497     mutable bool m_reevaluateCompositingAfterLayout { false };
    498 
    499498    bool m_compositing { false };
    500     bool m_compositingLayersNeedRebuild { false };
    501     bool m_rootLayerConfigurationNeedsUpdate { false };
    502499    bool m_flushingLayers { false };
    503500    bool m_shouldFlushOnReattach { false };
     
    549546    bool m_layerFlushThrottlingTemporarilyDisabledForInteraction { false };
    550547    bool m_hasPendingLayerFlush { false };
    551     bool m_layerNeedsCompositingUpdate { false };
    552548    bool m_viewBackgroundIsTransparent { false };
    553549
  • trunk/Source/WebCore/rendering/RenderTreeAsText.cpp

    r237058 r238090  
    705705    // Ensure our lists are up-to-date.
    706706    layer.updateLayerListsIfNeeded();
     707    layer.updateDescendantDependentFlags();
    707708
    708709    bool shouldPaint = (behavior & RenderAsTextShowAllLayers) ? true : layer.intersectsDamageRect(layerBounds, damageRect.rect(), &rootLayer, layer.offsetFromAncestor(&rootLayer));
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r238080 r238090  
     12018-11-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Make compositing updates incremental
     4        https://bugs.webkit.org/show_bug.cgi?id=90342
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Fix spelling error.
     9
     10        * WebView/WebView.mm:
     11        (-[WebView _setMediaLayer:forPluginView:]):
     12
    1132018-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
    214
  • trunk/Source/WebKitLegacy/mac/WebView/WebView.mm

    r238074 r238090  
    41904190        if (layerForWidget->contentsLayerForMedia() != layer) {
    41914191            layerForWidget->setContentsToPlatformLayer(layer, GraphicsLayer::ContentsLayerPurpose::Media);
    4192             // We need to make sure the layer hierachy change is applied immediately.
     4192            // We need to make sure the layer hierarchy change is applied immediately.
    41934193            if (mainCoreFrame->view())
    41944194                mainCoreFrame->view()->flushCompositingStateIncludingSubframes();
Note: See TracChangeset for help on using the changeset viewer.