Commit c316136c authored by achicu@adobe.com's avatar achicu@adobe.com
Browse files

[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:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@114518 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 4e5d8f96
2012-04-18 Alexandru Chiculita <achicu@adobe.com>
[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 <pilgrim@chromium.org>
 
Followup to "Call incrementStatsCounter directly"
......@@ -2983,7 +2983,7 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* co
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 @@ IntRect RenderLayer::absoluteBoundingBox() const
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 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* layer, const Render
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 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* layer, const Render
// 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 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* layer, const Render
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);
......
......@@ -485,7 +485,14 @@ public:
// 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&);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment