| Index: Source/core/rendering/RenderBox.cpp
|
| diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
|
| index 0087bae6a56fc67c6cf695ade40f3dce271da8a2..d165736f156b67002418711cba897e913a2a9bb7 100644
|
| --- a/Source/core/rendering/RenderBox.cpp
|
| +++ b/Source/core/rendering/RenderBox.cpp
|
| @@ -1245,19 +1245,28 @@ 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
|
| @@ -1367,7 +1376,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);
|
| }
|
|
|
| @@ -1471,7 +1482,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());
|
| }
|
| }
|
| @@ -1567,8 +1579,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) {
|
| @@ -1595,7 +1606,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;
|
|
|