Title: [143070] trunk
Revision
143070
Author
simon.fra...@apple.com
Date
2013-02-15 16:55:44 -0800 (Fri, 15 Feb 2013)

Log Message

drop-shadow filter with overflow:hidden child misbehaves
https://bugs.webkit.org/show_bug.cgi?id=109783

Source/WebCore:

Reviewed by Dean Jackson.

The change in r112745 was not sufficient; it failed to account
for descendant layers that needed to not clipping to avoid artefacts
with filters like drop-shadow.

Test: css3/filters/filter-repaint-shadow-layer-child.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerContents): Remove the useClipRect bool.
Replace it with a clipToDirtyRect member on the LayerPaintingInfo, which
gets passed to descendants. Remove some "Restore the clip" comments that added
nothing.
* rendering/RenderLayer.h:
(WebCore::RenderLayer::LayerPaintingInfo::LayerPaintingInfo):
(LayerPaintingInfo):

LayoutTests:

Reviewed by Dean Jackson.

* css3/filters/filter-repaint-shadow-layer-child-expected.html: Added.
* css3/filters/filter-repaint-shadow-layer-child.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (143069 => 143070)


--- trunk/LayoutTests/ChangeLog	2013-02-16 00:52:07 UTC (rev 143069)
+++ trunk/LayoutTests/ChangeLog	2013-02-16 00:55:44 UTC (rev 143070)
@@ -1,3 +1,13 @@
+2013-02-15  Simon Fraser  <simon.fra...@apple.com>
+
+        drop-shadow filter with overflow:hidden child misbehaves
+        https://bugs.webkit.org/show_bug.cgi?id=109783
+
+        Reviewed by Dean Jackson.
+
+        * css3/filters/filter-repaint-shadow-layer-child-expected.html: Added.
+        * css3/filters/filter-repaint-shadow-layer-child.html: Added.
+
 2013-02-15  Elliott Sprehn  <espr...@chromium.org>
 
         RenderQuote should not mark renderers as needing layout during layout

Added: trunk/LayoutTests/css3/filters/filter-repaint-shadow-layer-child-expected.html (0 => 143070)


--- trunk/LayoutTests/css3/filters/filter-repaint-shadow-layer-child-expected.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/filter-repaint-shadow-layer-child-expected.html	2013-02-16 00:55:44 UTC (rev 143070)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .box {
+            margin: 50px;
+            height: 150px;
+            width: 150px;
+        }
+
+        .shadow {
+            margin: 20px;
+            height: 300px;
+            width: 300px;
+            background-color: silver;
+            border: 1px solid black;
+            -webkit-filter: drop-shadow(10px 10px 10px blue);
+        }
+    </style>
+</head>
+
+<body>
+
+    <div class="shadow">
+    </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/css3/filters/filter-repaint-shadow-layer-child.html (0 => 143070)


