Title: [244509] trunk/Source/WebCore
Revision
244509
Author
simon.fra...@apple.com
Date
2019-04-22 12:57:58 -0700 (Mon, 22 Apr 2019)

Log Message

Introduce the concept of "opportunistic" stacking contexts
https://bugs.webkit.org/show_bug.cgi?id=197077

Reviewed by Zalan Bujtas.

Bring back a variant of some code removed in r236424, which allows a RenderLayer
to be stacking context for painting, without actually being on in terms of CSS.

Internally, RenderLayer will call setIsOpportunisticStackingContext() to make a layer
into a stacking context for painting. External callers deal with isStackingContext()
or isCSSStackingContext().

Sadly we can't make m_forcedStackingContext (set on media element layers) trigger a
non-CSS stacking context; media controls use mix-blend-mode, and rely on the fake-stacking
media layer to be the "isolateBlending" ancestor.

No code uses this yet.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::shouldBeCSSStackingContext const):
(WebCore::RenderLayer::isStackingContextChanged):
(WebCore::RenderLayer::setIsOpportunisticStackingContext):
(WebCore::RenderLayer::setIsCSSStackingContext):
(WebCore::RenderLayer::updateAncestorChainHasBlendingDescendants):
(WebCore::RenderLayer::dirtyAncestorChainHasBlendingDescendants):
(WebCore::RenderLayer::beginTransparencyLayers):
(WebCore::RenderLayer::calculateClipRects const):
(WebCore::outputPaintOrderTreeLegend):
(WebCore::outputPaintOrderTreeRecursive):
(WebCore::RenderLayer::shouldBeStackingContext const): Deleted.
(WebCore::RenderLayer::setIsStackingContext): Deleted.
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::compositingOpacity const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (244508 => 244509)


--- trunk/Source/WebCore/ChangeLog	2019-04-22 19:51:38 UTC (rev 244508)
+++ trunk/Source/WebCore/ChangeLog	2019-04-22 19:57:58 UTC (rev 244509)
@@ -1,3 +1,41 @@
+2019-04-22  Simon Fraser  <simon.fra...@apple.com>
+
+        Introduce the concept of "opportunistic" stacking contexts
+        https://bugs.webkit.org/show_bug.cgi?id=197077
+
+        Reviewed by Zalan Bujtas.
+
+        Bring back a variant of some code removed in r236424, which allows a RenderLayer
+        to be stacking context for painting, without actually being on in terms of CSS.
+        
+        Internally, RenderLayer will call setIsOpportunisticStackingContext() to make a layer
+        into a stacking context for painting. External callers deal with isStackingContext()
+        or isCSSStackingContext().
+
+        Sadly we can't make m_forcedStackingContext (set on media element layers) trigger a
+        non-CSS stacking context; media controls use mix-blend-mode, and rely on the fake-stacking
+        media layer to be the "isolateBlending" ancestor.
+
+        No code uses this yet.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        (WebCore::RenderLayer::shouldBeCSSStackingContext const):
+        (WebCore::RenderLayer::isStackingContextChanged):
+        (WebCore::RenderLayer::setIsOpportunisticStackingContext):
+        (WebCore::RenderLayer::setIsCSSStackingContext):
+        (WebCore::RenderLayer::updateAncestorChainHasBlendingDescendants):
+        (WebCore::RenderLayer::dirtyAncestorChainHasBlendingDescendants):
+        (WebCore::RenderLayer::beginTransparencyLayers):
+        (WebCore::RenderLayer::calculateClipRects const):
+        (WebCore::outputPaintOrderTreeLegend):
+        (WebCore::outputPaintOrderTreeRecursive):
+        (WebCore::RenderLayer::shouldBeStackingContext const): Deleted.
+        (WebCore::RenderLayer::setIsStackingContext): Deleted.
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::compositingOpacity const):
+
 2019-04-22  Justin Fan  <justin_...@apple.com>
 
         [WebGPU] Move swap chain methods from GPUDevice to GPUCanvasContext

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (244508 => 244509)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2019-04-22 19:51:38 UTC (rev 244508)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2019-04-22 19:57:58 UTC (rev 244509)
@@ -271,6 +271,7 @@
 RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
     : m_isRenderViewLayer(rendererLayerModelObject.isRenderView())
     , m_forcedStackingContext(rendererLayerModelObject.isMedia())
