Modified: trunk/Source/WebCore/ChangeLog (114517 => 114518)
--- trunk/Source/WebCore/ChangeLog 2012-04-18 16:33:06 UTC (rev 114517)
+++ trunk/Source/WebCore/ChangeLog 2012-04-18 16:34:32 UTC (rev 114518)
@@ -1,3 +1,23 @@
+2012-04-18 Alexandru Chiculita <[email protected]>
+
+ [CSS Filters] Do not use clipping rect when calculating the bounds of a layer
+ https://bugs.webkit.org/show_bug.cgi?id=83960
+
+ Reviewed by Simon Fraser.
+
+ The local clip rect should not be used when calculating the bounds of a filter area. Otherwise
+ drop-shadow might not know about the pixels outside the clipping rectangle, even though the actual shadow might
+ be inside it.
+
+ No new tests added in this patch, but this patch fixes two existing tests that fail.
+ LayoutTests/css3/filters/filter-repaint-shadow-clipped.html
+ LayoutTests/css3/filters/filter-repaint-shadow-rotated.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayerContents):
+ (WebCore::RenderLayer::calculateLayerBounds):
+ * rendering/RenderLayer.h:
+
2012-04-18 Mark Pilgrim <[email protected]>
Followup to "Call incrementStatsCounter directly"
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (114517 => 114518)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-04-18 16:33:06 UTC (rev 114517)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-04-18 16:34:32 UTC (rev 114518)
@@ -2983,7 +2983,7 @@
LayoutPoint rootLayerOffset;
convertToLayerCoords(rootLayer, rootLayerOffset);
m_filterRepaintRect.move(rootLayerOffset.x(), rootLayerOffset.y());
- LayoutRect filterPaintDirtyRect = filterPainter.prepareFilterEffect(this, calculateLayerBounds(this, rootLayer, false, false), parentPaintDirtyRect, m_filterRepaintRect);
+ LayoutRect filterPaintDirtyRect = filterPainter.prepareFilterEffect(this, calculateLayerBounds(this, rootLayer, 0), parentPaintDirtyRect, m_filterRepaintRect);
m_filterRepaintRect = IntRect();
// Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
// NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
@@ -4100,7 +4100,7 @@
return pixelSnappedIntRect(boundingBox(root()));
}
-IntRect RenderLayer::calculateLayerBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer, bool includeSelfTransform, bool includeLayerFilterOutsets)
+IntRect RenderLayer::calculateLayerBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags flags)
{
if (!layer->isSelfPaintingLayer())
return IntRect();
@@ -4121,12 +4121,14 @@
LayoutRect unionBounds = boundingBoxRect;
- LayoutRect localClipRect = layer->localClipRect();
- if (localClipRect != PaintInfo::infiniteRect()) {
- LayoutPoint ancestorRelOffset;
- layer->convertToLayerCoords(ancestorLayer, ancestorRelOffset);
- localClipRect.moveBy(ancestorRelOffset);
- return pixelSnappedIntRect(localClipRect);
+ if (flags & UseLocalClipRectIfPossible) {
+ LayoutRect localClipRect = layer->localClipRect();
+ if (localClipRect != PaintInfo::infiniteRect()) {
+ LayoutPoint ancestorRelOffset;
+ layer->convertToLayerCoords(ancestorLayer, ancestorRelOffset);
+ localClipRect.moveBy(ancestorRelOffset);
+ return pixelSnappedIntRect(localClipRect);
+ }
}
if (RenderLayer* reflection = layer->reflectionLayer()) {
@@ -4179,7 +4181,7 @@
// FIXME: We can optimize the size of the composited layers, by not enlarging
// filtered areas with the outsets if we know that the filter is going to render in hardware.
// https://bugs.webkit.org/show_bug.cgi?id=81239
- if (includeLayerFilterOutsets && layer->renderer()->style()->hasFilterOutsets()) {
+ if ((flags & IncludeLayerFilterOutsets) && layer->renderer()->style()->hasFilterOutsets()) {
int topOutset;
int rightOutset;
int bottomOutset;
@@ -4188,11 +4190,9 @@
unionBounds.move(-leftOutset, -topOutset);
unionBounds.expand(leftOutset + rightOutset, topOutset + bottomOutset);
}
-#else
- UNUSED_PARAM(includeLayerFilterOutsets);
#endif
- if (includeSelfTransform && layer->paintsWithTransform(PaintBehaviorNormal)) {
+ if ((flags & IncludeSelfTransform) && layer->paintsWithTransform(PaintBehaviorNormal)) {
TransformationMatrix* affineTrans = layer->transform();
boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
unionBounds = affineTrans->mapRect(unionBounds);
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (114517 => 114518)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2012-04-18 16:33:06 UTC (rev 114517)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2012-04-18 16:34:32 UTC (rev 114518)
@@ -485,7 +485,14 @@
// Pixel snapped bounding box relative to the root.
IntRect absoluteBoundingBox() const;
- static IntRect calculateLayerBounds(const RenderLayer*, const RenderLayer* ancestorLayer, bool includeSelfTransform = true, bool includeLayerFilterOutsets = true);
+ enum CalculateLayerBoundsFlag {
+ IncludeSelfTransform = 1 << 0,
+ UseLocalClipRectIfPossible = 1 << 1,
+ IncludeLayerFilterOutsets = 1 << 2,
+ DefaultCalculateLayerBoundsFlags = IncludeSelfTransform | UseLocalClipRectIfPossible | IncludeLayerFilterOutsets
+ };
+ typedef unsigned CalculateLayerBoundsFlags;
+ static IntRect calculateLayerBounds(const RenderLayer*, const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags);
void updateHoverActiveState(const HitTestRequest&, HitTestResult&);