Changeset 245371 in webkit
- Timestamp:
- May 15, 2019 7:51:15 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r245370 r245371 69 69 * loader/PingLoader.cpp: 70 70 (WebCore::PingLoader::sendPing): 71 72 2019-05-15 Simon Fraser <simon.fraser@apple.com> 73 74 Clean up RenderLayerCompositor::computeCompositingRequirements() and traverseUnchangedSubtree() 75 https://bugs.webkit.org/show_bug.cgi?id=197931 76 77 Reviewed by Zalan Bujtas. 78 79 These functions have grown and become hard to maintain, so try to undo some technical debt. 80 81 Rename "childState" to "currentState" since it's the state we pass to children, but also 82 is state we change when the current layer becomes composited. 83 84 Separate the layerWillComposite() lambda from layerWillCompositePostDescendants(). 85 86 Group the chunks of code at end of the functions into: 87 - updating bits on RenderLayer 88 - updating compositingState with changes from children and our state 89 - doing post-traversal work on overlapMap and backingSharingState 90 91 Code shared between the two functions is pushed into CompositingState::updateWithDescendantStateAndLayer(). 92 93 This moves code around but should not cause any behavior change. 94 95 * rendering/RenderLayerBacking.cpp: 96 (WebCore::RenderLayerBacking::updateConfiguration): 97 * rendering/RenderLayerCompositor.cpp: 98 (WebCore::RenderLayerCompositor::OverlapExtent::knownToBeHaveExtentUncertainty const): 99 (WebCore::RenderLayerCompositor::CompositingState::updateWithDescendantStateAndLayer): 100 (WebCore::RenderLayerCompositor::computeCompositingRequirements): 101 (WebCore::RenderLayerCompositor::traverseUnchangedSubtree): 102 (WebCore::RenderLayerCompositor::clipsCompositingDescendants): 103 (WebCore::RenderLayerCompositor::CompositingState::propagateStateFromChildren): Deleted. 104 (WebCore::RenderLayerCompositor::CompositingState::propagateStateFromChildrenForUnchangedSubtree): Deleted. 105 (WebCore::RenderLayerCompositor::clipsCompositingDescendants const): Deleted. 106 * rendering/RenderLayerCompositor.h: 71 107 72 108 2019-05-15 Simon Fraser <simon.fraser@apple.com> -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r245293 r245371 772 772 needsDescendantsClippingLayer = contentsClippingRect.isRounded(); 773 773 } else 774 needsDescendantsClippingLayer = compositor.clipsCompositingDescendants(m_owningLayer);774 needsDescendantsClippingLayer = RenderLayerCompositor::clipsCompositingDescendants(m_owningLayer); 775 775 776 776 if (updateScrollingLayers(usesCompositedScrolling)) -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r245336 r245371 114 114 }; 115 115 116 struct RenderLayerCompositor::OverlapExtent { 117 LayoutRect bounds; 118 bool extentComputed { false }; 119 bool hasTransformAnimation { false }; 120 bool animationCausesExtentUncertainty { false }; 121 122 bool knownToBeHaveExtentUncertainty() const { return extentComputed && animationCausesExtentUncertainty; } 123 }; 124 116 125 struct RenderLayerCompositor::CompositingState { 117 126 CompositingState(RenderLayer* compAncestor, bool testOverlap = true) … … 145 154 } 146 155 147 void propagateStateFromChildren(const CompositingState& childState)156 void updateWithDescendantStateAndLayer(const CompositingState& childState, const RenderLayer& layer, const OverlapExtent& layerExtent, bool isUnchangedSubtree = false) 148 157 { 149 158 // Subsequent layers in the parent stacking context also need to composite. 150 subtreeIsCompositing |= childState.subtreeIsCompositing; 151 fullPaintOrderTraversalRequired |= childState.fullPaintOrderTraversalRequired; 152 } 153 154 void propagateStateFromChildrenForUnchangedSubtree(const CompositingState& childState) 155 { 156 subtreeIsCompositing |= childState.subtreeIsCompositing; 159 subtreeIsCompositing |= childState.subtreeIsCompositing | layer.isComposited(); 160 if (!isUnchangedSubtree) 161 fullPaintOrderTraversalRequired |= childState.fullPaintOrderTraversalRequired; 162 163 // Turn overlap testing off for later layers if it's already off, or if we have an animating transform. 164 // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because 165 // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map. 166 auto canReenableOverlapTesting = [&layer]() { 167 return layer.isComposited() && RenderLayerCompositor::clipsCompositingDescendants(layer); 168 }; 169 if ((!childState.testingOverlap && !canReenableOverlapTesting()) || layerExtent.knownToBeHaveExtentUncertainty()) 170 testingOverlap = false; 171 172 #if ENABLE(CSS_COMPOSITING) 173 if ((layer.isComposited() && layer.hasBlendMode()) || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending())) 174 hasNotIsolatedCompositedBlendingDescendants = true; 175 #endif 157 176 } 158 177 … … 251 270 layer.backing()->clearBackingSharingLayers(); 252 271 } 253 254 struct RenderLayerCompositor::OverlapExtent {255 LayoutRect bounds;256 bool extentComputed { false };257 bool hasTransformAnimation { false };258 bool animationCausesExtentUncertainty { false };259 260 bool knownToBeHaveExtentUncertainty() const { return extentComputed && animationCausesExtentUncertainty; }261 };262 272 263 273 #if !LOG_DISABLED … … 900 910 // a compositing layer among them, so start by inheriting the compositing 901 911 // ancestor with subtreeIsCompositing set to false. 902 CompositingState childState = compositingState.stateForPaintOrderChildren(layer); 903 904 auto layerWillComposite = [&](bool postDescendants = false) { 905 // This layer now acts as the ancestor for kids. 906 childState.compositingAncestor = &layer; 907 overlapMap.pushCompositingContainer(); 908 909 if (postDescendants) { 910 childState.subtreeIsCompositing = true; 911 addToOverlapMapRecursive(overlapMap, layer); 912 } 913 912 CompositingState currentState = compositingState.stateForPaintOrderChildren(layer); 913 914 auto layerWillComposite = [&] { 914 915 // This layer is going to be composited, so children can safely ignore the fact that there's an 915 916 // animation running behind this layer, meaning they can rely on the overlap map testing again. 916 childState.testingOverlap = true; 917 currentState.testingOverlap = true; 918 // This layer now acts as the ancestor for kids. 919 currentState.compositingAncestor = &layer; 920 overlapMap.pushCompositingContainer(); 921 917 922 willBeComposited = true; 918 923 layerPaintsIntoProvidedBacking = false; 919 924 }; 920 925 926 auto layerWillCompositePostDescendants = [&] { 927 layerWillComposite(); 928 currentState.subtreeIsCompositing = true; 929 addToOverlapMapRecursive(overlapMap, layer); 930 }; 931 921 932 if (willBeComposited) { 922 // Tell the parent it has compositing descendants.923 compositingState.subtreeIsCompositing = true;924 925 933 layerWillComposite(); 926 934 927 935 computeExtent(overlapMap, layer, layerExtent); 928 c hildState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;936 currentState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation; 929 937 // Too hard to compute animated bounds if both us and some ancestor is animating transform. 930 938 layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation; 931 939 } else if (layerPaintsIntoProvidedBacking) { 932 c hildState.backingSharingAncestor = &layer;940 currentState.backingSharingAncestor = &layer; 933 941 overlapMap.pushCompositingContainer(); 934 942 } … … 943 951 944 952 for (auto* childLayer : layer.negativeZOrderLayers()) { 945 computeCompositingRequirements(&layer, *childLayer, overlapMap, c hildState, backingSharingState, anyDescendantHas3DTransform);953 computeCompositingRequirements(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform); 946 954 947 955 // If we have to make a layer for this child, make one now so we can have a contents layer 948 956 // (since we need to ensure that the -ve z-order child renders underneath our contents). 949 if (!willBeComposited && c hildState.subtreeIsCompositing) {957 if (!willBeComposited && currentState.subtreeIsCompositing) { 950 958 // make layer compositing 951 959 layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer); … … 955 963 956 964 for (auto* childLayer : layer.normalFlowLayers()) 957 computeCompositingRequirements(&layer, *childLayer, overlapMap, c hildState, backingSharingState, anyDescendantHas3DTransform);965 computeCompositingRequirements(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform); 958 966 959 967 for (auto* childLayer : layer.positiveZOrderLayers()) 960 computeCompositingRequirements(&layer, *childLayer, overlapMap, c hildState, backingSharingState, anyDescendantHas3DTransform);968 computeCompositingRequirements(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform); 961 969 962 970 // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled). … … 971 979 // FIXME: When layerExtent has taken animation bounds into account, we also know that the bounds 972 980 // include descendants, so we don't need to add them all to the overlap map. 973 if (c hildState.compositingAncestor && !childState.compositingAncestor->isRenderViewLayer())981 if (currentState.compositingAncestor && !currentState.compositingAncestor->isRenderViewLayer()) 974 982 addToOverlapMap(overlapMap, layer, layerExtent); 975 983 976 984 #if ENABLE(CSS_COMPOSITING) 977 985 bool isolatedCompositedBlending = layer.isolatesCompositedBlending(); 978 layer.setHasNotIsolatedCompositedBlendingDescendants(c hildState.hasNotIsolatedCompositedBlendingDescendants);986 layer.setHasNotIsolatedCompositedBlendingDescendants(currentState.hasNotIsolatedCompositedBlendingDescendants); 979 987 if (layer.isolatesCompositedBlending() != isolatedCompositedBlending) { 980 988 // isolatedCompositedBlending affects the result of clippedByAncestor(). … … 987 995 RenderLayer::IndirectCompositingReason indirectCompositingReason; 988 996 if (!willBeComposited && canBeComposited(layer) 989 && requiresCompositingForIndirectReason(layer, compositingState.compositingAncestor, c hildState.subtreeIsCompositing, anyDescendantHas3DTransform, layerPaintsIntoProvidedBacking, indirectCompositingReason)) {997 && requiresCompositingForIndirectReason(layer, compositingState.compositingAncestor, currentState.subtreeIsCompositing, anyDescendantHas3DTransform, layerPaintsIntoProvidedBacking, indirectCompositingReason)) { 990 998 layer.setIndirectCompositingReason(indirectCompositingReason); 991 layerWillComposite (true);999 layerWillCompositePostDescendants(); 992 1000 } 993 1001 … … 998 1006 999 1007 // Set the flag to say that this layer has compositing children. 1000 layer.setHasCompositingDescendant(c hildState.subtreeIsCompositing);1001 1002 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that again.1008 layer.setHasCompositingDescendant(currentState.subtreeIsCompositing); 1009 1010 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that now. 1003 1011 bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer); 1004 1005 // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.1006 // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because1007 // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.1008 if ((!childState.testingOverlap && !isCompositedClippingLayer) || layerExtent.knownToBeHaveExtentUncertainty())1009 compositingState.testingOverlap = false;1010 1011 1012 if (isCompositedClippingLayer & !willBeComposited) 1012 layerWillComposite(true); 1013 1014 #if ENABLE(CSS_COMPOSITING) 1015 if ((willBeComposited && layer.hasBlendMode()) || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending())) 1016 compositingState.hasNotIsolatedCompositedBlendingDescendants = true; 1017 #endif 1018 1019 if ((childState.compositingAncestor == &layer && !layer.isRenderViewLayer()) || childState.backingSharingAncestor == &layer) 1020 overlapMap.popCompositingContainer(); 1013 layerWillCompositePostDescendants(); 1021 1014 1022 1015 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need … … 1024 1017 // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden). 1025 1018 RequiresCompositingData rootLayerQueryData; 1026 if (layer.isRenderViewLayer() && !c hildState.subtreeIsCompositing && !requiresCompositingLayer(layer, rootLayerQueryData) && !m_forceCompositingMode && !needsCompositingForContentOrOverlays()) {1019 if (layer.isRenderViewLayer() && !currentState.subtreeIsCompositing && !requiresCompositingLayer(layer, rootLayerQueryData) && !m_forceCompositingMode && !needsCompositingForContentOrOverlays()) { 1027 1020 // Don't drop out of compositing on iOS, because we may flash. See <rdar://problem/8348337>. 1028 1021 #if !PLATFORM(IOS_FAMILY) … … 1031 1024 #endif 1032 1025 } 1033 1034 compositingState.propagateStateFromChildren(childState);1035 1026 1036 1027 ASSERT(willBeComposited == needsToBeComposited(layer, queryData)); … … 1046 1037 } 1047 1038 1048 backingSharingState.updateAfterDescendantTraversal(layer, compositingState.stackingContextAncestor); 1049 1039 // Update layer state bits. 1050 1040 if (layer.reflectionLayer() && updateLayerCompositingState(*layer.reflectionLayer(), queryData, CompositingChangeRepaintNow)) 1051 1041 layer.setNeedsCompositingLayerConnection(); 1052 1053 descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform();1054 1042 1055 1043 // FIXME: clarify needsCompositingPaintOrderChildrenUpdate. If a composited layer gets a new ancestor, it needs geometry computations. … … 1060 1048 1061 1049 layer.clearCompositingRequirementsTraversalState(); 1050 1051 // Compute state passed to the caller. 1052 descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform(); 1053 compositingState.updateWithDescendantStateAndLayer(currentState, layer, layerExtent); 1054 1055 // Pop backing/overlap sharing state. 1056 if ((willBeComposited && !layer.isRenderViewLayer()) || currentState.backingSharingAncestor == &layer) 1057 overlapMap.popCompositingContainer(); 1058 1059 backingSharingState.updateAfterDescendantTraversal(layer, compositingState.stackingContextAncestor); 1062 1060 overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer); 1063 1061 … … 1096 1094 } 1097 1095 1098 CompositingState c hildState = compositingState.stateForPaintOrderChildren(layer);1096 CompositingState currentState = compositingState.stateForPaintOrderChildren(layer); 1099 1097 1100 1098 if (layerIsComposited) { 1101 // Tell the parent it has compositing descendants.1102 compositingState.subtreeIsCompositing = true;1103 // This layer now acts as the ancestor for kids.1104 childState.compositingAncestor = &layer;1105 1106 overlapMap.pushCompositingContainer();1107 1099 // This layer is going to be composited, so children can safely ignore the fact that there's an 1108 1100 // animation running behind this layer, meaning they can rely on the overlap map testing again. 1109 childState.testingOverlap = true; 1101 currentState.testingOverlap = true; 1102 // This layer now acts as the ancestor for kids. 1103 currentState.compositingAncestor = &layer; 1104 overlapMap.pushCompositingContainer(); 1110 1105 1111 1106 computeExtent(overlapMap, layer, layerExtent); 1112 c hildState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;1107 currentState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation; 1113 1108 // Too hard to compute animated bounds if both us and some ancestor is animating transform. 1114 1109 layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation; … … 1124 1119 1125 1120 for (auto* childLayer : layer.negativeZOrderLayers()) { 1126 traverseUnchangedSubtree(&layer, *childLayer, overlapMap, c hildState, backingSharingState, anyDescendantHas3DTransform);1127 if (c hildState.subtreeIsCompositing)1121 traverseUnchangedSubtree(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform); 1122 if (currentState.subtreeIsCompositing) 1128 1123 ASSERT(layerIsComposited); 1129 1124 } 1130 1125 1131 1126 for (auto* childLayer : layer.normalFlowLayers()) 1132 traverseUnchangedSubtree(&layer, *childLayer, overlapMap, c hildState, backingSharingState, anyDescendantHas3DTransform);1127 traverseUnchangedSubtree(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform); 1133 1128 1134 1129 for (auto* childLayer : layer.positiveZOrderLayers()) 1135 traverseUnchangedSubtree(&layer, *childLayer, overlapMap, c hildState, backingSharingState, anyDescendantHas3DTransform);1130 traverseUnchangedSubtree(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform); 1136 1131 1137 1132 // All layers (even ones that aren't being composited) need to get added to … … 1140 1135 // FIXME: When layerExtent has taken animation bounds into account, we also know that the bounds 1141 1136 // include descendants, so we don't need to add them all to the overlap map. 1142 if (c hildState.compositingAncestor && !childState.compositingAncestor->isRenderViewLayer())1137 if (currentState.compositingAncestor && !currentState.compositingAncestor->isRenderViewLayer()) 1143 1138 addToOverlapMap(overlapMap, layer, layerExtent); 1144 1139 1145 compositingState.propagateStateFromChildrenForUnchangedSubtree(childState);1146 1147 1140 // Set the flag to say that this layer has compositing children. 1148 ASSERT(layer.hasCompositingDescendant() == childState.subtreeIsCompositing); 1149 1150 // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that again. 1151 bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer); 1152 1153 // Turn overlap testing off for later layers if it's already off, or if we have an animating transform. 1154 // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because 1155 // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map. 1156 if ((!childState.testingOverlap && !isCompositedClippingLayer) || layerExtent.knownToBeHaveExtentUncertainty()) 1157 compositingState.testingOverlap = false; 1158 1159 if (isCompositedClippingLayer) 1160 ASSERT(layerIsComposited); 1161 1162 #if ENABLE(CSS_COMPOSITING) 1163 if ((layerIsComposited && layer.hasBlendMode()) 1164 || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending())) 1165 compositingState.hasNotIsolatedCompositedBlendingDescendants = true; 1166 #endif 1167 1168 if ((childState.compositingAncestor == &layer && !layer.isRenderViewLayer()) || childState.backingSharingAncestor == &layer) 1141 ASSERT(layer.hasCompositingDescendant() == currentState.subtreeIsCompositing); 1142 ASSERT_IMPLIES(canBeComposited(layer) && clipsCompositingDescendants(layer), layerIsComposited); 1143 1144 descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform(); 1145 1146 ASSERT(!currentState.fullPaintOrderTraversalRequired); 1147 compositingState.updateWithDescendantStateAndLayer(currentState, layer, layerExtent, true); 1148 1149 if ((layerIsComposited && !layer.isRenderViewLayer()) || currentState.backingSharingAncestor == &layer) 1169 1150 overlapMap.popCompositingContainer(); 1170 1151 1171 1152 backingSharingState.updateAfterDescendantTraversal(layer, compositingState.stackingContextAncestor); 1172 1173 descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform(); 1153 overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer); 1174 1154 1175 1155 ASSERT(!layer.needsCompositingRequirementsTraversal()); 1176 1177 overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);1178 1156 } 1179 1157 … … 1257 1235 #endif 1258 1236 1259 auto appendForegroundLayerIfNecessary = [&] (){1237 auto appendForegroundLayerIfNecessary = [&] { 1260 1238 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented. 1261 1239 if (layer.negativeZOrderLayers().size()) { … … 2521 2499 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer 2522 2500 // into the hierarchy between this layer and its children in the z-order hierarchy. 2523 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer& layer) const2501 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer& layer) 2524 2502 { 2525 2503 return layer.hasCompositingDescendant() && layer.renderer().hasClipOrOverflowClip() && !layer.isolatesCompositedBlending(); -
trunk/Source/WebCore/rendering/RenderLayerCompositor.h
r245326 r245371 204 204 bool clippedByAncestor(RenderLayer&) const; 205 205 // Whether layer's backing needs a graphics layer to clip z-order children of the given layer. 206 bool clipsCompositingDescendants(const RenderLayer&) const;206 static bool clipsCompositingDescendants(const RenderLayer&); 207 207 208 208 // Whether the given layer needs an extra 'contents' layer.
Note: See TracChangeset
for help on using the changeset viewer.