+    , m_isOpportunisticStackingContext(false)
     , m_zOrderListsDirty(false)
     , m_normalFlowListDirty(true)
     , m_hadNegativeZOrderList(false)
@@ -317,7 +318,7 @@
     , m_renderer(rendererLayerModelObject)
 {
     setIsNormalFlowOnly(shouldBeNormalFlowOnly());
-    setIsStackingContext(shouldBeStackingContext());
+    setIsCSSStackingContext(shouldBeCSSStackingContext());
 
     m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
 
@@ -560,9 +561,9 @@
         || renderer().isInFlowRenderFragmentedFlow();
 }
 
-bool RenderLayer::shouldBeStackingContext() const
+bool RenderLayer::shouldBeCSSStackingContext() const
 {
-    return !renderer().style().hasAutoZIndex() || isRenderViewLayer() || isForcedStackingContext();
+    return !renderer().style().hasAutoZIndex() || isRenderViewLayer();
 }
 
 bool RenderLayer::setIsNormalFlowOnly(bool isNormalFlowOnly)
@@ -578,22 +579,37 @@
     return true;
 }
 
-bool RenderLayer::setIsStackingContext(bool isStackingContext)
+void RenderLayer::isStackingContextChanged()
 {
-    if (isStackingContext == m_isStackingContext)
-        return false;
-    
-    m_isStackingContext = isStackingContext;
-
     dirtyStackingContextZOrderLists();
-    if (isStackingContext)
+    if (isStackingContext())
         dirtyZOrderLists();
     else
         clearZOrderLists();
+}
 
+bool RenderLayer::setIsOpportunisticStackingContext(bool isStacking)
+{
+    bool wasStacking = isStackingContext();
+    m_isOpportunisticStackingContext = isStacking;
+    if (wasStacking == isStackingContext())
+        return false;
+
+    isStackingContextChanged();
     return true;
 }
 
+bool RenderLayer::setIsCSSStackingContext(bool isCSSStackingContext)
+{
+    bool wasStacking = isStackingContext();
+    m_isCSSStackingContext = isCSSStackingContext;
+    if (wasStacking == isStackingContext())
+        return false;
+
+    isStackingContextChanged();
+    return true;
+}
+
 void RenderLayer::setParent(RenderLayer* parent)
 {
     if (parent == m_parent)
@@ -1135,7 +1151,7 @@
 
         layer->updateSelfPaintingLayer();
 
-        if (layer->isStackingContext())
+        if (layer->isCSSStackingContext())
             break;
     }
 }
@@ -1148,7 +1164,7 @@
         
         layer->m_hasNotIsolatedBlendingDescendantsStatusDirty = true;
 
-        if (layer->isStackingContext())
+        if (layer->isCSSStackingContext())
             break;
     }
 }
