Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutObject.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
| index 56fcdcaad14c3c8bea7e21c193d6f9675f918caf..ae33b30f9fa99e42a635437c80e4c69ba2b4e008 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
| @@ -68,6 +68,7 @@ |
| #include "core/layout/LayoutView.h" |
| #include "core/page/AutoscrollController.h" |
| #include "core/page/Page.h" |
| +#include "core/paint/ObjectPaintInvalidator.h" |
| #include "core/paint/ObjectPaintProperties.h" |
| #include "core/paint/PaintLayer.h" |
| #include "core/style/ContentData.h" |
| @@ -132,9 +133,6 @@ static_assert(sizeof(LayoutObject) == sizeof(SameSizeAsLayoutObject), "LayoutObj |
| bool LayoutObject::s_affectsParentBlock = false; |
| -typedef HashMap<const LayoutObject*, LayoutRect> SelectionPaintInvalidationMap; |
| -static SelectionPaintInvalidationMap* selectionPaintInvalidationMap = nullptr; |
| - |
| // The pointer to paint properties is implemented as a global hash map temporarily, |
| // to avoid memory regression during the transition towards SPv2. |
| typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> ObjectPaintPropertiesMap; |
| @@ -1100,15 +1098,6 @@ void addJsonObjectForRect(TracedValue* value, const char* name, const T& rect) |
| value->endDictionary(); |
| } |
| -template <typename T> |
| -void addJsonObjectForPoint(TracedValue* value, const char* name, const T& point) |
| -{ |
| - value->beginDictionary(name); |
| - value->setDouble("x", point.x()); |
| - value->setDouble("y", point.y()); |
| - value->endDictionary(); |
| -} |
| - |
| static std::unique_ptr<TracedValue> jsonObjectForPaintInvalidationInfo(const LayoutRect& rect, const String& invalidationReason) |
| { |
| std::unique_ptr<TracedValue> value = TracedValue::create(); |
| @@ -1199,12 +1188,6 @@ void LayoutObject::invalidateDisplayItemClients(PaintInvalidationReason reason) |
| invalidateDisplayItemClient(*this, reason); |
| } |
| -void LayoutObject::invalidateDisplayItemClientsWithPaintInvalidationState(const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason reason) const |
| -{ |
| - paintInvalidationState.paintingLayer().setNeedsRepaint(); |
| - invalidateDisplayItemClients(reason); |
| -} |
| - |
| bool LayoutObject::compositedScrollsWithRespectTo(const LayoutBoxModelObject& paintInvalidationContainer) const |
| { |
| return paintInvalidationContainer.usesCompositedScrolling() && this != &paintInvalidationContainer; |
| @@ -1258,7 +1241,7 @@ void LayoutObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInv |
| newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinContainer(); |
| PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState); |
| - clearPaintInvalidationFlags(newPaintInvalidationState); |
| + clearPaintInvalidationFlags(); |
| newPaintInvalidationState.updateForChildren(reason); |
| invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); |
| @@ -1275,16 +1258,6 @@ void LayoutObject::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationStat |
| } |
| } |
| -static std::unique_ptr<TracedValue> jsonObjectForOldAndNewRects(const LayoutRect& oldRect, const LayoutPoint& oldLocation, const LayoutRect& newRect, const LayoutPoint& newLocation) |
| -{ |
| - std::unique_ptr<TracedValue> value = TracedValue::create(); |
| - addJsonObjectForRect(value.get(), "oldRect", oldRect); |
| - addJsonObjectForPoint(value.get(), "oldLocation", oldLocation); |
| - addJsonObjectForRect(value.get(), "newRect", newRect); |
| - addJsonObjectForPoint(value.get(), "newLocation", newLocation); |
| - return value; |
| -} |
| - |
| LayoutRect LayoutObject::selectionRectInViewCoordinates() const |
| { |
| LayoutRect selectionRect = localSelectionRect(); |
| @@ -1293,54 +1266,9 @@ LayoutRect LayoutObject::selectionRectInViewCoordinates() const |
| return selectionRect; |
| } |
| -LayoutRect LayoutObject::previousSelectionRectForPaintInvalidation() const |
| -{ |
| - if (!selectionPaintInvalidationMap) |
| - return LayoutRect(); |
| - |
| - return selectionPaintInvalidationMap->get(this); |
| -} |
| - |
| -void LayoutObject::setPreviousSelectionRectForPaintInvalidation(const LayoutRect& selectionRect) |
| -{ |
| - if (!selectionPaintInvalidationMap) { |
| - if (selectionRect.isEmpty()) |
| - return; |
| - selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); |
| - } |
| - |
| - if (selectionRect.isEmpty()) |
| - selectionPaintInvalidationMap->remove(this); |
| - else |
| - selectionPaintInvalidationMap->set(this, selectionRect); |
| -} |
| - |
| -inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason invalidationReason) |
| -{ |
| - // Update selection rect when we are doing full invalidation (in case that the object is moved, composite status changed, etc.) |
| - // or shouldInvalidationSelection is set (in case that the selection itself changed). |
| - bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); |
| - if (!fullInvalidation && !shouldInvalidateSelection()) |
| - return; |
| - |
| - LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); |
| - LayoutRect newSelectionRect = localSelectionRect(); |
| - if (!newSelectionRect.isEmpty()) |
| - paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelectionRect); |
| - |
| - newSelectionRect.move(scrollAdjustmentForPaintInvalidation(paintInvalidationContainer)); |
| - |
| - setPreviousSelectionRectForPaintInvalidation(newSelectionRect); |
| - |
| - if (!fullInvalidation) { |
| - fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelection, oldSelectionRect, newSelectionRect); |
| - invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, PaintInvalidationSelection); |
| - } |
| -} |
| - |
| PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState) |
| { |
| - ASSERT(&paintInvalidationState.currentObject() == this); |
| + DCHECK(&paintInvalidationState.currentObject() == this); |
| if (styleRef().hasOutline()) { |
| PaintLayer& layer = paintInvalidationState.paintingLayer(); |
| @@ -1352,107 +1280,34 @@ PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid |
| if (v->document().printing()) |
| return PaintInvalidationNone; // Don't invalidate paints if we're printing. |
| + PaintInvalidatorContextAdapter context(paintInvalidationState); |
| + |
| const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationState.paintInvalidationContainer(); |
| - ASSERT(paintInvalidationContainer == containerForPaintInvalidation()); |
| + DCHECK(paintInvalidationContainer == containerForPaintInvalidation()); |
| - const LayoutRect oldBounds = previousPaintInvalidationRect(); |
| - const LayoutPoint oldLocation = RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() ? LayoutPoint() : previousPositionFromPaintInvalidationBacking(); |
| - LayoutRect newBounds = paintInvalidationState.computePaintInvalidationRectInBacking(); |
| - LayoutPoint newLocation = RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() ? LayoutPoint() : paintInvalidationState.computePositionFromPaintInvalidationBacking(); |
| + context.oldBounds = previousPaintInvalidationRect(); |
| + context.oldLocation = previousPositionFromPaintInvalidationBacking(); |
| + context.newBounds = paintInvalidationState.computePaintInvalidationRectInBacking(); |
| + context.newLocation = paintInvalidationState.computePositionFromPaintInvalidationBacking(); |
| IntSize adjustment = scrollAdjustmentForPaintInvalidation(paintInvalidationContainer); |
| - newLocation.move(adjustment); |
| - newBounds.move(adjustment); |
| + context.newLocation.move(adjustment); |
| + context.newBounds.move(adjustment); |
| - setPreviousPaintInvalidationRect(newBounds); |
| - if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) |
| - setPreviousPositionFromPaintInvalidationBacking(newLocation); |
| + setPreviousPaintInvalidationRect(context.newBounds); |
| + setPreviousPositionFromPaintInvalidationBacking(context.newLocation); |
| if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainerOnly()) { |
| // We are done updating the paint invalidation rect. No other paint invalidation work to do for this object. |
| return PaintInvalidationNone; |
| } |
| - PaintInvalidationReason invalidationReason = getPaintInvalidationReason(paintInvalidationState, oldBounds, oldLocation, newBounds, newLocation); |
| - |
| - // We need to invalidate the selection before checking for whether we are doing a full invalidation. |
| - // This is because we need to update the old rect regardless. |
| - invalidateSelectionIfNeeded(paintInvalidationContainer, paintInvalidationState, invalidationReason); |
| - |
| - TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "LayoutObject::invalidatePaintIfNeeded()", |
| - "object", this->debugName().ascii(), |
| - "info", jsonObjectForOldAndNewRects(oldBounds, oldLocation, newBounds, newLocation)); |
|
chrishtr
2016/08/09 23:47:31
I think this is actually used by the frame viewer
Xianzhu
2016/08/10 16:25:01
I think the frame viewer is using another trace ev
|
| - |
| - bool boxDecorationBackgroundObscured = boxDecorationBackgroundIsKnownToBeObscured(); |
| - if (!isFullPaintInvalidationReason(invalidationReason) && boxDecorationBackgroundObscured != m_bitfields.lastBoxDecorationBackgroundObscured()) |
| - invalidationReason = PaintInvalidationBackgroundObscurationChange; |
| - m_bitfields.setLastBoxDecorationBackgroundObscured(boxDecorationBackgroundObscured); |
| - |
| - if (invalidationReason == PaintInvalidationNone) { |
| - // TODO(trchen): Currently we don't keep track of paint offset of layout objects. |
| - // There are corner cases that the display items need to be invalidated for paint offset |
| - // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based |
| - // invalidation is issued. See crbug.com/508383 and crbug.com/515977. |
| - // This is a workaround to force display items to update paint offset. |
| - if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paintInvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) |
| - invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, PaintInvalidationLocationChange); |
| - |
| - return invalidationReason; |
| - } |
| - |
| - if (invalidationReason == PaintInvalidationIncremental) |
| - incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newBounds, newLocation); |
| - else |
| - fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, oldBounds, newBounds); |
| - |
| - invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, invalidationReason); |
| - return invalidationReason; |
| + return invalidatePaintIfNeeded(context); |
| } |
| -PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInvalidationState& paintInvalidationState, |
| - const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalidationBacking, |
| - const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalidationBacking) const |
| +PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalidatorContext& context) const |
| { |
| - if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) |
| - return PaintInvalidationSubtree; |
| - |
| - if (shouldDoFullPaintInvalidation()) |
| - return m_bitfields.fullPaintInvalidationReason(); |
| - |
| - if (paintedOutputOfObjectHasNoEffect()) |
| - return PaintInvalidationNone; |
| - |
| - // The outline may change shape because of position change of descendants. For simplicity, |
| - // just force full paint invalidation if this object is marked for checking paint invalidation |
| - // for any reason. |
| - if (styleRef().hasOutline()) |
| - return PaintInvalidationOutline; |
| - |
| - bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositionFromPaintInvalidationBacking; |
| - |
| - // If the bounds are the same then we know that none of the statements below |
| - // can match, so we can early out. |
| - if (oldBounds == newBounds) |
| - return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocationChange : PaintInvalidationNone; |
| - |
| - // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could |
| - // be caused by some layout property (left / top) or some in-flow layoutObject inserted / removed before us in the tree. |
| - if (newBounds.location() != oldBounds.location()) |
| - return PaintInvalidationBoundsChange; |
| - |
| - // If the size is zero on one of our bounds then we know we're going to have |
| - // to do a full invalidation of either old bounds or new bounds. If we fall |
| - // into the incremental invalidation we'll issue two invalidations instead |
| - // of one. |
| - if (oldBounds.isEmpty()) |
| - return PaintInvalidationBecameVisible; |
| - if (newBounds.isEmpty()) |
| - return PaintInvalidationBecameInvisible; |
| - |
| - if (locationChanged) |
| - return PaintInvalidationLocationChange; |
| - |
| - return PaintInvalidationIncremental; |
| + return ObjectPaintInvalidator(*this, context).invalidatePaintIfNeeded(); |
| } |
| void LayoutObject::adjustInvalidationRectForCompositedScrolling(LayoutRect& rect, const LayoutBoxModelObject& paintInvalidationContainer) const |
| @@ -1482,44 +1337,6 @@ void LayoutObject::clearPreviousPaintInvalidationRects() |
| setPreviousPaintInvalidationRect(LayoutRect()); |
| } |
| -void LayoutObject::incrementallyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds, const LayoutPoint& positionFromPaintInvalidationBacking) |
| -{ |
| - ASSERT(oldBounds.location() == newBounds.location()); |
| - |
| - LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX(); |
| - if (deltaRight > 0) { |
| - LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()); |
| - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
| - } else if (deltaRight < 0) { |
| - LayoutRect invalidationRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()); |
| - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
| - } |
| - |
| - LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY(); |
| - if (deltaBottom > 0) { |
| - LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom); |
| - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
| - } else if (deltaBottom < 0) { |
| - LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom); |
| - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); |
| - } |
| -} |
| - |
| -void LayoutObject::fullyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason invalidationReason, const LayoutRect& oldBounds, const LayoutRect& newBounds) |
| -{ |
| - // The following logic avoids invalidating twice if one set of bounds contains the other. |
| - if (!newBounds.contains(oldBounds)) { |
| - LayoutRect invalidationRect = oldBounds; |
| - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, invalidationReason); |
| - |
| - if (oldBounds.contains(newBounds)) |
| - return; |
| - } |
| - |
| - LayoutRect invalidationRect = newBounds; |
| - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, invalidationReason); |
| -} |
| - |
| LayoutRect LayoutObject::absoluteClippedOverflowRect() const |
| { |
| LayoutRect rect = localOverflowRectForPaintInvalidation(); |
| @@ -2605,8 +2422,7 @@ void LayoutObject::willBeDestroyed() |
| setAncestorLineBoxDirty(false); |
| - if (selectionPaintInvalidationMap) |
| - selectionPaintInvalidationMap->remove(this); |
| + ObjectPaintInvalidator::objectWillBeDestroyed(*this); |
| if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| objectPaintPropertiesMap().remove(this); |
| @@ -3419,7 +3235,7 @@ void LayoutObject::setMayNeedPaintInvalidationSubtree() |
| setMayNeedPaintInvalidation(); |
| } |
| -void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& paintInvalidationState) |
| +void LayoutObject::clearPaintInvalidationFlags() |
| { |
| // paintInvalidationStateIsDirty should be kept in sync with the |
| // booleans that are cleared below. |