Title: [270200] trunk/Source/WebCore
Revision
270200
Author
simon.fra...@apple.com
Date
2020-11-27 10:50:25 -0800 (Fri, 27 Nov 2020)

Log Message

[LFC Display] Clean up CSS stacking context painting code
https://bugs.webkit.org/show_bug.cgi?id=219307

Reviewed by Antti Koivisto.

Clarify the code in Display::CSSPainter that paints stacking contexts and positioned
elements. Non-stacking positioned elements paint atomically, but don't paint descendant
stacking contexts (sometimes these are called "pseudo-stacking contexts" but that term
is avoided here to reduce confusion). Share code between painting these and stacking
contexts via paintAtomicallyPaintedBox().

Also make sure we paint the contents of non-container child boxes, so that things like
positioned images paint.

Remove some incorrect image painting code in BoxPainter::paintBox().

* display/DisplayTreeBuilder.cpp:
(WebCore::Display::TreeBuilder::recursiveBuildDisplayTree const):
* display/css/DisplayBoxPainter.cpp:
(WebCore::Display::BoxPainter::paintBox):
* display/css/DisplayCSSPainter.cpp:
(WebCore::Display::CSSPainter::recursivePaintDescendantsForPhase):
(WebCore::Display::CSSPainter::recursivePaintDescendants):
(WebCore::Display::CSSPainter::paintAtomicallyPaintedBox):
(WebCore::Display::CSSPainter::paintStackingContext):
(WebCore::Display::CSSPainter::participatesInZOrderSorting):
(WebCore::Display::CSSPainter::collectStackingContextDescendants):
(WebCore::Display::CSSPainter::recursiveCollectLayers):
* display/css/DisplayCSSPainter.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (270199 => 270200)


--- trunk/Source/WebCore/ChangeLog	2020-11-27 18:49:07 UTC (rev 270199)
+++ trunk/Source/WebCore/ChangeLog	2020-11-27 18:50:25 UTC (rev 270200)
@@ -1,5 +1,37 @@
 2020-11-27  Simon Fraser  <simon.fra...@apple.com>
 
+        [LFC Display] Clean up CSS stacking context painting code
+        https://bugs.webkit.org/show_bug.cgi?id=219307
+
+        Reviewed by Antti Koivisto.
+
+        Clarify the code in Display::CSSPainter that paints stacking contexts and positioned
+        elements. Non-stacking positioned elements paint atomically, but don't paint descendant
+        stacking contexts (sometimes these are called "pseudo-stacking contexts" but that term
+        is avoided here to reduce confusion). Share code between painting these and stacking
+        contexts via paintAtomicallyPaintedBox().
+
+        Also make sure we paint the contents of non-container child boxes, so that things like
+        positioned images paint.
+
+        Remove some incorrect image painting code in BoxPainter::paintBox().
+
+        * display/DisplayTreeBuilder.cpp:
+        (WebCore::Display::TreeBuilder::recursiveBuildDisplayTree const):
+        * display/css/DisplayBoxPainter.cpp:
+        (WebCore::Display::BoxPainter::paintBox):
+        * display/css/DisplayCSSPainter.cpp:
+        (WebCore::Display::CSSPainter::recursivePaintDescendantsForPhase):
+        (WebCore::Display::CSSPainter::recursivePaintDescendants):
+        (WebCore::Display::CSSPainter::paintAtomicallyPaintedBox):
+        (WebCore::Display::CSSPainter::paintStackingContext):
+        (WebCore::Display::CSSPainter::participatesInZOrderSorting):
+        (WebCore::Display::CSSPainter::collectStackingContextDescendants):
+        (WebCore::Display::CSSPainter::recursiveCollectLayers):
+        * display/css/DisplayCSSPainter.h:
+
+2020-11-27  Simon Fraser  <simon.fra...@apple.com>
+
         [LFC Display] A ContainerBox can establish an inline formatting context and have box children
         https://bugs.webkit.org/show_bug.cgi?id=218736
 

Modified: trunk/Source/WebCore/display/css/DisplayBoxPainter.cpp (270199 => 270200)


--- trunk/Source/WebCore/display/css/DisplayBoxPainter.cpp	2020-11-27 18:49:07 UTC (rev 270199)
+++ trunk/Source/WebCore/display/css/DisplayBoxPainter.cpp	2020-11-27 18:50:25 UTC (rev 270200)
@@ -94,16 +94,6 @@
     if (!dirtyRect.intersects(enclosingIntRect(absoluteRect)))
         return;
 
-    if (is<ImageBox>(box)) {
-        auto& imageBox = downcast<ImageBox>(box);
-        
-        auto* image = imageBox.image();
-        auto imageRect = imageBox.replacedContentRect();
-
-        if (image)
-            paintingContext.context.drawImage(*image, imageRect);
-    }
-
     if (is<BoxModelBox>(box))
         paintBoxDecorations(downcast<BoxModelBox>(box), paintingContext);
 

