Index: Source/core/rendering/RenderBox.cpp |
diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp |
index c6b40102f36b736d24fc1ddb468ddc148e97d010..82ef009dd6f802aa605fad78a095bd4ec454f966 100644 |
--- a/Source/core/rendering/RenderBox.cpp |
+++ b/Source/core/rendering/RenderBox.cpp |
@@ -1243,19 +1243,29 @@ void RenderBox::paintBackground(const PaintInfo& paintInfo, const LayoutRect& pa |
paintFillLayers(paintInfo, resolveColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), paintRect, bleedAvoidance); |
} |
-LayoutRect RenderBox::backgroundPaintedExtent() const |
+bool RenderBox::getBackgroundPaintedExtent(LayoutRect& paintedExtent) const |
{ |
ASSERT(hasBackground()); |
LayoutRect backgroundRect = pixelSnappedIntRect(borderBoxRect()); |
Color backgroundColor = resolveColor(CSSPropertyBackgroundColor); |
- if (backgroundColor.alpha()) |
- return backgroundRect; |
- if (!style()->backgroundLayers()->image() || style()->backgroundLayers()->next()) |
- return backgroundRect; |
+ |
+ if (backgroundColor.alpha()) { |
+ paintedExtent = backgroundRect; |
+ return true; |
+ } |
+ |
+ if (!style()->backgroundLayers()->image() || style()->backgroundLayers()->next()) { |
+ paintedExtent = backgroundRect; |
+ return true; |
+ } |
+ |
BackgroundImageGeometry geometry; |
- const_cast<RenderBox*>(this)->calculateBackgroundImageGeometry(style()->backgroundLayers(), backgroundRect, geometry); |
- return geometry.destRect(); |
+ calculateBackgroundImageGeometry(0, style()->backgroundLayers(), backgroundRect, geometry); |
+ if (geometry.hasNonLocalGeometry()) |
+ return false; |
+ paintedExtent = geometry.destRect(); |
+ return true; |
} |
bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const |
@@ -1365,7 +1375,9 @@ bool RenderBox::computeBackgroundIsKnownToBeObscured() |
// FIXME: box-shadow is painted while background painting. |
if (style()->boxShadow()) |
return false; |
- LayoutRect backgroundRect = backgroundPaintedExtent(); |
+ LayoutRect backgroundRect; |
+ if (!getBackgroundPaintedExtent(backgroundRect)) |
+ return false; |
return foregroundIsKnownToBeOpaqueInRect(backgroundRect, backgroundObscurationTestMaxDepth); |
} |
@@ -1469,7 +1481,8 @@ LayoutRect RenderBox::maskClipRect() |
for (const FillLayer* maskLayer = style()->maskLayers(); maskLayer; maskLayer = maskLayer->next()) { |
if (maskLayer->image()) { |
BackgroundImageGeometry geometry; |
- calculateBackgroundImageGeometry(maskLayer, borderBox, geometry); |
+ // Masks should never have fixed attachment, so it's OK for paintContainer to be null. |
+ calculateBackgroundImageGeometry(0, maskLayer, borderBox, geometry); |
result.unite(geometry.destRect()); |
} |
} |
@@ -1565,8 +1578,7 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer |
for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next()) { |
if (curLayer->image() && image == curLayer->image()->data() && curLayer->image()->canRender(this, style()->effectiveZoom())) { |
- // Now that we know this image is being used, compute the renderer and the rect |
- // if we haven't already |
+ // Now that we know this image is being used, compute the renderer and the rect if we haven't already. |
if (!layerRenderer) { |
bool drawingRootBackground = drawingBackground && (isRoot() || (isBody() && !document().documentElement()->renderer()->hasBackground())); |
if (drawingRootBackground) { |
@@ -1593,7 +1605,14 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer |
} |
BackgroundImageGeometry geometry; |
- layerRenderer->calculateBackgroundImageGeometry(curLayer, rendererRect, geometry); |
+ layerRenderer->calculateBackgroundImageGeometry(0, curLayer, rendererRect, geometry); |
+ if (geometry.hasNonLocalGeometry()) { |
+ // Rather than incur the costs of computing the paintContainer for renderers with fixed backgrounds |
+ // in order to get the right destRect, just repaint the entire renderer. |
+ layerRenderer->repaint(); |
+ return true; |
+ } |
+ |
layerRenderer->repaintRectangle(geometry.destRect()); |
if (geometry.destRect() == rendererRect) |
return true; |