@@ -1979,7 +1995,7 @@
         ancestor->beginTransparencyLayers(context, paintingInfo, dirtyRect);
     
     if (paintsWithTransparency(paintingInfo.paintBehavior)) {
-        ASSERT(isStackingContext());
+        ASSERT(isCSSStackingContext());
         m_usedTransparency = true;
         context.save();
         LayoutRect adjustedClipRect = paintingExtent(*this, paintingInfo.rootLayer, dirtyRect, paintingInfo.paintBehavior);
@@ -6364,10 +6380,10 @@
 {
     setIsNormalFlowOnly(shouldBeNormalFlowOnly());
 
-    if (setIsStackingContext(shouldBeStackingContext())) {
+    if (setIsCSSStackingContext(shouldBeCSSStackingContext())) {
 #if ENABLE(CSS_COMPOSITING)
         if (parent()) {
-            if (isStackingContext()) {
+            if (isCSSStackingContext()) {
                 if (!hasNotIsolatedBlendingDescendantsStatusDirty() && hasNotIsolatedBlendingDescendants())
                     parent()->dirtyAncestorChainHasBlendingDescendants();
             } else {
@@ -6755,7 +6771,7 @@
 static void outputPaintOrderTreeLegend(TextStream& stream)
 {
     stream.nextLine();
-    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, (c)omposited descendant, (s)scrolling ancestor\n"
+    stream << "(S)tacking Context/(F)orced SC/O(P)portunistic SC, (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, (c)omposited descendant, (s)scrolling ancestor\n"
         "Dirty (z)-lists, Dirty (n)ormal flow lists\n"
         "Traversal needs: requirements (t)raversal on descendants, (b)acking or hierarchy traversal on descendants, (r)equirements traversal on all descendants, requirements traversal on all (s)ubsequent layers, (h)ierarchy traversal on all descendants, update of paint (o)rder children\n"
         "Update needs:    post-(l)ayout requirements, (g)eometry, (k)ids geometry, (c)onfig, layer conne(x)ion, (s)crolling tree\n";
@@ -6771,7 +6787,7 @@
 
 static void outputPaintOrderTreeRecursive(TextStream& stream, const WebCore::RenderLayer& layer, const char* prefix, unsigned depth = 0)
 {
-    stream << (layer.isStackingContext() ? "S" : "-");
+    stream << (layer.isCSSStackingContext() ? "S" : (layer.isForcedStackingContext() ? "F" : (layer.isOpportunisticStackingContext() ? "P" : "-")));
     stream << (layer.isNormalFlowOnly() ? "N" : "-");
     stream << (layer.renderer().hasOverflowClip() ? "O" : "-");
     stream << (layer.isTransparent() ? "A" : "-");

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (244508 => 244509)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2019-04-22 19:51:38 UTC (rev 244508)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2019-04-22 19:57:58 UTC (rev 244509)
@@ -166,8 +166,16 @@
     void removeOnlyThisLayer();
 
     bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
-    bool isStackingContext() const { return m_isStackingContext; }
 
+    // isStackingContext is true for layers that we've determined should be stacking contexts for painting.
+    // Not all stacking contexts are CSS stacking contexts.
+    bool isStackingContext() const { return isCSSStackingContext() || m_isOpportunisticStackingContext; }
+
+    // isCSSStackingContext is true for layers that are stacking contexts from a CSS perspective.
+    // isCSSStackingContext() => isStackingContext().
+    // FIXME: m_forcedStackingContext should affect isStackingContext(), not isCSSStackingContext(), but doing so breaks media control mix-blend-mode.
+    bool isCSSStackingContext() const { return m_isCSSStackingContext || m_forcedStackingContext; }
+
     // Gets the enclosing stacking context for this layer, excluding this layer itself.
     RenderLayer* stackingContext() const;
 
@@ -500,6 +508,7 @@
 
     bool isRenderViewLayer() const { return m_isRenderViewLayer; }
     bool isForcedStackingContext() const { return m_forcedStackingContext; }
+    bool isOpportunisticStackingContext() const { return m_isOpportunisticStackingContext; }
 
     RenderLayerCompositor& compositor() const;
     
@@ -781,7 +790,7 @@
     bool hasBlendMode() const { return renderer().hasBlendMode(); }
     BlendMode blendMode() const { return static_cast<BlendMode>(m_blendMode); }
 
-    bool isolatesCompositedBlending() const { return m_hasNotIsolatedCompositedBlendingDescendants && isStackingContext(); }
+    bool isolatesCompositedBlending() const { return m_hasNotIsolatedCompositedBlendingDescendants && isCSSStackingContext(); }
     bool hasNotIsolatedCompositedBlendingDescendants() const { return m_hasNotIsolatedCompositedBlendingDescendants; }
     void setHasNotIsolatedCompositedBlendingDescendants(bool hasNotIsolatedCompositedBlendingDescendants)
     {
@@ -788,7 +797,7 @@
         m_hasNotIsolatedCompositedBlendingDescendants = hasNotIsolatedCompositedBlendingDescendants;
     }
 
-    bool isolatesBlending() const { return hasNotIsolatedBlendingDescendants() && isStackingContext(); }
+    bool isolatesBlending() const { return hasNotIsolatedBlendingDescendants() && isCSSStackingContext(); }
     
     // FIXME: We should ASSERT(!m_hasNotIsolatedBlendingDescendantsStatusDirty); here but we hit the same bugs as visible content above.
     bool hasNotIsolatedBlendingDescendants() const { return m_hasNotIsolatedBlendingDescendants; }
@@ -882,12 +891,16 @@
     void dirtyPaintOrderListsOnChildChange(RenderLayer&);
 
     bool shouldBeNormalFlowOnly() const;
-    bool shouldBeStackingContext() const;
-    
+    bool shouldBeCSSStackingContext() const;
+
     // Return true if changed.
     bool setIsNormalFlowOnly(bool);
-    bool setIsStackingContext(bool);
 
+    bool setIsOpportunisticStackingContext(bool);
+    bool setIsCSSStackingContext(bool);
+    
+    void isStackingContextChanged();
+
     bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
 
     void updateZOrderLists();
@@ -1169,7 +1182,8 @@
     const bool m_forcedStackingContext : 1;
 
     bool m_isNormalFlowOnly : 1;
-    bool m_isStackingContext : 1;
+    bool m_isCSSStackingContext : 1;
+    bool m_isOpportunisticStackingContext : 1;
 
     bool m_zOrderListsDirty : 1;
     bool m_normalFlowListDirty: 1;

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (244508 => 244509)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2019-04-22 19:51:38 UTC (rev 244508)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2019-04-22 19:57:58 UTC (rev 244509)
@@ -1897,7 +1897,7 @@
     for (auto* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
         // We only care about parents that are stacking contexts.
         // Recall that opacity creates stacking context.
-        if (!curr->isStackingContext())
+        if (!curr->isCSSStackingContext())
             continue;
         
         // If we found a compositing layer, we want to compute opacity

Modified: trunk/Source/WebCore/rendering/RenderTreeAsText.cpp (244508 => 244509)


--- trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2019-04-22 19:51:38 UTC (rev 244508)
+++ trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2019-04-22 19:57:58 UTC (rev 244509)
@@ -712,7 +712,7 @@
         
     if (negativeZOrderLayers.size()) {
         if (behavior & RenderAsTextShowLayerNesting) {
-            ts << indent << " negative z-order list(" << negativeZOrderLayers.size() << ")\n";
+            ts << indent << " negative z-order list (" << negativeZOrderLayers.size() << ")\n";
             ts.increaseIndent();
         }
         
@@ -745,7 +745,7 @@
     auto normalFlowLayers = layer.normalFlowLayers();
     if (normalFlowLayers.size()) {
         if (behavior & RenderAsTextShowLayerNesting) {
-            ts << indent << " normal flow list(" << normalFlowLayers.size() << ")\n";
+            ts << indent << " normal flow list (" << normalFlowLayers.size() << ")\n";
             ts.increaseIndent();
         }
         
@@ -762,7 +762,7 @@
 
         if (layerCount) {
             if (behavior & RenderAsTextShowLayerNesting) {
-                ts << indent << " positive z-order list(" << layerCount << ")\n";
+                ts << indent << " positive z-order list (" << layerCount << ")\n";
                 ts.increaseIndent();
             }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to