| Index: third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| index 07b5e361fbee14735bda680b5369120d56f2f039..a3834e60f3232096aa939748be64fe4f9f56bd71 100644
|
| --- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
|
| @@ -18,8 +18,7 @@ namespace blink {
|
|
|
| static bool supportsCachedOffsets(const LayoutObject& object)
|
| {
|
| - return !object.hasTransformRelatedProperty()
|
| - && !object.hasReflection()
|
| + return !object.hasReflection()
|
| && !object.hasFilterInducingProperty()
|
| && !object.isLayoutFlowThread()
|
| && !object.isLayoutMultiColumnSpannerPlaceholder()
|
| @@ -35,10 +34,14 @@ PaintInvalidationState::PaintInvalidationState(const LayoutView& layoutView, Vec
|
| , m_cachedOffsetsEnabled(true)
|
| , m_cachedOffsetsForAbsolutePositionEnabled(true)
|
| , m_paintInvalidationContainer(&layoutView.containerForPaintInvalidation())
|
| + , m_realPaintInvalidationContainer(m_paintInvalidationContainer)
|
| , m_paintInvalidationContainerForStackedContents(m_paintInvalidationContainer)
|
| + , m_realPaintInvalidationContainerForStackedContents(m_paintInvalidationContainer)
|
| , m_containerForAbsolutePosition(layoutView)
|
| , m_pendingDelayedPaintInvalidations(pendingDelayedPaintInvalidations)
|
| , m_paintingLayer(*layoutView.layer())
|
| + , m_transformParent(nullptr)
|
| + , m_parentPaintInvalidationState(nullptr)
|
| #if ENABLE(ASSERT)
|
| , m_didUpdateForChildren(false)
|
| #endif
|
| @@ -48,6 +51,7 @@ PaintInvalidationState::PaintInvalidationState(const LayoutView& layoutView, Vec
|
| {
|
| if (!supportsCachedOffsets(layoutView)) {
|
| m_cachedOffsetsEnabled = false;
|
| + LOG(ERROR) << "set to false";
|
| return;
|
| }
|
|
|
| @@ -68,11 +72,15 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par
|
| , m_cachedOffsetsEnabled(parentState.m_cachedOffsetsEnabled)
|
| , m_cachedOffsetsForAbsolutePositionEnabled(parentState.m_cachedOffsetsForAbsolutePositionEnabled)
|
| , m_paintInvalidationContainer(parentState.m_paintInvalidationContainer)
|
| + , m_realPaintInvalidationContainer(parentState.m_realPaintInvalidationContainer)
|
| , m_paintInvalidationContainerForStackedContents(parentState.m_paintInvalidationContainerForStackedContents)
|
| + , m_realPaintInvalidationContainerForStackedContents(parentState.m_realPaintInvalidationContainerForStackedContents)
|
| , m_containerForAbsolutePosition(currentObject.canContainAbsolutePositionObjects() ? currentObject : parentState.m_containerForAbsolutePosition)
|
| , m_svgTransform(parentState.m_svgTransform)
|
| , m_pendingDelayedPaintInvalidations(parentState.pendingDelayedPaintInvalidationTargets())
|
| , m_paintingLayer(currentObject.hasLayer() && toLayoutBoxModelObject(currentObject).hasSelfPaintingLayer() ? *toLayoutBoxModelObject(currentObject).layer() : parentState.m_paintingLayer)
|
| + , m_transformParent(parentState.m_transformParent)
|
| + , m_parentPaintInvalidationState(nullptr)
|
| #if ENABLE(ASSERT)
|
| , m_didUpdateForChildren(false)
|
| #endif
|
| @@ -80,6 +88,10 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par
|
| , m_canCheckFastPathSlowPathEquality(parentState.m_canCheckFastPathSlowPathEquality)
|
| #endif
|
| {
|
| + if (parentState.m_currentObject.styleRef().hasTransform()) {
|
| + m_transformParent = &parentState;
|
| + }
|
| +
|
| ASSERT(&m_paintingLayer == currentObject.paintingLayer());
|
|
|
| if (currentObject == parentState.m_currentObject) {
|
| @@ -94,14 +106,23 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par
|
|
|
| ASSERT(parentState.m_didUpdateForChildren);
|
|
|
| - if (currentObject.isPaintInvalidationContainer()) {
|
| + if (currentObject.isPaintInvalidationContainer() || (currentObject.isBox() && currentObject.styleRef().hasTransform())) {
|
| m_paintInvalidationContainer = toLayoutBoxModelObject(¤tObject);
|
| if (currentObject.styleRef().isStackingContext())
|
| - m_paintInvalidationContainerForStackedContents = toLayoutBoxModelObject(¤tObject);
|
| + m_paintInvalidationContainerForStackedContents = m_paintInvalidationContainer;
|
| +
|
| + if (currentObject.isPaintInvalidationContainer()) {
|
| + m_realPaintInvalidationContainer = toLayoutBoxModelObject(¤tObject);
|
| + if (currentObject.styleRef().isStackingContext())
|
| + m_realPaintInvalidationContainerForStackedContents = toLayoutBoxModelObject(¤tObject);
|
| + } else {
|
| + m_parentPaintInvalidationState = &parentState;
|
| + }
|
| } else if (currentObject.isLayoutView()) {
|
| // m_paintInvalidationContainerForStackedContents is only for stacked descendants in its own frame,
|
| // because it doesn't establish stacking context for stacked contents in sub-frames.
|
| // Contents stacked in the root stacking context in this frame should use this frame's paintInvalidationContainer.
|
| + m_realPaintInvalidationContainerForStackedContents = m_realPaintInvalidationContainer;
|
| m_paintInvalidationContainerForStackedContents = m_paintInvalidationContainer;
|
| } else if (currentObject.styleRef().isStacked()
|
| // This is to exclude some objects (e.g. LayoutText) inheriting stacked style from parent but aren't actually stacked.
|
| @@ -110,6 +131,7 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par
|
| // The current object is stacked, so we should use m_paintInvalidationContainerForStackedContents as its
|
| // paint invalidation container on which the current object is painted.
|
| m_paintInvalidationContainer = m_paintInvalidationContainerForStackedContents;
|
| + m_realPaintInvalidationContainer = m_realPaintInvalidationContainerForStackedContents;
|
| // We are changing paintInvalidationContainer to m_paintInvalidationContainerForStackedContents. Must disable
|
| // cached offsets because we didn't track paint offset from m_paintInvalidationContainerForStackedContents.
|
| // TODO(wangxianzhu): There are optimization opportunities:
|
| @@ -198,6 +220,7 @@ void PaintInvalidationState::updateForCurrentObject(const PaintInvalidationState
|
| m_cachedOffsetsEnabled = false;
|
| return;
|
| }
|
| + // Does this still work correctly??
|
| // Use slow path to get the offset of the fixed-position, and enable fast path for descendants.
|
| FloatPoint fixedOffset = m_currentObject.localToAncestorPoint(FloatPoint(), m_paintInvalidationContainer, TraverseDocumentBoundaries);
|
| m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
|
| @@ -287,7 +310,7 @@ void PaintInvalidationState::updateForNormalChildren()
|
|
|
| if (m_currentObject.isLayoutView()) {
|
| if (!m_currentObject.document().settings() || !m_currentObject.document().settings()->rootLayerScrolls()) {
|
| - if (m_currentObject != m_paintInvalidationContainer) {
|
| + if (m_currentObject != m_realPaintInvalidationContainer) {
|
| m_paintOffset -= toLayoutView(m_currentObject).frameView()->scrollOffset();
|
| addClipRectRelativeToPaintOffset(toLayoutView(m_currentObject).viewRect());
|
| }
|
| @@ -309,7 +332,7 @@ void PaintInvalidationState::updateForNormalChildren()
|
|
|
| // Do not clip scroll layer contents because the compositor expects the whole layer
|
| // to be always invalidated in-time.
|
| - if (box == m_paintInvalidationContainer && box.scrollsOverflow())
|
| + if (box == m_realPaintInvalidationContainer && box.scrollsOverflow())
|
| ASSERT(!m_clipped); // The box establishes paint invalidation container, so no m_clipped inherited.
|
| else
|
| addClipRectRelativeToPaintOffset(box.overflowClipRect(LayoutPoint()));
|
| @@ -397,21 +420,32 @@ static void slowMapToVisualRectInAncestorSpace(const LayoutObject& object, const
|
|
|
| void PaintInvalidationState::mapLocalRectToPaintInvalidationContainer(LayoutRect& rect) const
|
| {
|
| - ASSERT(!m_didUpdateForChildren);
|
| -
|
| if (m_cachedOffsetsEnabled) {
|
| #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY
|
| LayoutRect slowPathRect(rect);
|
| - slowMapToVisualRectInAncestorSpace(m_currentObject, *m_paintInvalidationContainer, slowPathRect);
|
| + slowMapToVisualRectInAncestorSpace(m_currentObject, *m_realPaintInvalidationContainer, slowPathRect);
|
| #endif
|
| rect.move(m_paintOffset);
|
| if (m_clipped)
|
| rect.intersect(m_clipRect);
|
| +
|
| + if (m_parentPaintInvalidationState) {
|
| + if (m_currentObject.container()) {
|
| + RELEASE_ASSERT(m_currentObject.container()->isBoxModelObject());
|
| + LayoutBoxModelObject* box = toLayoutBoxModelObject(m_currentObject.container());
|
| + m_currentObject.mapToVisualRectInAncestorSpace(box, rect);
|
| + }
|
| +
|
| + m_parentPaintInvalidationState->mapLocalRectToPaintInvalidationContainer(rect);
|
| + } else if (m_transformParent) {
|
| + m_transformParent->mapLocalRectToPaintInvalidationContainer(rect);
|
| + }
|
| +
|
| #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY
|
| assertFastPathAndSlowPathRectsEqual(rect, slowPathRect);
|
| #endif
|
| } else {
|
| - slowMapToVisualRectInAncestorSpace(m_currentObject, *m_paintInvalidationContainer, rect);
|
| + slowMapToVisualRectInAncestorSpace(m_currentObject, *m_realPaintInvalidationContainer, rect);
|
| }
|
| }
|
|
|
| @@ -420,7 +454,7 @@ void PaintInvalidationState::mapLocalRectToPaintInvalidationBacking(LayoutRect&
|
| mapLocalRectToPaintInvalidationContainer(rect);
|
|
|
| if (m_paintInvalidationContainer->layer()->groupedMapping())
|
| - PaintLayer::mapRectInPaintInvalidationContainerToBacking(*m_paintInvalidationContainer, rect);
|
| + PaintLayer::mapRectInPaintInvalidationContainerToBacking(*m_realPaintInvalidationContainer, rect);
|
| }
|
|
|
| void PaintInvalidationState::addClipRectRelativeToPaintOffset(const LayoutRect& localClipRect)
|
|
|