Changeset 238090 in webkit
- Timestamp:
- Nov 12, 2018, 9:14:05 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 7 added
- 22 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r238086 r238090 1 2018-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 1 29 2018-11-12 Jer Noble <jer.noble@apple.com> 2 30 -
trunk/LayoutTests/compositing/filters/sw-layer-overlaps-hw-shadow-expected.txt
r225897 r238090 8 8 (children 2 9 9 (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) 14 13 (drawsContent 1) 15 14 ) -
trunk/LayoutTests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt
r225897 r238090 8 8 (children 2 9 9 (GraphicsLayer 10 (offsetFromRenderer width=-1 25 height=-125)11 (position 2 05.00 205.00)12 (anchor 0.7 8 0.78)13 (bounds 2 25.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) 14 14 (drawsContent 1) 15 15 ) 16 16 (GraphicsLayer 17 (bounds 2 25.00 225.00)17 (bounds 200.00 200.00) 18 18 (drawsContent 1) 19 19 ) -
trunk/LayoutTests/compositing/filters/sw-shadow-overlaps-hw-layer-expected.txt
r168244 r238090 13 13 ) 14 14 (GraphicsLayer 15 (bounds 125.00 125.00) 15 (bounds 100.00 100.00) 16 (contentsOpaque 1) 16 17 (drawsContent 1) 17 18 ) -
trunk/LayoutTests/compositing/filters/sw-shadow-overlaps-hw-shadow-expected.txt
r225897 r238090 8 8 (children 2 9 9 (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) 14 13 (drawsContent 1) 15 14 ) 16 15 (GraphicsLayer 17 (bounds 125.00 125.00) 16 (bounds 100.00 100.00) 17 (contentsOpaque 1) 18 18 (drawsContent 1) 19 19 ) -
trunk/LayoutTests/compositing/layer-creation/change-to-overlap-expected.txt
r238089 r238090 8 8 (children 2 9 9 (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) 15 13 ) 16 14 (GraphicsLayer 17 ( bounds 100.00 100.00)18 ( contentsOpaque 1)15 (position 5.00 5.00) 16 (bounds 150.00 150.00) 19 17 ) 20 18 ) -
trunk/LayoutTests/compositing/video/video-clip-change-src.html
r177324 r238090 22 22 23 23 function canplaythrough() { 24 if (callback) 24 if (!callback) 25 return; 26 27 setTimeout(() => { 25 28 callback(); 29 }, 0); 26 30 } 27 31 -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r238013 r238090 626 626 webkit.org/b/188357 legacy-animation-engine/compositing/layer-creation/animation-overlap-with-children.html [ Pass Failure ] 627 627 628 webkit.org/b/190648 compositing/layer-creation/fixed-overlap-extent.html [ Pass Failure ] 629 628 630 # <rdar://problem/42904780> 629 631 [ Mojave+ Release ] imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/hkdf.https.worker.html [ Failure ] -
trunk/Source/WebCore/ChangeLog
r238089 r238090 1 2018-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 1 172 2018-11-12 Rob Buis <rbuis@igalia.com> 2 173 -
trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
r237009 r238090 924 924 m_markedCanvasDirty = true; 925 925 htmlCanvas()->clearCopiedImage(); 926 renderBox->contentChanged(Canvas Changed);926 renderBox->contentChanged(CanvasPixelsChanged); 927 927 } else { 928 928 if (!m_markedCanvasDirty) { -
trunk/Source/WebCore/page/FrameView.cpp
r238064 r238090 2410 2410 return; 2411 2411 2412 for (auto& renderer : *m_viewportConstrainedObjects) 2412 for (auto& renderer : *m_viewportConstrainedObjects) { 2413 2413 renderer->setNeedsLayout(); 2414 if (renderer->hasLayer()) { 2415 auto* layer = downcast<RenderBoxModelObject>(*renderer).layer(); 2416 layer->setNeedsCompositingGeometryUpdate(); 2417 } 2418 } 2414 2419 } 2415 2420 -
trunk/Source/WebCore/page/Page.cpp
r238049 r238090 880 880 881 881 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 } 884 887 885 888 document->resolveStyle(Document::ResolveStyleType::Rebuild); -
trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
r238070 r238090 2157 2157 } 2158 2158 2159 if (madeLayer) 2159 if (madeLayer) { 2160 2160 updateBackdropFiltersRect(); 2161 noteSublayersChanged(DontScheduleFlush); 2162 } 2161 2163 } 2162 2164 -
trunk/Source/WebCore/rendering/RenderBox.cpp
r238001 r238090 262 262 view().repaintRootContents(); 263 263 if (oldStyle->hasEntirelyFixedBackground() != newStyle.hasEntirelyFixedBackground()) 264 view().compositor().root FixedBackgroundsChanged();264 view().compositor().rootLayerConfigurationChanged(); 265 265 } 266 266 -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r238070 r238090 274 274 , m_zOrderListsDirty(false) 275 275 , m_normalFlowListDirty(true) 276 , m_hadNegativeZOrderList(false) 276 277 , m_inResizeMode(false) 277 278 , m_scrollDimensionsDirty(true) … … 287 288 , m_hasVisibleDescendant(false) 288 289 , m_registeredScrollableArea(false) 290 , m_isFixedIntersectingViewport(false) 289 291 , m_3DTransformedDescendantStatusDirty(true) 290 292 , m_has3DTransformedDescendant(false) … … 372 374 373 375 // 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()); 376 378 } 377 379 … … 404 406 setAncestorChainHasSelfPaintingLayerDescendant(); 405 407 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 406 417 #if ENABLE(CSS_COMPOSITING) 407 418 if (child.hasBlendMode() || (child.hasNotIsolatedBlendingDescendants() && !child.isolatesBlending())) … … 440 451 if (oldChild.isSelfPaintingLayer() || oldChild.hasSelfPaintingLayerDescendant()) 441 452 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); 453 454 if (compositor().inCompositingMode()) 455 setDescendantsNeedCompositingRequirementsTraversal(); 442 456 443 457 #if ENABLE(CSS_COMPOSITING) … … 553 567 bool RenderLayer::shouldBeStackingContext() const 554 568 { 555 // Non-auto z-index always implies stacking context here, because StyleResolver::adjustRenderStyle already adjusts z-index556 // based on positioning and other criteria.557 569 return !renderer().style().hasAutoZIndex() || isRenderViewLayer() || isForcedStackingContext(); 558 570 } … … 601 613 } 602 614 615 RenderLayer* 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 603 625 void RenderLayer::dirtyZOrderLists() 604 626 { 605 ASSERT( m_layerListMutationAllowed);627 ASSERT(layerListMutationAllowed()); 606 628 ASSERT(isStackingContext()); 607 629 … … 612 634 m_zOrderListsDirty = true; 613 635 614 if (!renderer().renderTreeBeingDestroyed()) 615 compositor().setCompositingLayersNeedRebuild(); 636 // FIXME: Ideally, we'd only dirty if the lists changed. 637 if (hasCompositingDescendant()) 638 setNeedsCompositingPaintOrderChildrenUpdate(); 616 639 } 617 640 … … 624 647 void RenderLayer::dirtyNormalFlowList() 625 648 { 626 ASSERT( m_layerListMutationAllowed);649 ASSERT(layerListMutationAllowed()); 627 650 628 651 if (m_normalFlowList) … … 630 653 m_normalFlowListDirty = true; 631 654 632 if ( !renderer().renderTreeBeingDestroyed())633 compositor().setCompositingLayersNeedRebuild();655 if (hasCompositingDescendant()) 656 setNeedsCompositingPaintOrderChildrenUpdate(); 634 657 } 635 658 … … 639 662 return; 640 663 641 ASSERT( m_layerListMutationAllowed);664 ASSERT(layerListMutationAllowed()); 642 665 643 666 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { … … 655 678 void RenderLayer::rebuildZOrderLists() 656 679 { 657 ASSERT( m_layerListMutationAllowed);680 ASSERT(layerListMutationAllowed()); 658 681 ASSERT(isDirtyStackingContext()); 659 682 rebuildZOrderLists(m_posZOrderList, m_negZOrderList); 660 683 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 } 661 694 } 662 695 … … 703 736 child->collectLayers(includeHiddenLayers, positiveZOrderList, negativeZOrderList); 704 737 } 738 } 739 } 740 741 void 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); 705 747 } 706 748 } … … 767 809 void RenderLayer::contentChanged(ContentChangeType changeType) 768 810 { 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); 774 818 } 775 819 … … 881 925 m_reflection->layout(); 882 926 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 888 927 if (renderer().isInFlowRenderFragmentedFlow()) { 889 928 updatePagination(); … … 900 939 child->updateLayerPositions(geometryMap, flags); 901 940 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 911 941 // With all our children positioned, now update our marquee if we need to. 912 942 if (m_marquee) { … … 917 947 m_updatingMarqueePosition = oldUpdatingMarqueePosition; 918 948 } 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)); 919 960 920 961 if (geometryMap) … … 1141 1182 } 1142 1183 1143 if (had3DTransform != has3DTransform()) 1184 if (had3DTransform != has3DTransform()) { 1144 1185 dirty3DTransformedDescendantStatus(); 1186 // Having a 3D transform affects whether enclosing perspective and preserve-3d layers composite, so trigger an update. 1187 setNeedsPostLayoutCompositingUpdateOnAncestors(); 1188 } 1145 1189 } 1146 1190 … … 1524 1568 positionOrOffsetChanged |= location() != localPoint; 1525 1569 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 1526 1580 return positionOrOffsetChanged; 1527 1581 } … … 1570 1624 } 1571 1625 1572 RenderLayer* RenderLayer::stackingContext() const1573 {1574 RenderLayer* layer = parent();1575 while (layer && !layer->isStackingContext())1576 layer = layer->parent();1577 1578 ASSERT(!layer || layer->isStackingContext());1579 return layer;1580 }1581 1582 1626 static inline bool isContainerForPositioned(RenderLayer& layer, PositionType position) 1583 1627 { … … 1660 1704 1661 1705 return curr; 1662 }1663 1664 static inline const RenderLayer* compositingContainer(const RenderLayer& layer)1665 {1666 return layer.isNormalFlowOnly() ? layer.parent() : layer.stackingContext();1667 1706 } 1668 1707 … … 1688 1727 return const_cast<RenderLayer*>(this); 1689 1728 1690 for (const RenderLayer* curr = compositingContainer(*this); curr; curr = compositingContainer(*curr)) {1729 for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) { 1691 1730 if (curr->isComposited()) 1692 1731 return const_cast<RenderLayer*>(curr); … … 1701 1740 return const_cast<RenderLayer*>(this); 1702 1741 1703 for (const RenderLayer* curr = compositingContainer(*this); curr; curr = compositingContainer(*curr)) {1742 for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) { 1704 1743 if (compositedWithOwnBackingStore(*curr)) 1705 1744 return const_cast<RenderLayer*>(curr); … … 1790 1829 return const_cast<RenderLayer*>(current); 1791 1830 1792 current = c ompositingContainer(*current);1831 current = current->paintOrderParent(); 1793 1832 ASSERT(current); 1794 1833 if (current->transform() || compositedWithOwnBackingStore(*current)) … … 2328 2367 if (m_scrollPosition == newPosition) { 2329 2368 #if PLATFORM(IOS_FAMILY) 2330 if (m_requiresScrollBoundsOriginUpdate) 2369 if (m_requiresScrollBoundsOriginUpdate) { 2370 setNeedsCompositingGeometryUpdate(); 2331 2371 updateCompositingLayersAfterScroll(); 2372 } 2332 2373 #endif 2333 2374 return; … … 2354 2395 // in this case we're still updating their positions; we'll update compositing layers later 2355 2396 // when that completes. 2397 if (usesCompositedScrolling()) { 2398 setNeedsCompositingGeometryUpdate(); 2399 setDescendantsNeedUpdateBackingAndHierarchyTraversal(); 2400 } 2401 2356 2402 updateCompositingLayersAfterScroll(); 2357 2403 } … … 2376 2422 2377 2423 bool requiresRepaint = true; 2378 if (compositor().inCompositingMode() && usesCompositedScrolling()) 2424 if (compositor().inCompositingMode() && usesCompositedScrolling()) { 2425 setNeedsCompositingGeometryUpdate(); 2426 setDescendantsNeedUpdateBackingAndHierarchyTraversal(); 2379 2427 requiresRepaint = false; 2428 } 2380 2429 2381 2430 // Just schedule a full repaint of our object. … … 2529 2578 if (usesCompositedScrolling()) 2530 2579 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(); 2532 2583 compositor().updateCompositingLayers(CompositingUpdateType::OnScroll, compositingAncestor); 2584 } 2533 2585 } 2534 2586 } … … 3519 3571 scrollToOffsetWithoutAnimation(IntPoint(scrollOffset())); 3520 3572 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(); 3525 3575 3526 3576 updateScrollSnapState(); … … 4200 4250 return; 4201 4251 4202 // Ensure our lists are up-to-date.4203 4252 updateLayerListsIfNeeded(); 4204 4253 … … 4793 4842 ASSERT(!renderer().view().needsLayout()); 4794 4843 4795 updateLayerListsIfNeeded();4796 4797 4844 ASSERT(!isRenderFragmentedFlow()); 4798 4845 LayoutRect hitTestArea = renderer().view().documentRect(); … … 4937 4984 const HitTestingTransformState* transformState, double* zOffset) 4938 4985 { 4986 updateLayerListsIfNeeded(); 4987 4939 4988 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) 4940 4989 return nullptr; … … 4960 5009 4961 5010 // Ensure our lists and 3d status are up-to-date. 4962 updateCompositingAndLayerListsIfNeeded();4963 5011 update3DTransformedDescendantStatus(); 4964 5012 … … 5729 5777 } 5730 5778 5779 LayoutRect RenderLayer::overlapBounds() const 5780 { 5781 if (overlapBoundsIncludeChildren()) 5782 return calculateLayerBounds(this, { }, defaultCalculateLayerBoundsFlags() | IncludeFilterOutsets); 5783 5784 return localBoundingBox(); 5785 } 5786 5731 5787 LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutSize& offsetFromRoot, OptionSet<CalculateLayerBoundsFlag> flags) const 5732 5788 { … … 5810 5866 computeLayersUnion(*childLayer); 5811 5867 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())) 5816 5869 renderer().style().filterOutsets().expandRect(unionBounds); 5817 5870 … … 5958 6011 // This function should not be called when layer-lists are dirty. 5959 6012 // It is somehow getting triggered during style update. 5960 if ( m_zOrderListsDirty || m_normalFlowListDirty)6013 if (zOrderListsDirty() || normalFlowListDirty()) 5961 6014 return false; 5962 6015 … … 6000 6053 } 6001 6054 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();6013 6055 } 6014 6056 … … 6585 6627 { 6586 6628 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"; 6589 6634 stream.nextLine(); 6590 6635 } … … 6603 6648 stream << (layer.renderer().hasOverflowClip() ? "O" : "-"); 6604 6649 stream << (layer.isTransparent() ? "A" : "-"); 6650 stream << (layer.hasBlendMode() ? "B" : "-"); 6651 stream << (layer.isolatesBlending() ? "I" : "-"); 6605 6652 stream << (layer.renderer().hasTransformRelatedProperty() ? "T" : "-"); 6606 6653 stream << (layer.hasFilter() ? "F" : "-"); … … 6613 6660 stream << (layer.normalFlowListDirty() ? "n" : "-"); 6614 6661 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 6615 6681 outputIdent(stream, depth); 6616 6682 -
trunk/Source/WebCore/rendering/RenderLayer.h
r237266 r238090 179 179 RenderLayer* enclosingStackingContext() { return isStackingContext() ? this : stackingContext(); } 180 180 181 RenderLayer* paintOrderParent() const; 182 181 183 void dirtyNormalFlowList(); 182 184 void dirtyZOrderLists(); … … 185 187 bool normalFlowListDirty() const { return m_normalFlowListDirty; } 186 188 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 195 private: 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 238 public: 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 = { }; } 187 298 188 299 class LayerList { … … 244 355 // Update our normal and z-index lists. 245 356 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 } 246 366 247 367 void repaintIncludingDescendants(); … … 275 395 276 396 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. 278 398 279 399 LayoutRect rect() const { return LayoutRect(location(), size()); } … … 385 505 CheckForRepaint = 1 << 0, 386 506 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, 392 510 }; 393 static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint , IsCompositingUpdateRoot, UpdateCompositingLayers}; }511 static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint }; } 394 512 395 513 void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, OptionSet<UpdateLayerPositionsFlag>); … … 570 688 IncludeSelfTransform = 1 << 0, 571 689 UseLocalClipRectIfPossible = 1 << 1, 572 Include LayerFilterOutsets= 1 << 2,573 ExcludeHiddenDescendants= 1 << 3,574 DontConstrainForMask= 1 << 4,575 IncludeCompositedDescendants= 1 << 5,576 UseFragmentBoxesExcludingCompositing= 1 << 6,577 UseFragmentBoxes IncludingCompositing = 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, 579 697 }; 580 static constexpr OptionSet<CalculateLayerBoundsFlag> defaultCalculateLayerBoundsFlags() { return { IncludeSelfTransform, UseLocalClipRectIfPossible, Include LayerFilterOutsets, UseFragmentBoxesExcludingCompositing }; }698 static constexpr OptionSet<CalculateLayerBoundsFlag> defaultCalculateLayerBoundsFlags() { return { IncludeSelfTransform, UseLocalClipRectIfPossible, IncludePaintedFilterOutsets, UseFragmentBoxesExcludingCompositing }; } 581 699 582 700 // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known. … … 590 708 591 709 // Bounds used for layer overlap testing in RenderLayerCompositor. 592 LayoutRect overlapBounds() const { return overlapBoundsIncludeChildren() ? calculateLayerBounds(this, LayoutSize()) : localBoundingBox(); }710 LayoutRect overlapBounds() const; 593 711 594 712 // Takes transform animations into account, returning true if they could be cheaply computed. … … 709 827 bool requiresFullLayerImageForFilters() const; 710 828 711 #if !ASSERT_DISABLED712 bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }713 void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }714 #endif715 716 829 Element* enclosingElement() const; 717 830 … … 732 845 { 733 846 ASSERT(isRenderFragmentedFlow()); 734 return m_zOrderListsDirty || m_normalFlowListDirty;847 return zOrderListsDirty() || normalFlowListDirty(); 735 848 } 736 849 … … 797 910 ClipRects* clipRects(const ClipRectsContext&) const; 798 911 799 800 912 void setAncestorChainHasSelfPaintingLayerDescendant(); 801 913 void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); … … 835 947 836 948 LayoutPoint renderBoxLocation() const { return is<RenderBox>(renderer()) ? downcast<RenderBox>(renderer()).location() : LayoutPoint(); } 837 838 void updateCompositingAndLayerListsIfNeeded();839 949 840 950 bool setupFontSubpixelQuantization(GraphicsContext&, bool& didQuantizeFonts); … … 958 1068 void setAncestorChainHasVisibleDescendant(); 959 1069 960 void updateDescendantDependentFlags();961 962 1070 bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; } 963 1071 … … 1037 1145 bool overflowControlsIntersectRect(const IntRect& localRect) const; 1038 1146 1039 // The bitfields are up here so they will fall into the padding from ScrollableArea on 64-bit.1147 OptionSet<Compositing> m_compositingDirtyBits; 1040 1148 1041 1149 const bool m_isRenderViewLayer : 1; … … 1047 1155 bool m_zOrderListsDirty : 1; 1048 1156 bool m_normalFlowListDirty: 1; 1157 bool m_hadNegativeZOrderList : 1; 1049 1158 1050 1159 // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop. … … 1071 1180 bool m_hasVisibleDescendant : 1; 1072 1181 bool m_registeredScrollableArea : 1; 1182 bool m_isFixedIntersectingViewport : 1; 1073 1183 1074 1184 bool m_3DTransformedDescendantStatusDirty : 1; … … 1176 1286 { 1177 1287 ASSERT(!isStackingContext()); 1178 ASSERT( m_layerListMutationAllowed);1288 ASSERT(layerListMutationAllowed()); 1179 1289 1180 1290 m_posZOrderList = nullptr; … … 1194 1304 1195 1305 rebuildZOrderLists(); 1306 } 1307 1308 inline RenderLayer* RenderLayer::paintOrderParent() const 1309 { 1310 return m_isNormalFlowOnly ? m_parent : stackingContext(); 1196 1311 } 1197 1312 -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r238070 r238090 592 592 } 593 593 594 voidRenderLayerBacking::updateCompositedBounds()594 bool RenderLayerBacking::updateCompositedBounds() 595 595 { 596 596 LayoutRect layerBounds = m_owningLayer.calculateLayerBounds(&m_owningLayer, LayoutSize(), RenderLayer::defaultCalculateLayerBoundsFlags() | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask); … … 627 627 m_artificiallyInflatedBounds = false; 628 628 629 setCompositedBounds(layerBounds);629 return setCompositedBounds(layerBounds); 630 630 } 631 631 … … 634 634 if (!is<RenderWidget>(renderer())) 635 635 return; 636 636 637 if (auto* innerCompositor = RenderLayerCompositor::frameContentsCompositor(&downcast<RenderWidget>(renderer()))) { 637 638 innerCompositor->frameViewDidChangeSize(); … … 640 641 } 641 642 642 void RenderLayerBacking::updateAfterLayout( OptionSet<UpdateAfterLayoutFlags> flags)643 void RenderLayerBacking::updateAfterLayout(bool needsFullRepaint) 643 644 { 644 645 LOG(Compositing, "RenderLayerBacking %p updateAfterLayout (layer %p)", this, &m_owningLayer); 645 646 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()) 668 657 setContentsNeedDisplay(); 669 658 } 670 659 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. 661 void RenderLayerBacking::updateConfigurationAfterStyleChange() 662 { 716 663 updateMaskingLayer(renderer().hasMask(), renderer().hasClipPath()); 717 718 updateChildClippingStrategy(needsDescendantsClippingLayer);719 664 720 665 if (m_owningLayer.hasReflection()) { … … 726 671 m_graphicsLayer->setReplicatedByLayer(nullptr); 727 672 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 687 bool 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 728 745 PaintedContentsInfo contentsInfo(*this); 729 746 747 // Requires layout. 730 748 if (!m_owningLayer.isRenderViewLayer()) { 731 749 bool didUpdateContentsRect = false; … … 734 752 updateRootLayerConfiguration(); 735 753 754 // Requires layout. 736 755 if (contentsInfo.isDirectlyCompositedImage()) 737 756 updateImageContents(contentsInfo); … … 753 772 auto* mediaElement = downcast<HTMLMediaElement>(renderer().element()); 754 773 m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer(), GraphicsLayer::ContentsLayerPurpose::Media); 774 // Requires layout. 755 775 resetContentsRect(); 756 776 } … … 761 781 if (auto* context = canvas->renderingContext()) 762 782 m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer(), GraphicsLayer::ContentsLayerPurpose::Canvas); 783 763 784 layerConfigChanged = true; 764 785 } 765 786 #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 } 768 791 769 792 return layerConfigChanged; … … 895 918 } 896 919 920 // FIXME: See if we need this now that updateGeometry() is always called in post-order traversal. 897 921 LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const 898 922 { … … 945 969 void RenderLayerBacking::updateGeometry() 946 970 { 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()); 950 975 951 976 const RenderStyle& style = renderer().style(); … … 979 1004 updateBlendMode(style); 980 1005 #endif 981 m_owningLayer.updateDescendantDependentFlags();982 1006 983 1007 // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959 … … 1020 1044 } 1021 1045 1022 // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordi date system which is not necessarily1046 // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordinate system which is not necessarily 1023 1047 // the same as the ancestor graphics layer. 1024 1048 OffsetFromRenderer primaryGraphicsLayerOffsetFromRenderer; … … 1442 1466 void RenderLayerBacking::setRequiresBackgroundLayer(bool requiresBackgroundLayer) 1443 1467 { 1468 if (requiresBackgroundLayer == m_requiresBackgroundLayer) 1469 return; 1470 1444 1471 m_requiresBackgroundLayer = requiresBackgroundLayer; 1472 m_owningLayer.setNeedsCompositingConfigurationUpdate(); 1445 1473 } 1446 1474 … … 1655 1683 layerChanged = true; 1656 1684 m_graphicsLayer->setMaskLayer(m_maskLayer.copyRef()); 1685 // We need a geometry update to size the new mask layer. 1686 m_owningLayer.setNeedsCompositingGeometryUpdate(); 1657 1687 } 1658 1688 } else if (m_maskLayer) { … … 1986 2016 bool RenderLayerBacking::paintsContent(RenderLayer::PaintedContentRequest& request) const 1987 2017 { 2018 m_owningLayer.updateDescendantDependentFlags(); 2019 1988 2020 bool paintsContent = false; 1989 2021 … … 2217 2249 2218 2250 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(); 2226 2255 2227 2256 #if ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS) … … 2394 2423 ASSERT(!paintsIntoCompositedAncestor()); 2395 2424 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 2396 2429 auto& frameView = renderer().view().frameView(); 2397 2430 if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints()) … … 2427 2460 { 2428 2461 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(); 2429 2466 2430 2467 FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor()); … … 2772 2809 #endif 2773 2810 2811 if (didAnimate) 2812 m_owningLayer.setNeedsPostLayoutCompositingUpdate(); 2813 2774 2814 return didAnimate; 2775 2815 } … … 2788 2828 { 2789 2829 m_graphicsLayer->removeAnimation(animationName); 2830 m_owningLayer.setNeedsPostLayoutCompositingUpdate(); 2790 2831 } 2791 2832 … … 2855 2896 #endif 2856 2897 2898 if (didAnimate) 2899 m_owningLayer.setNeedsPostLayoutCompositingUpdate(); 2900 2857 2901 return didAnimate; 2858 2902 } … … 2868 2912 { 2869 2913 AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property); 2870 if (animatedProperty != AnimatedPropertyInvalid) 2914 if (animatedProperty != AnimatedPropertyInvalid) { 2871 2915 m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty)); 2916 m_owningLayer.setNeedsPostLayoutCompositingUpdate(); 2917 } 2872 2918 } 2873 2919 … … 2905 2951 } 2906 2952 2907 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds) 2908 { 2953 bool RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds) 2954 { 2955 if (bounds == m_compositedBounds) 2956 return false; 2957 2909 2958 m_compositedBounds = bounds; 2959 return true; 2910 2960 } 2911 2961 -
trunk/Source/WebCore/rendering/RenderLayerBacking.h
r237266 r238090 66 66 RenderLayer& owningLayer() const { return m_owningLayer; } 67 67 68 enum class UpdateAfterLayoutFlags { 69 NeedsFullRepaint = 1 << 0, 70 IsUpdateRoot = 1 << 1 71 }; 72 void updateAfterLayout(OptionSet<UpdateAfterLayoutFlags>); 73 68 void updateConfigurationAfterStyleChange(); 69 74 70 // Returns true if layer configuration changed. 75 71 bool updateConfiguration(); … … 83 79 // Update contents and clipping structure. 84 80 void updateDrawsContent(); 81 82 void updateAfterLayout(bool needsFullRepaint); 85 83 86 84 GraphicsLayer* graphicsLayer() const { return m_graphicsLayer.get(); } … … 178 176 179 177 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(); 182 182 183 183 void updateAfterWidgetResize(); -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r238070 r238090 221 221 CompositingState(RenderLayer* compAncestor, bool testOverlap = true) 222 222 : compositingAncestor(compAncestor) 223 , subtreeIsCompositing(false)224 223 , testingOverlap(testOverlap) 225 , ancestorHasTransformAnimation(false)226 #if ENABLE(CSS_COMPOSITING)227 , hasNotIsolatedCompositedBlendingDescendants(false)228 #endif229 #if ENABLE(TREE_DEBUGGING)230 , depth(0)231 #endif232 224 { 233 225 } … … 237 229 , subtreeIsCompositing(other.subtreeIsCompositing) 238 230 , testingOverlap(other.testingOverlap) 231 , fullPaintOrderTraversalRequired(other.fullPaintOrderTraversalRequired) 232 , descendantsRequireCompositingUpdate(other.descendantsRequireCompositingUpdate) 239 233 , ancestorHasTransformAnimation(other.ancestorHasTransformAnimation) 240 234 #if ENABLE(CSS_COMPOSITING) … … 248 242 249 243 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 }; 253 249 #if ENABLE(CSS_COMPOSITING) 254 bool hasNotIsolatedCompositedBlendingDescendants ;250 bool hasNotIsolatedCompositedBlendingDescendants { false }; 255 251 #endif 256 252 #if ENABLE(TREE_DEBUGGING) 257 int depth ;253 int depth { 0 }; 258 254 #endif 259 255 }; … … 300 296 } else 301 297 destroyRootLayer(); 298 299 300 m_renderView.layer()->setNeedsPostLayoutCompositingUpdate(); 302 301 } 303 302 } … … 326 325 327 326 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 } 330 331 } 331 332 … … 350 351 351 352 if (updateCompositingPolicy()) 352 setCompositingLayersNeedRebuild();353 rootRenderLayer().setDescendantsNeedCompositingRequirementsTraversal(); 353 354 } 354 355 … … 360 361 return; 361 362 362 bool forceCompositingMode = m_hasAcceleratedCompositing && m_renderView.settings().forceCompositingMode() && requiresCompositingForScrollableFrame(); 363 RequiresCompositingData queryData; 364 bool forceCompositingMode = m_hasAcceleratedCompositing && m_renderView.settings().forceCompositingMode() && requiresCompositingForScrollableFrame(queryData); 363 365 if (forceCompositingMode != m_forceCompositingMode) { 364 366 m_forceCompositingMode = forceCompositingMode; 365 setCompositingLayersNeedRebuild();367 rootRenderLayer().setDescendantsNeedCompositingRequirementsTraversal(); 366 368 } 367 369 } … … 388 390 } 389 391 390 void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)391 {392 if (inCompositingMode())393 m_compositingLayersNeedRebuild = needRebuild;394 }395 396 392 void RenderLayerCompositor::willRecalcStyle() 397 393 { 398 m_layerNeedsCompositingUpdate = false;399 394 cacheAcceleratedCompositingFlags(); 400 395 } … … 402 397 bool RenderLayerCompositor::didRecalcStyleWithNoPendingLayout() 403 398 { 404 if (!m_layerNeedsCompositingUpdate)405 return false;406 407 399 return updateCompositingLayers(CompositingUpdateType::AfterStyleChange); 408 400 } … … 652 644 } 653 645 646 // Returns true on a successful update. 654 647 bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot) 655 648 { 656 649 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 657 655 658 656 if (updateType == CompositingUpdateType::AfterStyleChange || updateType == CompositingUpdateType::AfterLayout) … … 668 666 669 667 // 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. 670 669 if (m_renderView.needsLayout()) 671 670 return false; … … 674 673 enableCompositingMode(true); 675 674 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; 679 693 ++m_compositingUpdateCount; 680 694 … … 682 696 683 697 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);717 698 718 699 #if !LOG_DISABLED … … 722 703 startTime = MonotonicTime::now(); 723 704 } 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()) { 739 707 m_obligateCompositedLayerCount = 0; 740 708 m_secondaryCompositedLayerCount = 0; … … 748 716 #endif 749 717 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()) { 752 734 Vector<Ref<GraphicsLayer>> childList; 753 rebuildCompositingLayerTree(*updateRoot, childList, 0);735 updateBackingAndHierarchy(*updateRoot, childList); 754 736 755 737 // Host the document layer in the RenderView's root layer. … … 763 745 m_rootContentLayer->setChildren(WTFMove(childList)); 764 746 } 765 747 766 748 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 775 751 #if !LOG_DISABLED 776 if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {752 if (compositingLogEnabled()) { 777 753 MonotonicTime endTime = MonotonicTime::now(); 778 754 LOG(Compositing, "Total layers primary secondary obligatory backing (KB) secondary backing(KB) total backing (KB) update time (ms)\n"); … … 783 759 } 784 760 #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 779 void 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) 788 971 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. 1007 void 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 1115 void 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(); 794 1226 } 795 1227 … … 813 1245 814 1246 #if !LOG_DISABLED 815 void RenderLayerCompositor::logLayerInfo(const RenderLayer& layer, int depth)1247 void RenderLayerCompositor::logLayerInfo(const RenderLayer& layer, const char* phase, int depth) 816 1248 { 817 1249 if (!compositingLogEnabled()) … … 819 1251 820 1252 auto* backing = layer.backing(); 821 if (requiresCompositingLayer(layer) || layer.isRenderViewLayer()) { 1253 RequiresCompositingData queryData; 1254 if (requiresCompositingLayer(layer, queryData) || layer.isRenderViewLayer()) { 822 1255 ++m_obligateCompositedLayerCount; 823 1256 m_obligatoryBackingStoreBytes += backing->backingStoreMemoryEstimate(); … … 883 1316 logString.append(layer.name()); 884 1317 1318 logString.appendLiteral(" - "); 1319 logString.append(phase); 1320 885 1321 LOG(Compositing, "%s", logString.toString().utf8().data()); 886 1322 } 887 1323 #endif 888 1324 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; 1325 static 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 1331 static bool styleAffectsLayerGeometry(const RenderStyle& style) 1332 { 1333 return style.hasClip() || style.clipPath() || style.hasBorderRadius(); 949 1334 } 950 1335 … … 954 1339 return; 955 1340 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 } 973 1412 } 974 1413 … … 988 1427 989 1428 // 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)) 991 1430 return true; 992 1431 … … 1006 1445 } 1007 1446 1447 // FIXME: remove and never ask questions about reflection layers. 1008 1448 static RenderLayerModelObject& rendererForCompositingTests(const RenderLayer& layer) 1009 1449 { … … 1022 1462 } 1023 1463 1024 bool RenderLayerCompositor::updateBacking(RenderLayer& layer, CompositingChangeRepaint shouldRepaint, BackingRequired backingRequired)1464 bool RenderLayerCompositor::updateBacking(RenderLayer& layer, RequiresCompositingData& queryData, CompositingChangeRepaint shouldRepaint, BackingRequired backingRequired) 1025 1465 { 1026 1466 bool layerChanged = false; 1027 RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;1028 1029 1467 if (backingRequired == BackingRequired::Unknown) 1030 backingRequired = needsToBeComposited(layer, &viewportConstrainedNotCompositedReason) ? BackingRequired::Yes : BackingRequired::No;1468 backingRequired = needsToBeComposited(layer, queryData) ? BackingRequired::Yes : BackingRequired::No; 1031 1469 else { 1032 1470 // 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); 1034 1472 } 1035 1473 … … 1062 1500 if (layer.parent()) 1063 1501 layer.computeRepaintRectsIncludingDescendants(); 1502 1503 layer.setNeedsCompositingGeometryUpdate(); 1504 layer.setNeedsCompositingConfigurationUpdate(); 1505 layer.setNeedsCompositingPaintOrderChildrenUpdate(); 1064 1506 1065 1507 layerChanged = true; … … 1112 1554 // the scrolling coordinator needs to recalculate whether it can do fast scrolling. 1113 1555 if (layer.renderer().isFixedPositioned()) { 1114 if (layer.viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {1115 layer.setViewportConstrainedNotCompositedReason( viewportConstrainedNotCompositedReason);1556 if (layer.viewportConstrainedNotCompositedReason() != queryData.nonCompositedForPositionReason) { 1557 layer.setViewportConstrainedNotCompositedReason(queryData.nonCompositedForPositionReason); 1116 1558 layerChanged = true; 1117 1559 } … … 1129 1571 } 1130 1572 1131 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer& layer, CompositingChangeRepaint shouldRepaint)1132 { 1133 bool layerChanged = updateBacking(layer, shouldRepaint);1573 bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer& layer, RequiresCompositingData& queryData, CompositingChangeRepaint shouldRepaint) 1574 { 1575 bool layerChanged = updateBacking(layer, queryData, shouldRepaint); 1134 1576 1135 1577 // See if we need content or clipping layers. Methods called here should assume … … 1178 1620 } 1179 1621 1622 // FIXME: remove. 1180 1623 void RenderLayerCompositor::layerWasAdded(RenderLayer&, RenderLayer&) 1181 1624 { 1182 setCompositingLayersNeedRebuild();1183 1625 } 1184 1626 … … 1189 1631 1190 1632 removeFromScrollCoordinatedLayers(child); 1191 repaintInCompositedAncestor(child, child.backing()->compositedBounds()); 1633 repaintInCompositedAncestor(child, child.backing()->compositedBounds()); // FIXME: do via dirty bits? 1192 1634 1193 1635 setCompositingParent(child, nullptr); 1194 setCompositingLayersNeedRebuild();1636 child.setNeedsCompositingLayerConnection(); 1195 1637 } 1196 1638 … … 1280 1722 if (ancestorLayer) 1281 1723 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 must1287 // 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 itself1290 // 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 flag1299 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 map1317 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 have1325 // RenderLayer children and whose children can't use its backing to render1326 // into. These children (the controls) always need to be promoted into their1327 // own layers to draw on top of the accelerated video.1328 if (compositingState.compositingAncestor && compositingState.compositingAncestor->renderer().isVideo())1329 compositingReason = RenderLayer::IndirectCompositingReason::Overlap;1330 #endif1331 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 is1340 // a compositing layer among them, so start by inheriting the compositing1341 // ancestor with subtreeIsCompositing set to false.1342 CompositingState childState(compositingState);1343 childState.subtreeIsCompositing = false;1344 #if ENABLE(CSS_COMPOSITING)1345 childState.hasNotIsolatedCompositedBlendingDescendants = false;1346 #endif1347 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 an1356 // 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_DISABLED1366 LayerListMutationDetector mutationChecker(layer);1367 #endif1368 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 layer1375 // (since we need to ensure that the -ve z-order child renders underneath our contents).1376 if (!willBeComposited && childState.subtreeIsCompositing) {1377 // make layer compositing1378 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 an1382 // animation running behind this layer, meaning they can rely on the overlap map testing again1383 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 to1403 // the overlap map. Layers that do not composite will draw into their1404 // 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 bounds1406 // 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 #endif1414 // 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 because1443 // 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 #endif1461 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 need1466 // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode1467 // 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 #endif1474 }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);1488 1724 } 1489 1725 … … 1525 1761 #endif 1526 1762 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 layers1531 // 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 now1536 // 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_DISABLED1553 logLayerInfo(layer, depth);1554 #else1555 UNUSED_PARAM(depth);1556 #endif1557 }1558 1559 // If this layer has backing, then we are collecting its children, otherwise appending1560 // to the compositing child list of an enclosing layer.1561 Vector<Ref<GraphicsLayer>> layerChildren;1562 auto& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;1563 1564 #if !ASSERT_DISABLED1565 LayerListMutationDetector mutationChecker(layer);1566 #endif1567 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 1611 1763 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset) 1612 1764 { … … 1689 1841 } 1690 1842 1691 void RenderLayerCompositor::root FixedBackgroundsChanged()1843 void RenderLayerCompositor::rootLayerConfigurationChanged() 1692 1844 { 1693 1845 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 } 1696 1850 } 1697 1851 … … 1781 1935 hostingLayer->addChild(*rootLayer); 1782 1936 } 1937 // FIXME: Why always return true and not just when the layers changed? 1783 1938 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 now1791 // 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_DISABLED1806 logLayerInfo(layer, depth);1807 #else1808 UNUSED_PARAM(depth);1809 #endif1810 }1811 1812 #if !ASSERT_DISABLED1813 LayerListMutationDetector mutationChecker(layer);1814 #endif1815 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_DISABLED1854 LayerListMutationDetector mutationChecker(layer);1855 #endif1856 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 }1870 1939 } 1871 1940 … … 1973 2042 1974 2043 #if ENABLE(RUBBER_BANDING) 1975 if (m_contentShadowLayer ) {2044 if (m_contentShadowLayer && m_rootContentLayer) { 1976 2045 m_contentShadowLayer->setPosition(m_rootContentLayer->position()); 1977 2046 m_contentShadowLayer->setSize(m_rootContentLayer->size()); … … 1990 2059 } 1991 2060 1992 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer& layer, Re nderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const2061 bool RenderLayerCompositor::needsToBeComposited(const RenderLayer& layer, RequiresCompositingData& queryData) const 1993 2062 { 1994 2063 if (!canBeComposited(layer)) 1995 2064 return false; 1996 2065 1997 return requiresCompositingLayer(layer, viewportConstrainedNotCompositedReason) || layer.mustCompositeForIndirectReasons() || (inCompositingMode() && layer.isRenderViewLayer());2066 return requiresCompositingLayer(layer, queryData) || layer.mustCompositeForIndirectReasons() || (inCompositingMode() && layer.isRenderViewLayer()); 1998 2067 } 1999 2068 2000 2069 // Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. 2001 2070 // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. 2002 // static2003 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, Re nderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const2071 // FIXME: is clipsCompositingDescendants() an intrinsic reason? 2072 bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, RequiresCompositingData& queryData) const 2004 2073 { 2005 2074 auto& renderer = rendererForCompositingTests(layer); … … 2009 2078 || requiresCompositingForAnimation(renderer) 2010 2079 || clipsCompositingDescendants(*renderer.layer()) 2011 || requiresCompositingForPosition(renderer, *renderer.layer(), viewportConstrainedNotCompositedReason)2080 || requiresCompositingForPosition(renderer, *renderer.layer(), queryData) 2012 2081 || requiresCompositingForCanvas(renderer) 2013 2082 || requiresCompositingForFilters(renderer) … … 2015 2084 || requiresCompositingForBackfaceVisibility(renderer) 2016 2085 || 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); 2020 2089 } 2021 2090 … … 2065 2134 return true; 2066 2135 2136 RequiresCompositingData queryData; 2067 2137 if (layer.isRenderViewLayer() 2068 2138 || layer.transform() // note: excludes perspective and transformStyle3D. 2069 2139 || requiresCompositingForAnimation(renderer) 2070 || requiresCompositingForPosition(renderer, layer )2140 || requiresCompositingForPosition(renderer, layer, queryData) 2071 2141 || requiresCompositingForCanvas(renderer) 2072 2142 || requiresCompositingForFilters(renderer) … … 2074 2144 || requiresCompositingForBackfaceVisibility(renderer) 2075 2145 || requiresCompositingForVideo(renderer) 2076 || requiresCompositingForFrame(renderer )2077 || requiresCompositingForPlugin(renderer )2078 || requiresCompositingForOverflowScrolling(layer )2146 || requiresCompositingForFrame(renderer, queryData) 2147 || requiresCompositingForPlugin(renderer, queryData) 2148 || requiresCompositingForOverflowScrolling(layer, queryData) 2079 2149 || renderer.isTransparent() 2080 2150 || renderer.hasMask() … … 2106 2176 return reasons; 2107 2177 2178 RequiresCompositingData queryData; 2179 2108 2180 auto& renderer = rendererForCompositingTests(layer); 2109 2181 … … 2115 2187 else if (requiresCompositingForCanvas(renderer)) 2116 2188 reasons.add(CompositingReason::Canvas); 2117 else if (requiresCompositingForPlugin(renderer ))2189 else if (requiresCompositingForPlugin(renderer, queryData)) 2118 2190 reasons.add(CompositingReason::Plugin); 2119 else if (requiresCompositingForFrame(renderer ))2191 else if (requiresCompositingForFrame(renderer, queryData)) 2120 2192 reasons.add(CompositingReason::IFrame); 2121 2193 … … 2135 2207 reasons.add(CompositingReason::WillChange); 2136 2208 2137 if (requiresCompositingForPosition(renderer, *renderer.layer() ))2209 if (requiresCompositingForPosition(renderer, *renderer.layer(), queryData)) 2138 2210 reasons.add(renderer.isFixedPositioned() ? CompositingReason::PositionFixed : CompositingReason::PositionSticky); 2139 2211 2140 if (requiresCompositingForOverflowScrolling(*renderer.layer() ))2212 if (requiresCompositingForOverflowScrolling(*renderer.layer(), queryData)) 2141 2213 reasons.add(CompositingReason::OverflowScrollingTouch); 2142 2214 … … 2282 2354 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy, 2283 2355 // but a sibling in the z-order hierarchy. 2356 // FIXME: can we do this without a tree walk? 2284 2357 bool RenderLayerCompositor::clippedByAncestor(RenderLayer& layer) const 2285 2358 { 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. 2289 2364 auto* compositingAncestor = layer.ancestorCompositingLayer(); 2290 2365 if (!compositingAncestor) … … 2324 2399 } 2325 2400 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(); 2401 bool 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); 2342 2425 } 2343 2426 … … 2359 2442 if (renderer.style().transform().has3DOperation() && renderer.hasFilter()) 2360 2443 return true; 2361 return !renderer.style().transform().isRepresentableIn2D();2444 return renderer.style().transform().isRepresentableIn2D() ? false : true; 2362 2445 } 2363 2446 return false; … … 2393 2476 2394 2477 auto& video = downcast<RenderVideo>(renderer); 2395 return (video.requiresImmediateCompositing() || video.shouldDisplayVideo()) && canAccelerateVideoRendering(video); 2478 if ((video.requiresImmediateCompositing() || video.shouldDisplayVideo()) && canAccelerateVideoRendering(video)) 2479 return true; 2396 2480 #else 2397 2481 UNUSED_PARAM(renderer); 2482 #endif 2398 2483 return false; 2399 #endif2400 2484 } 2401 2485 … … 2425 2509 } 2426 2510 2427 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderLayerModelObject& renderer) const 2511 bool 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 2524 bool 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 2544 bool RenderLayerCompositor::requiresCompositingForPlugin(RenderLayerModelObject& renderer, RequiresCompositingData& queryData) const 2428 2545 { 2429 2546 if (!(m_compositingTriggers & ChromeClient::PluginTrigger)) … … 2434 2551 return false; 2435 2552 2436 m_reevaluateCompositingAfterLayout = true;2437 2438 2553 auto& pluginRenderer = downcast<RenderWidget>(renderer); 2439 2554 if (pluginRenderer.style().visibility() != Visibility::Visible) … … 2441 2556 2442 2557 // 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; 2444 2560 return pluginRenderer.isComposited(); 2561 } 2445 2562 2446 2563 // Don't go into compositing mode if height or width are zero, or size is 1x1. 2447 2564 IntRect contentBox = snappedIntRect(pluginRenderer.contentBoxRect()); 2448 return contentBox.height() * contentBox.width() > 1;2449 } 2450 2451 bool RenderLayerCompositor::requiresCompositingForFrame(RenderLayerModelObject& renderer ) const2565 return (contentBox.height() * contentBox.width() > 1); 2566 } 2567 2568 bool RenderLayerCompositor::requiresCompositingForFrame(RenderLayerModelObject& renderer, RequiresCompositingData& queryData) const 2452 2569 { 2453 2570 if (!is<RenderWidget>(renderer)) … … 2461 2578 return false; 2462 2579 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; 2467 2582 return frameRenderer.isComposited(); 2468 2583 } 2584 2469 2585 // Don't go into compositing mode if height or width are zero. 2470 2586 return !snappedIntRect(frameRenderer.contentBoxRect()).isEmpty(); 2471 2587 } 2472 2588 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 2589 bool 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 2610 bool 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 2670 bool 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? 2499 2690 bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerModelObject& renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const 2500 2691 { … … 2526 2717 } 2527 2718 2528 bool RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons(const RenderLayerModelObject& renderer, const RenderStyle& oldStyle) 2529 { 2530 auto& style = renderer.style(); 2531 if (RenderElement::createsGroupForStyle(style) != RenderElement::createsGroupForStyle(oldStyle)) 2719 bool RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons(const RenderStyle& oldStyle, const RenderStyle& newStyle) 2720 { 2721 if (RenderElement::createsGroupForStyle(newStyle) != RenderElement::createsGroupForStyle(oldStyle)) 2532 2722 return true; 2533 if ( style.isolation() != oldStyle.isolation())2723 if (newStyle.isolation() != oldStyle.isolation()) 2534 2724 return true; 2535 if ( style.hasTransform() != oldStyle.hasTransform())2725 if (newStyle.hasTransform() != oldStyle.hasTransform()) 2536 2726 return true; 2537 if ( style.boxReflect() != oldStyle.boxReflect())2727 if (newStyle.boxReflect() != oldStyle.boxReflect()) 2538 2728 return true; 2539 if ( style.transformStyle3D() != oldStyle.transformStyle3D())2729 if (newStyle.transformStyle3D() != oldStyle.transformStyle3D()) 2540 2730 return true; 2541 if ( style.hasPerspective() != oldStyle.hasPerspective())2731 if (newStyle.hasPerspective() != oldStyle.hasPerspective()) 2542 2732 return true; 2543 2733 2544 2734 return false; 2545 }2546 2547 bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject& renderer) const2548 {2549 #if ENABLE(FILTERS_LEVEL_2)2550 if (renderer.hasBackdropFilter())2551 return true;2552 #endif2553 2554 if (!(m_compositingTriggers & ChromeClient::FilterTrigger))2555 return false;2556 2557 return renderer.hasFilter();2558 }2559 2560 bool RenderLayerCompositor::requiresCompositingForWillChange(RenderLayerModelObject& renderer) const2561 {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 #endif2569 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();2577 2735 } 2578 2736 … … 2625 2783 } 2626 2784 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 } 2785 bool RenderLayerCompositor::fixedLayerIntersectsViewport(const RenderLayer& layer) const 2786 { 2787 ASSERT(layer.renderer().style().position() == PositionType::Fixed); 2691 2788 2692 2789 // Fixed position elements that are invisible in the current view don't get their own layer. … … 2698 2795 viewBounds = m_renderView.frameView().rectForFixedPositionLayout(); 2699 2796 2700 LayoutRect layerBounds = layer.calculateLayerBounds(&layer, LayoutSize(), { RenderLayer::UseLocalClipRectIfPossible, RenderLayer::Include LayerFilterOutsets, RenderLayer::UseFragmentBoxesExcludingCompositing,2797 LayoutRect layerBounds = layer.calculateLayerBounds(&layer, LayoutSize(), { RenderLayer::UseLocalClipRectIfPossible, RenderLayer::IncludeFilterOutsets, RenderLayer::UseFragmentBoxesExcludingCompositing, 2701 2798 RenderLayer::ExcludeHiddenDescendants, RenderLayer::DontConstrainForMask, RenderLayer::IncludeCompositedDescendants }); 2702 2799 // Map to m_renderView to ignore page scale. 2703 2800 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 2804 bool RenderLayerCompositor::useCoordinatedScrollingForLayer(const RenderLayer& layer) const 2805 { 2806 if (layer.isRenderViewLayer() && hasCoordinatedScrolling()) 2807 return true; 2724 2808 2725 2809 return layer.hasTouchScrollableOverflow(); 2726 #else2727 UNUSED_PARAM(layer);2728 return false;2729 #endif2730 2810 } 2731 2811 … … 3119 3199 3120 3200 bool hadFixedBackground = oldStyle && oldStyle->hasEntirelyFixedBackground(); 3121 if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground()) { 3122 setCompositingLayersNeedRebuild(); 3123 scheduleCompositingLayerUpdate(); 3124 } 3201 if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground()) 3202 rootLayerConfigurationChanged(); 3125 3203 } 3126 3204 … … 3139 3217 bool extendedBackgroundColorChanged = m_rootExtendedBackgroundColor != extendedBackgroundColor; 3140 3218 3141 LOG(Compositing, "RenderLayerCompositor %p rootBackgroundColorOrTransparencyChanged. isTransparent=%d, transparencyChanged=%d, backgroundColorChanged=%d, extendedBackgroundColorChanged=%d", this, isTransparent, transparencyChanged, backgroundColorChanged, extendedBackgroundColorChanged);3142 3219 if (!transparencyChanged && !backgroundColorChanged && !extendedBackgroundColorChanged) 3143 3220 return; 3221 3222 LOG(Compositing, "RenderLayerCompositor %p rootBackgroundColorOrTransparencyChanged. isTransparent=%d", this, isTransparent); 3144 3223 3145 3224 m_viewBackgroundIsTransparent = isTransparent; … … 3161 3240 } 3162 3241 3163 setRootLayerConfigurationNeedsUpdate(); 3164 scheduleCompositingLayerUpdate(); 3242 rootLayerConfigurationChanged(); 3165 3243 } 3166 3244 … … 4065 4143 case CompositingUpdateType::AfterStyleChange: ts << "after style change"; break; 4066 4144 case CompositingUpdateType::AfterLayout: ts << "after layout"; break; 4067 case CompositingUpdateType::OnHitTest: ts << "on hit test"; break;4068 4145 case CompositingUpdateType::OnScroll: ts << "on scroll"; break; 4069 4146 case CompositingUpdateType::OnCompositedScroll: ts << "on composited scroll"; break; -
trunk/Source/WebCore/rendering/RenderLayerCompositor.h
r238070 r238090 50 50 AfterStyleChange, 51 51 AfterLayout, 52 OnHitTest,53 52 OnScroll, 54 53 OnCompositedScroll … … 111 110 bool canRender3DTransforms() const; 112 111 113 // Called when the layer hierarchy needs to be updated (compositing layers have been114 // created, destroyed or re-parented).115 void setCompositingLayersNeedRebuild(bool needRebuild = true);116 bool compositingLayersNeedRebuild() const { return m_compositingLayersNeedRebuild; }117 118 112 void willRecalcStyle(); 119 113 … … 142 136 // Update the compositing state of the given layer. Returns true if that state changed. 143 137 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 149 150 // Whether layer's backing needs a graphics layer to do clipping by an ancestor (non-stacking-context parent with overflow). 150 151 bool clippedByAncestor(RenderLayer&) const; … … 154 155 // Whether the given layer needs an extra 'contents' layer. 155 156 bool needsContentsCompositingLayer(const RenderLayer&) const; 157 158 bool fixedLayerIntersectsViewport(const RenderLayer&) const; 156 159 157 160 bool supportsFixedRootBackgroundCompositing() const; … … 235 238 void frameViewDidAddOrRemoveScrollbars(); 236 239 void frameViewDidLayout(); 237 void root FixedBackgroundsChanged();240 void rootLayerConfigurationChanged(); 238 241 239 242 void scrollingLayerDidChange(RenderLayer&); … … 296 299 void setTracksRepaints(bool tracksRepaints) { m_isTrackingRepaints = tracksRepaints; } 297 300 298 299 void setShouldReevaluateCompositingAfterLayout() { m_reevaluateCompositingAfterLayout = true; }300 301 301 bool viewHasTransparentBackground(Color* backgroundColor = nullptr) const; 302 302 … … 347 347 348 348 // Whether the given RL needs a compositing layer. 349 bool needsToBeComposited(const RenderLayer&, Re nderLayer::ViewportConstrainedNotCompositedReason* = nullptr) const;349 bool needsToBeComposited(const RenderLayer&, RequiresCompositingData&) const; 350 350 // Whether the layer has an intrinsic need for compositing layer. 351 bool requiresCompositingLayer(const RenderLayer&, Re nderLayer::ViewportConstrainedNotCompositedReason* = nullptr) const;351 bool requiresCompositingLayer(const RenderLayer&, RequiresCompositingData&) const; 352 352 // Whether the layer could ever be composited. 353 353 bool canBeComposited(const RenderLayer&) const; … … 356 356 // Make or destroy the backing for this layer; returns true if backing changed. 357 357 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); 359 359 360 360 void clearBackingForLayerIncludingDescendants(RenderLayer&); … … 369 369 void updateCompositingLayersTimerFired(); 370 370 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 }; 374 378 // 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 381 381 void setCompositingParent(RenderLayer& childLayer, RenderLayer* parentLayer); 382 382 void removeCompositedChildren(RenderLayer&); … … 418 418 #endif 419 419 420 // Non layout-dependent 420 421 bool requiresCompositingForAnimation(RenderLayerModelObject&) const; 421 422 bool requiresCompositingForTransform(RenderLayerModelObject&) const; … … 423 424 bool requiresCompositingForVideo(RenderLayerModelObject&) const; 424 425 bool requiresCompositingForCanvas(RenderLayerModelObject&) const; 425 bool requiresCompositingForPlugin(RenderLayerModelObject&) const;426 bool requiresCompositingForFrame(RenderLayerModelObject&) const;427 426 bool requiresCompositingForFilters(RenderLayerModelObject&) const; 428 427 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 432 436 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); 434 439 435 440 void updateCustomLayersAfterFlush(); … … 470 475 #if !LOG_DISABLED 471 476 const char* logReasonsForCompositing(const RenderLayer&); 472 void logLayerInfo(const RenderLayer&, int depth);477 void logLayerInfo(const RenderLayer&, const char*, int depth); 473 478 #endif 474 479 … … 476 481 bool isMainFrameCompositor() const; 477 482 478 void setRootLayerConfigurationNeedsUpdate() { m_rootLayerConfigurationNeedsUpdate = true; }479 480 483 private: 481 484 RenderView& m_renderView; … … 493 496 bool m_displayListDrawingEnabled { false }; 494 497 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 499 498 bool m_compositing { false }; 500 bool m_compositingLayersNeedRebuild { false };501 bool m_rootLayerConfigurationNeedsUpdate { false };502 499 bool m_flushingLayers { false }; 503 500 bool m_shouldFlushOnReattach { false }; … … 549 546 bool m_layerFlushThrottlingTemporarilyDisabledForInteraction { false }; 550 547 bool m_hasPendingLayerFlush { false }; 551 bool m_layerNeedsCompositingUpdate { false };552 548 bool m_viewBackgroundIsTransparent { false }; 553 549 -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r237058 r238090 705 705 // Ensure our lists are up-to-date. 706 706 layer.updateLayerListsIfNeeded(); 707 layer.updateDescendantDependentFlags(); 707 708 708 709 bool shouldPaint = (behavior & RenderAsTextShowAllLayers) ? true : layer.intersectsDamageRect(layerBounds, damageRect.rect(), &rootLayer, layer.offsetFromAncestor(&rootLayer)); -
trunk/Source/WebKitLegacy/mac/ChangeLog
r238080 r238090 1 2018-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 1 13 2018-11-11 Wenson Hsieh <wenson_hsieh@apple.com> 2 14 -
trunk/Source/WebKitLegacy/mac/WebView/WebView.mm
r238074 r238090 4190 4190 if (layerForWidget->contentsLayerForMedia() != layer) { 4191 4191 layerForWidget->setContentsToPlatformLayer(layer, GraphicsLayer::ContentsLayerPurpose::Media); 4192 // We need to make sure the layer hiera chy change is applied immediately.4192 // We need to make sure the layer hierarchy change is applied immediately. 4193 4193 if (mainCoreFrame->view()) 4194 4194 mainCoreFrame->view()->flushCompositingStateIncludingSubframes();
Note:
See TracChangeset
for help on using the changeset viewer.