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);