Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (134355 => 134356)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-11-13 05:24:31 UTC (rev 134355)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-11-13 05:24:49 UTC (rev 134356)
@@ -3173,17 +3173,18 @@
bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars;
bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
- // Calculate the clip rects we should use only when we need them.
- LayoutRect layerBounds;
- ClipRect damageRect, clipRectToApply, outlineRect;
- LayoutPoint paintOffset;
-
bool useClipRect = true;
GraphicsContext* transparencyLayerContext = context;
// Ensure our lists are up-to-date.
updateLayerListsIfNeeded();
+ LayoutPoint offsetFromRoot;
+ convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
+
+ IntRect rootRelativeBounds;
+ bool rootRelativeBoundsComputed = false;
+
bool didQuantizeFonts = true;
bool scrollingOnMainThread = true;
Frame* frame = renderer()->frame();
@@ -3213,7 +3214,13 @@
hasClipPath = true;
context->save();
ShapeClipPathOperation* clipPath = static_cast<ShapeClipPathOperation*>(style->clipPath());
- context->clipPath(clipPath->path(calculateLayerBounds(paintingInfo.rootLayer, 0)), clipPath->windRule());
+
+ if (!rootRelativeBoundsComputed) {
+ rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
+ rootRelativeBoundsComputed = true;
+ }
+
+ context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule());
}
#if ENABLE(SVG)
else if (style->clipPath()->getOperationType() == ClipPathOperation::REFERENCE) {
@@ -3221,8 +3228,14 @@
Document* document = renderer()->document();
// FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
Element* element = document ? document->getElementById(referenceClipPathOperation->fragment()) : 0;
- if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer())
- static_cast<RenderSVGResourceClipper*>(element->renderer())->applyClippingToContext(renderer(), calculateLayerBounds(paintingInfo.rootLayer, 0), paintingInfo.paintDirtyRect, context);
+ if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer()) {
+ if (!rootRelativeBoundsComputed) {
+ rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
+ rootRelativeBoundsComputed = true;
+ }
+
+ static_cast<RenderSVGResourceClipper*>(element->renderer())->applyClippingToContext(renderer(), rootRelativeBounds, paintingInfo.paintDirtyRect, context);
+ }
}
#endif
}
@@ -3231,13 +3244,17 @@
#if ENABLE(CSS_FILTERS)
FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
- LayoutPoint rootLayerOffset;
- convertToLayerCoords(paintingInfo.rootLayer, rootLayerOffset);
RenderLayerFilterInfo* filterInfo = this->filterInfo();
ASSERT(filterInfo);
LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
- filterRepaintRect.move(rootLayerOffset.x(), rootLayerOffset.y());
- if (filterPainter.prepareFilterEffect(this, calculateLayerBounds(paintingInfo.rootLayer, 0), paintingInfo.paintDirtyRect, filterRepaintRect)) {
+ filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y());
+
+ if (!rootRelativeBoundsComputed) {
+ rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
+ rootRelativeBoundsComputed = true;
+ }
+
+ if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect, filterRepaintRect)) {
// Now we know for sure, that the source image will be updated, so we can revert our tracking repaint rect back to zero.
filterInfo->resetDirtySourceRect();
@@ -3258,9 +3275,14 @@
}
}
#endif
-
+
+ // Calculate the clip rects we should use only when we need them.
+ LayoutRect layerBounds;
+ ClipRect damageRect, clipRectToApply, outlineRect;
+ LayoutPoint paintOffset;
+
if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
- calculateRects(localPaintingInfo.rootLayer, localPaintingInfo.region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, localPaintingInfo.paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect,
+ calculateRects(localPaintingInfo.rootLayer, localPaintingInfo.region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, localPaintingInfo.paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, &offsetFromRoot,
IgnoreOverlayScrollbarSize, localPaintFlags & PaintLayerPaintingOverflowContents ? IgnoreOverflowClip : RespectOverflowClip);
paintOffset = toPoint(layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation);
if (this == localPaintingInfo.rootLayer)
@@ -3283,7 +3305,7 @@
// We want to paint our layer, but only if we intersect the damage rect.
if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents))
- shouldPaintContent &= intersectsDamageRect(layerBounds, damageRect.rect(), localPaintingInfo.rootLayer);
+ shouldPaintContent &= intersectsDamageRect(layerBounds, damageRect.rect(), localPaintingInfo.rootLayer, &offsetFromRoot);
if (localPaintFlags & PaintLayerPaintingCompositingBackgroundPhase) {
if (shouldPaintContent && !selectionOnly) {
@@ -3759,7 +3781,7 @@
ClipRect bgRect;
ClipRect fgRect;
ClipRect outlineRect;
- calculateRects(rootLayer, hitTestLocation.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, IncludeOverlayScrollbarSize);
+ calculateRects(rootLayer, hitTestLocation.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, 0, IncludeOverlayScrollbarSize);
// The following are used for keeping track of the z-depth of the hit point of 3d-transformed
// descendants.
@@ -4180,7 +4202,8 @@
}
void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
- ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, OverlayScrollbarSizeRelevancy relevancy, ShouldRespectOverflowClip respectOverflowClip) const
+ ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot,
+ OverlayScrollbarSizeRelevancy relevancy, ShouldRespectOverflowClip respectOverflowClip) const
{
if (rootLayer != this && parent()) {
backgroundRect = backgroundClipRect(rootLayer, region, clipRectsType, relevancy, respectOverflowClip);
@@ -4192,7 +4215,10 @@
outlineRect = backgroundRect;
LayoutPoint offset;
- convertToLayerCoords(rootLayer, offset);
+ if (offsetFromRoot)
+ offset = *offsetFromRoot;
+ else
+ convertToLayerCoords(rootLayer, offset);
layerBounds = LayoutRect(offset, size());
// Update the clip rects that will be passed to child layers.
@@ -4308,7 +4334,7 @@
renderer()->repaintRectangle(rect);
}
-bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer) const
+bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
{
// Always examine the canvas and the root.
// FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
@@ -4329,7 +4355,7 @@
// Otherwise we need to compute the bounding box of this single layer and see if it intersects
// the damage rect.
- return boundingBox(rootLayer).intersects(damageRect);
+ return boundingBox(rootLayer, offsetFromRoot).intersects(damageRect);
}
LayoutRect RenderLayer::localBoundingBox() const
@@ -4380,15 +4406,20 @@
return result;
}
-LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer) const
+LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot) const
{
LayoutRect result = localBoundingBox();
if (renderer()->isBox())
renderBox()->flipForWritingMode(result);
else
renderer()->containingBlock()->flipForWritingMode(result);
+
LayoutPoint delta;
- convertToLayerCoords(ancestorLayer, delta);
+ if (offsetFromRoot)
+ delta = *offsetFromRoot;
+ else
+ convertToLayerCoords(ancestorLayer, delta);
+
result.moveBy(delta);
return result;
}
@@ -4398,7 +4429,7 @@
return pixelSnappedIntRect(boundingBox(root()));
}
-IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags flags) const
+IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const
{
if (!isSelfPaintingLayer())
return IntRect();
@@ -4449,7 +4480,7 @@
if (RenderLayer* reflection = reflectionLayer()) {
if (!reflection->isComposited()) {
- IntRect childUnionBounds = reflection->calculateLayerBounds(this, descendantFlags);
+ IntRect childUnionBounds = reflection->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(childUnionBounds);
}
}
@@ -4465,7 +4496,7 @@
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
if (!curLayer->isComposited()) {
- IntRect childUnionBounds = curLayer->calculateLayerBounds(this, descendantFlags);
+ IntRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(childUnionBounds);
}
}
@@ -4476,7 +4507,7 @@
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
if (!curLayer->isComposited()) {
- IntRect childUnionBounds = curLayer->calculateLayerBounds(this, descendantFlags);
+ IntRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(childUnionBounds);
}
}
@@ -4487,7 +4518,7 @@
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
if (!curLayer->isComposited()) {
- IntRect curAbsBounds = curLayer->calculateLayerBounds(this, descendantFlags);
+ IntRect curAbsBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);
unionBounds.unite(curAbsBounds);
}
}
@@ -4515,7 +4546,10 @@
}
LayoutPoint ancestorRelOffset;
- convertToLayerCoords(ancestorLayer, ancestorRelOffset);
+ if (offsetFromRoot)
+ ancestorRelOffset = *offsetFromRoot;
+ else
+ convertToLayerCoords(ancestorLayer, ancestorRelOffset);
unionBounds.moveBy(ancestorRelOffset);
return pixelSnappedIntRect(unionBounds);
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (134355 => 134356)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2012-11-13 05:24:31 UTC (rev 134355)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2012-11-13 05:24:49 UTC (rev 134356)
@@ -532,8 +532,9 @@
// This method figures out our layerBounds in coordinates relative to
// |rootLayer}. It also computes our background and foreground clip rects
// for painting/event handling.
+ // Pass offsetFromRoot if known.
void calculateRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
- ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect,
+ ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot = 0,
OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip = RespectOverflowClip) const;
// Compute and cache clip rects computed with the given layer as the root
@@ -548,10 +549,11 @@
LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
LayoutRect localClipRect() const; // Returns the background clip rect of the layer in the local coordinate space.
- bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer) const;
+ // Pass offsetFromRoot if known.
+ bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0) const;
- // Bounding box relative to some ancestor layer.
- LayoutRect boundingBox(const RenderLayer* rootLayer) const;
+ // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known.
+ LayoutRect boundingBox(const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0) const;
// Bounding box in the coordinates of this layer.
LayoutRect localBoundingBox() const;
// Pixel snapped bounding box relative to the root.
@@ -565,7 +567,8 @@
DefaultCalculateLayerBoundsFlags = IncludeSelfTransform | UseLocalClipRectIfPossible | IncludeLayerFilterOutsets
};
typedef unsigned CalculateLayerBoundsFlags;
- IntRect calculateLayerBounds(const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;
+ // Can pass offsetFromRoot if known.
+ IntRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;
// WARNING: This method returns the offset for the parent as this is what updateLayerPositions expects.
LayoutPoint computeOffsetFromRoot(bool& hasLayerOffset) const;