--- trunk/LayoutTests/css3/filters/filter-repaint-shadow-layer-child.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/filter-repaint-shadow-layer-child.html	2013-02-16 00:55:44 UTC (rev 143070)
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .box {
+            margin: 50px;
+            height: 150px;
+            width: 150px;
+        }
+
+        .before {
+            overflow-y: scroll;
+            background-color: red;
+        }
+
+        .shadow {
+            margin: 20px;
+            height: 300px;
+            width: 300px;
+            background-color: silver;
+            border: 1px solid black;
+            -webkit-filter: drop-shadow(10px 10px 10px blue);
+        }
+    </style>
+
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        function doTest()
+        {
+            window.setTimeout(function() {
+                document.querySelector(".before").classList.remove("before");
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+
+<body>
+
+    <!-- You should not seen part of a blue shadow inside the gray box. -->
+    <div class="shadow">
+        <div class="before box"></div>
+    </div>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (143069 => 143070)


--- trunk/Source/WebCore/ChangeLog	2013-02-16 00:52:07 UTC (rev 143069)
+++ trunk/Source/WebCore/ChangeLog	2013-02-16 00:55:44 UTC (rev 143070)
@@ -1,3 +1,25 @@
+2013-02-15  Simon Fraser  <simon.fra...@apple.com>
+
+        drop-shadow filter with overflow:hidden child misbehaves
+        https://bugs.webkit.org/show_bug.cgi?id=109783
+
+        Reviewed by Dean Jackson.
+        
+        The change in r112745 was not sufficient; it failed to account
+        for descendant layers that needed to not clipping to avoid artefacts
+        with filters like drop-shadow.
+
+        Test: css3/filters/filter-repaint-shadow-layer-child.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayerContents): Remove the useClipRect bool.
+        Replace it with a clipToDirtyRect member on the LayerPaintingInfo, which
+        gets passed to descendants. Remove some "Restore the clip" comments that added
+        nothing.
+        * rendering/RenderLayer.h:
+        (WebCore::RenderLayer::LayerPaintingInfo::LayerPaintingInfo):
+        (LayerPaintingInfo):
+
 2013-02-15  Sheriff Bot  <webkit.review....@gmail.com>
 
         Unreviewed, rolling out r143066.

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (143069 => 143070)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-02-16 00:52:07 UTC (rev 143069)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-02-16 00:55:44 UTC (rev 143070)
@@ -3585,7 +3585,6 @@
     bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars;
     bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
 
-    bool useClipRect = true;
     GraphicsContext* transparencyLayerContext = context;
     
     if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isRoot())
@@ -3685,7 +3684,7 @@
                 // If the filter needs the full source image, we need to avoid using the clip rectangles.
                 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
                 // Note that we will still apply the clipping on the final rendering of the filter.
-                useClipRect = !filterRenderer()->hasFilterThatMovesPixels();
+                localPaintingInfo.clipToDirtyRect = !filterRenderer()->hasFilterThatMovesPixels();
             }
         }
     }
@@ -3732,7 +3731,7 @@
             if (haveTransparency)
                 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
         
-            if (useClipRect) {
+            if (localPaintingInfo.clipToDirtyRect) {
                 // Paint our background first, before painting any child layers.
                 // Establish the clip used to paint our background.
                 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
@@ -3742,10 +3741,8 @@
             PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, localPaintingInfo.region);
             renderer()->paint(paintInfo, paintOffset);
 
-            if (useClipRect) {
-                // Restore the clip.
+            if (localPaintingInfo.clipToDirtyRect)
                 restoreClip(context, localPaintingInfo.paintDirtyRect, damageRect);
-            }
         }
 
         // Now walk the sorted list of children with negative z-indices.
@@ -3759,7 +3756,7 @@
             if (haveTransparency)
                 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
 
-            if (useClipRect) {
+            if (localPaintingInfo.clipToDirtyRect) {
                 // Set up the clip used when painting our children.
                 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, clipRectToApply);
             }
@@ -3778,10 +3775,8 @@
                 renderer()->paint(paintInfo, paintOffset);
             }
 
-            if (useClipRect) {
-                // Now restore our clip.
+            if (localPaintingInfo.clipToDirtyRect)
                 restoreClip(context, localPaintingInfo.paintDirtyRect, clipRectToApply);
-            }
         }
 
         if (shouldPaintOutline && !outlineRect.isEmpty()) {
@@ -3818,17 +3813,15 @@
     ASSERT(transparencyLayerContext == context);
 
     if ((localPaintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly) {
-        if (useClipRect)
+        if (localPaintingInfo.clipToDirtyRect)
             clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
         
         // Paint the mask.
         PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region);
         renderer()->paint(paintInfo, paintOffset);
         
-        if (useClipRect) {
-            // Restore the clip.
+        if (localPaintingInfo.clipToDirtyRect)
             restoreClip(context, localPaintingInfo.paintDirtyRect, damageRect);
-        }
     }
 
     // End our transparency layer

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (143069 => 143070)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2013-02-16 00:52:07 UTC (rev 143069)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2013-02-16 00:55:44 UTC (rev 143070)
@@ -867,6 +867,7 @@
             , region(inRegion)
             , overlapTestRequests(inOverlapTestRequests)
             , paintBehavior(inPaintBehavior)
+            , clipToDirtyRect(true)
         { }
         RenderLayer* rootLayer;
         RenderObject* paintingRoot; // only paint descendants of this object
@@ -875,6 +876,7 @@
         RenderRegion* region; // May be null.
         OverlapTestRequestMap* overlapTestRequests; // May be null.
         PaintBehavior paintBehavior;
+        bool clipToDirtyRect;
     };
         
     void paintLayer(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to