Modified: trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp (270199 => 270200)


--- trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp	2020-11-27 18:49:07 UTC (rev 270199)
+++ trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp	2020-11-27 18:50:25 UTC (rev 270200)
@@ -40,11 +40,11 @@
 namespace Display {
 
 // FIXME: Make this an iterator.
-void CSSPainter::recursivePaintDescendants(const ContainerBox& containerBox, PaintingContext& paintingContext, PaintPhase paintPhase)
+void CSSPainter::recursivePaintDescendantsForPhase(const ContainerBox& containerBox, PaintingContext& paintingContext, PaintPhase paintPhase)
 {
     for (const auto* child = containerBox.firstChild(); child; child = child->nextSibling()) {
         auto& box = *child;
-        if (isStackingContextPaintingBoundary(box))
+        if (participatesInZOrderSorting(box))
             continue;
 
         switch (paintPhase) {
@@ -61,57 +61,54 @@
                 BoxPainter::paintBoxContent(box, paintingContext);
         };
         if (is<ContainerBox>(box))
-            recursivePaintDescendants(downcast<ContainerBox>(box), paintingContext, paintPhase);
+            recursivePaintDescendantsForPhase(downcast<ContainerBox>(box), paintingContext, paintPhase);
     }
 }
 
-void CSSPainter::paintStackingContext(const BoxModelBox& contextRoot, PaintingContext& paintingContext, const IntRect& dirtyRect)
+void CSSPainter::recursivePaintDescendants(const ContainerBox& containerBox, PaintingContext& paintingContext)
 {
-    UNUSED_PARAM(dirtyRect);
-    
-    BoxPainter::paintBoxDecorations(contextRoot, paintingContext);
+    // For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block equivalent:
+    // Box decorations.
+    // Table decorations.
+    recursivePaintDescendantsForPhase(containerBox, paintingContext, PaintPhase::BlockBackgrounds);
 
-    auto paintDescendants = [&](const ContainerBox& containerBox) {
-        // For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block equivalent:
-        // Box decorations.
-        // Table decorations.
-        recursivePaintDescendants(containerBox, paintingContext, PaintPhase::BlockBackgrounds);
+    // All non-positioned floating descendants, in tree order. For each one of these, treat the element as if it created a new stacking context,
+    // but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent
+    // stacking context, not this new one.
+    recursivePaintDescendantsForPhase(containerBox, paintingContext, PaintPhase::Floats);
 
-        // All non-positioned floating descendants, in tree order. For each one of these, treat the element as if it created a new stacking context,
-        // but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent
-        // stacking context, not this new one.
-        recursivePaintDescendants(containerBox, paintingContext, PaintPhase::Floats);
+    // If the element is an inline element that generates a stacking context, then:
+    // FIXME: Handle this case.
+    
+    // Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
+    // 1. If the element is a block-level replaced element, then: the replaced content, atomically.
+    // 2. Otherwise, for each line box of that element...
+    recursivePaintDescendantsForPhase(containerBox, paintingContext, PaintPhase::BlockForegrounds);
+}
 
-        // If the element is an inline element that generates a stacking context, then:
-        // FIXME: Handle this case.
-        
-        // Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
-        // 1. If the element is a block-level replaced element, then: the replaced content, atomically.
-        // 2. Otherwise, for each line box of that element...
-        recursivePaintDescendants(containerBox, paintingContext, PaintPhase::BlockForegrounds);
-    };
-
-    if (is<ContainerBox>(contextRoot)) {
-        auto& containerBox = downcast<ContainerBox>(contextRoot);
-
-        Vector<const BoxModelBox*> negativeZOrderList;
-        Vector<const BoxModelBox*> positiveZOrderList;
+void CSSPainter::paintAtomicallyPaintedBox(const Box& box, PaintingContext& paintingContext, const IntRect& dirtyRect, IncludeStackingContextDescendants includeStackingContextDescendants)
+{
+    UNUSED_PARAM(dirtyRect);
     
-        recursiveCollectLayers(containerBox, negativeZOrderList, positiveZOrderList);
+    BoxPainter::paintBox(box, paintingContext, dirtyRect);
+    if (!is<ContainerBox>(box))
+        return;
 
-        auto compareZIndex = [] (const BoxModelBox* a, const BoxModelBox* b) {
-            return a->style().zIndex().valueOr(0) < b->style().zIndex().valueOr(0);
-        };
+    auto& containerBox = downcast<ContainerBox>(box);
 
-        std::stable_sort(positiveZOrderList.begin(), positiveZOrderList.end(), compareZIndex);
-        std::stable_sort(negativeZOrderList.begin(), negativeZOrderList.end(), compareZIndex);
+    Vector<const BoxModelBox*> negativeZOrderList;
+    Vector<const BoxModelBox*> positiveZOrderList;
+    if (includeStackingContextDescendants == IncludeStackingContextDescendants::Yes) {
+        collectStackingContextDescendants(containerBox, negativeZOrderList, positiveZOrderList);
 
         // Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then tree order.
         for (auto* box : negativeZOrderList)
             paintStackingContext(*box, paintingContext, dirtyRect);
+    }
 
-        paintDescendants(containerBox);
+    recursivePaintDescendants(containerBox, paintingContext);
 
+    if (includeStackingContextDescendants == IncludeStackingContextDescendants::Yes) {
         // All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order. For those with 'z-index: auto', treat the element
         // as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context
         // should be considered part of the parent stacking context, not this new one. For those with 'z-index: 0', treat the stacking context
@@ -119,20 +116,39 @@
         for (auto* box : positiveZOrderList) {
             if (box->style().isStackingContext())
                 paintStackingContext(*box, paintingContext, dirtyRect);
-            else if (is<ContainerBox>(*box)) {
-                BoxPainter::paintBoxDecorations(*box, paintingContext);
-                paintDescendants(downcast<ContainerBox>(*box));
-            } else
-                BoxPainter::paintBox(*box, paintingContext, dirtyRect);
+            else
+                paintAtomicallyPaintedBox(*box, paintingContext, dirtyRect);
         }
     }
 }
 
+void CSSPainter::paintStackingContext(const BoxModelBox& contextRoot, PaintingContext& paintingContext, const IntRect& dirtyRect)
+{
+    paintAtomicallyPaintedBox(contextRoot, paintingContext, dirtyRect, IncludeStackingContextDescendants::Yes);
+}
+
 bool CSSPainter::isStackingContextPaintingBoundary(const Box& box)
 {
     return box.style().isStackingContext();
 }
 
+bool CSSPainter::participatesInZOrderSorting(const Box& box)
+{
+    return box.style().participatesInZOrderSorting();
+}
+
+void CSSPainter::collectStackingContextDescendants(const ContainerBox& containerBox, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList)
+{
+    recursiveCollectLayers(containerBox, negativeZOrderList, positiveZOrderList);
+
+    auto compareZIndex = [] (const BoxModelBox* a, const BoxModelBox* b) {
+        return a->style().zIndex().valueOr(0) < b->style().zIndex().valueOr(0);
+    };
+
+    std::stable_sort(positiveZOrderList.begin(), positiveZOrderList.end(), compareZIndex);
+    std::stable_sort(negativeZOrderList.begin(), negativeZOrderList.end(), compareZIndex);
+}
+
 void CSSPainter::recursiveCollectLayers(const ContainerBox& containerBox, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList)
 {
     for (const auto* child = containerBox.firstChild(); child; child = child->nextSibling()) {
@@ -140,7 +156,6 @@
             auto& childBox = downcast<BoxModelBox>(*child);
 
             auto zIndex = childBox.style().zIndex().valueOr(0);
-
             if (zIndex < 0)
                 negativeZOrderList.append(&childBox);
             else

Modified: trunk/Source/WebCore/display/css/DisplayCSSPainter.h (270199 => 270200)


--- trunk/Source/WebCore/display/css/DisplayCSSPainter.h	2020-11-27 18:49:07 UTC (rev 270199)
+++ trunk/Source/WebCore/display/css/DisplayCSSPainter.h	2020-11-27 18:50:25 UTC (rev 270200)
@@ -48,7 +48,6 @@
 
 class CSSPainter {
 public:
-    static void paintStackingContext(const BoxModelBox&, PaintingContext&, const IntRect& dirtyRect);
     static void paintTree(const Tree&, PaintingContext&, const IntRect& dirtyRect);
 
 private:
@@ -57,9 +56,18 @@
         Floats,
         BlockForegrounds
     };
-    static void recursivePaintDescendants(const ContainerBox&, PaintingContext&, PaintPhase);
+    static void recursivePaintDescendants(const ContainerBox&, PaintingContext&);
+    static void recursivePaintDescendantsForPhase(const ContainerBox&, PaintingContext&, PaintPhase);
 
+    enum class IncludeStackingContextDescendants { Yes, No };
+    static void paintAtomicallyPaintedBox(const Box&, PaintingContext&, const IntRect& dirtyRect, IncludeStackingContextDescendants = IncludeStackingContextDescendants::No);
+
+    static void paintStackingContext(const BoxModelBox&, PaintingContext&, const IntRect& dirtyRect);
+
     static bool isStackingContextPaintingBoundary(const Box&);
+    static bool participatesInZOrderSorting(const Box&);
+
+    static void collectStackingContextDescendants(const ContainerBox&, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList);
     static void recursiveCollectLayers(const ContainerBox&, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList);
 };
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to