Chromium Code Reviews| Index: Source/core/layout/LayoutBox.cpp |
| diff --git a/Source/core/layout/LayoutBox.cpp b/Source/core/layout/LayoutBox.cpp |
| index c5df9eae4bd658aa70c98a73235a9ffde4457e82..6f6ad20081f9adc363a66f834ccfaa6c949777fc 100644 |
| --- a/Source/core/layout/LayoutBox.cpp |
| +++ b/Source/core/layout/LayoutBox.cpp |
| @@ -89,17 +89,6 @@ static OverrideSizeMap* gExtraBlockOffsetMap = 0; |
| static const int autoscrollBeltSize = 20; |
| static const unsigned backgroundObscurationTestMaxDepth = 4; |
| -static bool skipBodyBackground(const LayoutBox* bodyElementLayoutObject) |
| -{ |
| - ASSERT(bodyElementLayoutObject->isBody()); |
| - // The <body> only paints its background if the root element has defined a background independent of the body, |
| - // or if the <body>'s parent is not the document element's layoutObject (e.g. inside SVG foreignObject). |
| - LayoutObject* documentElementLayoutObject = bodyElementLayoutObject->document().documentElement()->layoutObject(); |
| - return documentElementLayoutObject |
| - && !documentElementLayoutObject->hasBackground() |
| - && (documentElementLayoutObject == bodyElementLayoutObject->parent()); |
| -} |
| - |
| LayoutBox::LayoutBox(ContainerNode* node) |
| : LayoutBoxModelObject(node) |
| , m_intrinsicContentLogicalHeight(-1) |
| @@ -177,16 +166,6 @@ void LayoutBox::styleWillChange(StyleDifference diff, const ComputedStyle& newSt |
| { |
| const ComputedStyle* oldStyle = style(); |
| if (oldStyle) { |
| - // The background of the root element or the body element could propagate up to |
| - // the canvas. Just dirty the entire canvas when our style changes substantially. |
| - if ((diff.needsPaintInvalidation() || diff.needsLayout()) && node() |
| - && (isHTMLHtmlElement(*node()) || isHTMLBodyElement(*node()))) { |
| - view()->setShouldDoFullPaintInvalidation(); |
| - |
| - if (oldStyle->hasEntirelyFixedBackground() != newStyle.hasEntirelyFixedBackground()) |
| - view()->compositor()->setNeedsUpdateFixedBackground(); |
| - } |
| - |
| // When a layout hint happens and an object's position style changes, we have to do a layout |
| // to dirty the layout tree using the old position value now. |
| if (diff.needsFullLayout() && parent() && oldStyle->position() != newStyle.position()) { |
| @@ -304,12 +283,11 @@ void LayoutBox::updateFromStyle() |
| LayoutBoxModelObject::updateFromStyle(); |
| const ComputedStyle& styleToUse = styleRef(); |
| - bool isRootObject = isDocumentElement(); |
| bool isViewObject = isLayoutView(); |
| bool rootLayerScrolls = document().settings() && document().settings()->rootLayerScrolls(); |
| - // The root and the LayoutView always paint their backgrounds/borders. |
| - if (isRootObject || isViewObject) |
| + // LayoutView of the main frame is resposible from painting base background. |
| + if (isViewObject && !document().ownerElement()) |
| setHasBoxDecorationBackground(true); |
| setFloating(!isOutOfFlowPositioned() && styleToUse.isFloating()); |
| @@ -1180,7 +1158,7 @@ bool LayoutBox::getBackgroundPaintedExtent(LayoutRect& paintedExtent) |
| bool LayoutBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const |
| { |
| - if (isBody() && skipBodyBackground(this)) |
| + if (isDocumentElement() || backgroundStolenForBeingBody()) |
| return false; |
| Color backgroundColor = resolveColor(CSSPropertyBackgroundColor); |
| @@ -1321,9 +1299,6 @@ void LayoutBox::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintOf |
| void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*) |
| { |
| - if (!parent()) |
| - return; |
| - |
| // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border images. |
| if ((style()->borderImage().image() && style()->borderImage().image()->data() == image) |
| || (style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image)) { |
| @@ -1340,35 +1315,21 @@ void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*) |
| } |
| } |
| - if (!paintInvalidationLayerRectsForImage(image, style()->backgroundLayers(), true)) |
| - paintInvalidationLayerRectsForImage(image, style()->maskLayers(), false); |
| + if (!invalidatePaintOfLayerRectsForImage(image, style()->backgroundLayers(), true)) |
| + invalidatePaintOfLayerRectsForImage(image, style()->maskLayers(), false); |
| } |
| -bool LayoutBox::paintInvalidationLayerRectsForImage(WrappedImagePtr image, const FillLayer& layers, bool drawingBackground) |
| +bool LayoutBox::invalidatePaintOfLayerRectsForImage(WrappedImagePtr image, const FillLayer& layers, bool drawingBackground) |
| { |
| - Vector<LayoutObject*> layerLayoutObjects; |
| - |
| - // A background of the body or document must extend to the total visible size of the document. This means the union of the |
| - // view and document bounds, since it can be the case that the view is larger than the document and vice-versa. |
| - // http://dev.w3.org/csswg/css-backgrounds/#the-background |
| - if (drawingBackground && (isDocumentElement() || (isBody() && !document().documentElement()->layoutObject()->hasBackground()))) { |
| - layerLayoutObjects.append(document().documentElement()->layoutObject()); |
| - layerLayoutObjects.append(view()); |
| - if (view()->frameView()) |
| - view()->frameView()->setNeedsFullPaintInvalidation(); |
| - } else { |
| - layerLayoutObjects.append(this); |
| - } |
| + if (drawingBackground && (isDocumentElement() || backgroundStolenForBeingBody())) |
| + return false; |
| for (const FillLayer* curLayer = &layers; curLayer; curLayer = curLayer->next()) { |
| - if (curLayer->image() && image == curLayer->image()->data() && curLayer->image()->canRender(*this, style()->effectiveZoom())) { |
| - for (LayoutObject* layerLayoutObject : layerLayoutObjects) { |
| - // For now, only support delayed paint invalidation for animated background images. |
| - bool maybeAnimated = curLayer->image()->cachedImage() && curLayer->image()->cachedImage()->image() && curLayer->image()->cachedImage()->image()->maybeAnimated(); |
| - if (maybeAnimated && drawingBackground) |
| - layerLayoutObject->setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); |
| - else |
| - layerLayoutObject->setShouldDoFullPaintInvalidation(PaintInvalidationFull); |
| - } |
| + if (curLayer->image() && image == curLayer->image()->data()) { |
| + bool maybeAnimated = curLayer->image()->cachedImage() && curLayer->image()->cachedImage()->image() && curLayer->image()->cachedImage()->image()->maybeAnimated(); |
| + if (maybeAnimated && drawingBackground) |
| + setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); |
| + else |
| + setShouldDoFullPaintInvalidation(); |
| return true; |
| } |
| } |
| @@ -3954,7 +3915,8 @@ PaintInvalidationReason LayoutBox::paintInvalidationReason(const LayoutBoxModelO |
| && hasLayer() && layer()->transform() && !layer()->transform()->isIdentityOrTranslation()) |
| return PaintInvalidationBoundsChange; |
| - if (!style()->hasBackground() && !style()->hasBoxDecorations()) { |
| + bool paintsBackground = style()->hasBackground() && !isDocumentElement() && !backgroundStolenForBeingBody(); |
| + if (!paintsBackground && !style()->hasBoxDecorations()) { |
| // We could let incremental invalidation cover non-composited scrollbars, but just |
| // do a full invalidation because incremental invalidation will go away with slimming paint. |
| if (invalidationReason == PaintInvalidationIncremental && hasNonCompositedScrollbars()) |
| @@ -3962,18 +3924,26 @@ PaintInvalidationReason LayoutBox::paintInvalidationReason(const LayoutBoxModelO |
| return invalidationReason; |
| } |
| - if (style()->backgroundLayers().thisOrNextLayersUseContentBox() || style()->maskLayers().thisOrNextLayersUseContentBox()) { |
| + if (paintsBackground && (style()->backgroundLayers().thisOrNextLayersUseContentBox() || style()->maskLayers().thisOrNextLayersUseContentBox())) { |
| LayoutRect oldContentBoxRect = m_rareData ? m_rareData->m_previousContentBoxRect : LayoutRect(); |
| LayoutRect newContentBoxRect = contentBoxRect(); |
| if (oldContentBoxRect != newContentBoxRect) |
| return PaintInvalidationContentBoxChange; |
| } |
| - if (style()->backgroundLayers().thisOrNextLayersHaveLocalAttachment()) { |
| + if (paintsBackground && style()->backgroundLayers().thisOrNextLayersHaveLocalAttachment()) { |
| LayoutRect oldLayoutOverflowRect = m_rareData ? m_rareData->m_previousLayoutOverflowRect : LayoutRect(); |
| LayoutRect newLayoutOverflowRect = layoutOverflowRect(); |
| - if (oldLayoutOverflowRect != newLayoutOverflowRect) |
| - return PaintInvalidationLayoutOverflowBoxChange; |
| + if (oldLayoutOverflowRect != newLayoutOverflowRect) { |
|
Xianzhu
2015/06/05 00:52:46
We could keep these lines as-is. The change increa
|
| + // Background positioning for the LayoutView are based on the box of the root element. |
| + // Whether full invalidation is needed will be checked with special logic in |
| + // LayoutView::invalidatePaintIfNeeded. Here we only need to guarantee incremental |
| + // painting is done for newly expanded area. |
| + if (!isLayoutView()) |
| + return PaintInvalidationLayoutOverflowBoxChange; |
| + if (invalidationReason < PaintInvalidationIncremental) |
| + invalidationReason = PaintInvalidationIncremental; |
| + } |
| } |
| LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(oldBounds.size()); |
| @@ -3998,11 +3968,13 @@ PaintInvalidationReason LayoutBox::paintInvalidationReason(const LayoutBoxModelO |
| return PaintInvalidationBorderBoxChange; |
| } |
| + if (!paintsBackground) |
| + return invalidationReason; |
| + |
| if (oldBorderBoxSize.width() != newBorderBoxSize.width() && mustInvalidateBackgroundOrBorderPaintOnWidthChange()) |
| return PaintInvalidationBorderBoxChange; |
| if (oldBorderBoxSize.height() != newBorderBoxSize.height() && mustInvalidateBackgroundOrBorderPaintOnHeightChange()) |
| return PaintInvalidationBorderBoxChange; |
| - |
| return PaintInvalidationIncremental; |
| } |
| @@ -4713,7 +4685,7 @@ void LayoutBox::logicalExtentAfterUpdatingLogicalWidth(const LayoutUnit& newLogi |
| setMarginRight(oldMarginRight); |
| } |
| -inline bool LayoutBox::mustInvalidateFillLayersPaintOnWidthChange(const FillLayer& layer) const |
| +bool LayoutBox::mustInvalidateFillLayersPaintOnWidthChange(const FillLayer& layer) const |
| { |
| // Nobody will use multiple layers without wanting fancy positioning. |
| if (layer.next()) |