Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/PaintInvalidationState.h" | 5 #include "core/layout/PaintInvalidationState.h" |
| 6 | 6 |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/layout/LayoutInline.h" | 9 #include "core/layout/LayoutInline.h" |
| 10 #include "core/layout/LayoutPart.h" | 10 #include "core/layout/LayoutPart.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 && !object.hasReflection() | 22 && !object.hasReflection() |
| 23 && !object.hasFilterInducingProperty() | 23 && !object.hasFilterInducingProperty() |
| 24 && !object.isLayoutFlowThread() | 24 && !object.isLayoutFlowThread() |
| 25 && !object.isLayoutMultiColumnSpannerPlaceholder() | 25 && !object.isLayoutMultiColumnSpannerPlaceholder() |
| 26 && !object.styleRef().isFlippedBlocksWritingMode() | 26 && !object.styleRef().isFlippedBlocksWritingMode() |
| 27 && !(object.isLayoutBlock() && object.isSVG()); | 27 && !(object.isLayoutBlock() && object.isSVG()); |
| 28 } | 28 } |
| 29 | 29 |
| 30 PaintInvalidationState::PaintInvalidationState(const LayoutView& layoutView, Vec tor<LayoutObject*>& pendingDelayedPaintInvalidations) | 30 PaintInvalidationState::PaintInvalidationState(const LayoutView& layoutView, Vec tor<LayoutObject*>& pendingDelayedPaintInvalidations) |
| 31 : m_currentObject(layoutView) | 31 : m_currentObject(layoutView) |
| 32 , m_forcedSubtreeInvalidationWithinContainer(false) | 32 , m_forcedSubtreeInvalidationFlags(0) |
| 33 , m_forcedSubtreeInvalidationRectUpdateWithinContainer(false) | |
| 34 , m_clipped(false) | 33 , m_clipped(false) |
| 35 , m_clippedForAbsolutePosition(false) | 34 , m_clippedForAbsolutePosition(false) |
| 36 , m_cachedOffsetsEnabled(true) | 35 , m_cachedOffsetsEnabled(true) |
| 37 , m_cachedOffsetsForAbsolutePositionEnabled(true) | 36 , m_cachedOffsetsForAbsolutePositionEnabled(true) |
| 38 , m_paintInvalidationContainer(&layoutView.containerForPaintInvalidation()) | 37 , m_paintInvalidationContainer(&layoutView.containerForPaintInvalidation()) |
| 39 , m_paintInvalidationContainerForStackedContents(m_paintInvalidationContaine r) | 38 , m_paintInvalidationContainerForStackedContents(m_paintInvalidationContaine r) |
| 40 , m_containerForAbsolutePosition(layoutView) | 39 , m_containerForAbsolutePosition(layoutView) |
| 41 , m_pendingDelayedPaintInvalidations(pendingDelayedPaintInvalidations) | 40 , m_pendingDelayedPaintInvalidations(pendingDelayedPaintInvalidations) |
| 42 , m_enclosingSelfPaintingLayer(*layoutView.layer()) | 41 , m_enclosingSelfPaintingLayer(*layoutView.layer()) |
| 43 #if ENABLE(ASSERT) | 42 #if ENABLE(ASSERT) |
| 44 , m_didUpdateForChildren(false) | 43 , m_didUpdateForChildren(false) |
| 45 #endif | 44 #endif |
| 46 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY | 45 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY |
| 47 , m_canCheckFastPathSlowPathEquality(layoutView == m_paintInvalidationContai ner) | 46 , m_canCheckFastPathSlowPathEquality(layoutView == m_paintInvalidationContai ner) |
| 48 #endif | 47 #endif |
| 49 { | 48 { |
| 50 if (!supportsCachedOffsets(layoutView)) { | 49 if (!supportsCachedOffsets(layoutView)) { |
| 51 m_cachedOffsetsEnabled = false; | 50 m_cachedOffsetsEnabled = false; |
| 52 return; | 51 return; |
| 53 } | 52 } |
| 54 | 53 |
| 55 FloatPoint point = layoutView.localToAncestorPoint(FloatPoint(), m_paintInva lidationContainer, TraverseDocumentBoundaries | InputIsInFrameCoordinates); | 54 FloatPoint point = layoutView.localToAncestorPoint(FloatPoint(), m_paintInva lidationContainer, TraverseDocumentBoundaries | InputIsInFrameCoordinates); |
| 56 m_paintOffset = LayoutSize(point.x(), point.y()); | 55 m_paintOffset = LayoutSize(point.x(), point.y()); |
| 57 m_paintOffsetForAbsolutePosition = m_paintOffset; | 56 m_paintOffsetForAbsolutePosition = m_paintOffset; |
| 58 } | 57 } |
| 59 | 58 |
| 60 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par entState, const LayoutObject& currentObject) | 59 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par entState, const LayoutObject& currentObject) |
| 61 : m_currentObject(currentObject) | 60 : m_currentObject(currentObject) |
| 62 , m_forcedSubtreeInvalidationWithinContainer(parentState.m_forcedSubtreeInva lidationWithinContainer) | 61 , m_forcedSubtreeInvalidationFlags(parentState.m_forcedSubtreeInvalidationFl ags) |
| 63 , m_forcedSubtreeInvalidationRectUpdateWithinContainer(parentState.m_forcedS ubtreeInvalidationRectUpdateWithinContainer) | |
| 64 , m_clipped(parentState.m_clipped) | 62 , m_clipped(parentState.m_clipped) |
| 65 , m_clippedForAbsolutePosition(parentState.m_clippedForAbsolutePosition) | 63 , m_clippedForAbsolutePosition(parentState.m_clippedForAbsolutePosition) |
| 66 , m_clipRect(parentState.m_clipRect) | 64 , m_clipRect(parentState.m_clipRect) |
| 67 , m_clipRectForAbsolutePosition(parentState.m_clipRectForAbsolutePosition) | 65 , m_clipRectForAbsolutePosition(parentState.m_clipRectForAbsolutePosition) |
| 68 , m_paintOffset(parentState.m_paintOffset) | 66 , m_paintOffset(parentState.m_paintOffset) |
| 69 , m_paintOffsetForAbsolutePosition(parentState.m_paintOffsetForAbsolutePosit ion) | 67 , m_paintOffsetForAbsolutePosition(parentState.m_paintOffsetForAbsolutePosit ion) |
| 70 , m_cachedOffsetsEnabled(parentState.m_cachedOffsetsEnabled) | 68 , m_cachedOffsetsEnabled(parentState.m_cachedOffsetsEnabled) |
| 71 , m_cachedOffsetsForAbsolutePositionEnabled(parentState.m_cachedOffsetsForAb solutePositionEnabled) | 69 , m_cachedOffsetsForAbsolutePositionEnabled(parentState.m_cachedOffsetsForAb solutePositionEnabled) |
| 72 , m_paintInvalidationContainer(parentState.m_paintInvalidationContainer) | 70 , m_paintInvalidationContainer(parentState.m_paintInvalidationContainer) |
| 73 , m_paintInvalidationContainerForStackedContents(parentState.m_paintInvalida tionContainerForStackedContents) | 71 , m_paintInvalidationContainerForStackedContents(parentState.m_paintInvalida tionContainerForStackedContents) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 // The current object is stacked, so we should use m_paintInvalidationCo ntainerForStackedContents as its | 108 // The current object is stacked, so we should use m_paintInvalidationCo ntainerForStackedContents as its |
| 111 // paint invalidation container on which the current object is painted. | 109 // paint invalidation container on which the current object is painted. |
| 112 m_paintInvalidationContainer = m_paintInvalidationContainerForStackedCon tents; | 110 m_paintInvalidationContainer = m_paintInvalidationContainerForStackedCon tents; |
| 113 // We are changing paintInvalidationContainer to m_paintInvalidationCont ainerForStackedContents. Must disable | 111 // We are changing paintInvalidationContainer to m_paintInvalidationCont ainerForStackedContents. Must disable |
| 114 // cached offsets because we didn't track paint offset from m_paintInval idationContainerForStackedContents. | 112 // cached offsets because we didn't track paint offset from m_paintInval idationContainerForStackedContents. |
| 115 // TODO(wangxianzhu): There are optimization opportunities: | 113 // TODO(wangxianzhu): There are optimization opportunities: |
| 116 // - Like what we do for fixed-position, calculate the paint offset in s low path and enable fast path for | 114 // - Like what we do for fixed-position, calculate the paint offset in s low path and enable fast path for |
| 117 // descendants if possible; or | 115 // descendants if possible; or |
| 118 // - Track offset between the two paintInvalidationContainers. | 116 // - Track offset between the two paintInvalidationContainers. |
| 119 m_cachedOffsetsEnabled = false; | 117 m_cachedOffsetsEnabled = false; |
| 118 if (m_forcedSubtreeInvalidationFlags & FullInvalidationForStackedContent s) | |
|
chrishtr
2016/05/09 22:20:42
Where was this logic previously?
Xianzhu
2016/05/10 17:17:12
It was in traverseNonCompositingDescendants() call
| |
| 119 m_forcedSubtreeInvalidationFlags |= FullInvalidation; | |
| 120 } | 120 } |
| 121 | 121 |
| 122 if (!currentObject.isBoxModelObject() && !currentObject.isSVG()) | 122 if (!currentObject.isBoxModelObject() && !currentObject.isSVG()) |
| 123 return; | 123 return; |
| 124 | 124 |
| 125 if (m_cachedOffsetsEnabled || currentObject == m_paintInvalidationContainer) | 125 if (m_cachedOffsetsEnabled || currentObject == m_paintInvalidationContainer) |
| 126 m_cachedOffsetsEnabled = supportsCachedOffsets(currentObject); | 126 m_cachedOffsetsEnabled = supportsCachedOffsets(currentObject); |
| 127 | 127 |
| 128 if (currentObject.isSVG()) { | 128 if (currentObject.isSVG()) { |
| 129 if (currentObject.isSVGRoot()) { | 129 if (currentObject.isSVGRoot()) { |
| 130 m_svgTransform = toLayoutSVGRoot(currentObject).localToBorderBoxTran sform(); | 130 m_svgTransform = toLayoutSVGRoot(currentObject).localToBorderBoxTran sform(); |
| 131 // Don't early return here, because the SVGRoot object needs to exec ute the later code | 131 // Don't early return here, because the SVGRoot object needs to exec ute the later code |
| 132 // as a normal LayoutBox. | 132 // as a normal LayoutBox. |
| 133 } else { | 133 } else { |
| 134 ASSERT(currentObject != m_paintInvalidationContainer); | 134 ASSERT(currentObject != m_paintInvalidationContainer); |
| 135 m_svgTransform *= currentObject.localToSVGParentTransform(); | 135 m_svgTransform *= currentObject.localToSVGParentTransform(); |
| 136 return; | 136 return; |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 | 139 |
| 140 if (currentObject == m_paintInvalidationContainer) { | 140 if (currentObject == m_paintInvalidationContainer) { |
| 141 // When we hit a new paint invalidation container, we don't need to | 141 // When we hit a new paint invalidation container, we don't need to |
| 142 // continue forcing a check for paint invalidation, since we're | 142 // continue forcing a check for paint invalidation, since we're |
| 143 // descending into a different invalidation container. (For instance if | 143 // descending into a different invalidation container. (For instance if |
| 144 // our parents were moved, the entire container will just move.) | 144 // our parents were moved, the entire container will just move.) |
| 145 m_forcedSubtreeInvalidationWithinContainer = false; | 145 // However, we need to keep the FullInvalidationForStackedContents flag |
| 146 m_forcedSubtreeInvalidationRectUpdateWithinContainer = false; | 146 // if the current object isn't the paint invalidation container of |
| 147 | 147 // stacked contents. |
| 148 if (currentObject == m_paintInvalidationContainerForStackedContents | 148 if (currentObject != m_paintInvalidationContainerForStackedContents) { |
| 149 && currentObject != m_containerForAbsolutePosition | 149 m_forcedSubtreeInvalidationFlags &= FullInvalidationForStackedConten ts; |
| 150 && m_cachedOffsetsForAbsolutePositionEnabled | 150 } else { |
| 151 && m_cachedOffsetsEnabled) { | 151 m_forcedSubtreeInvalidationFlags = 0; |
| 152 // The current object is the new paintInvalidationContainer for abso lute-position descendants but is not their container. | 152 if (currentObject != m_containerForAbsolutePosition |
| 153 // Call updateForCurrentObject() before resetting m_paintOffset to g et paint offset of the current object | 153 && m_cachedOffsetsForAbsolutePositionEnabled |
| 154 // from the original paintInvalidationContainerForStackingContents, then use this paint offset to adjust | 154 && m_cachedOffsetsEnabled) { |
| 155 // m_paintOffsetForAbsolutePosition. | 155 // The current object is the new paintInvalidationContainer for absolute-position descendants but is not their container. |
| 156 updateForCurrentObject(parentState); | 156 // Call updateForCurrentObject() before resetting m_paintOffset to get paint offset of the current object |
| 157 m_paintOffsetForAbsolutePosition -= m_paintOffset; | 157 // from the original paintInvalidationContainerForStackingConten ts, then use this paint offset to adjust |
| 158 if (m_clippedForAbsolutePosition) | 158 // m_paintOffsetForAbsolutePosition. |
| 159 m_clipRectForAbsolutePosition.move(-m_paintOffset); | 159 updateForCurrentObject(parentState); |
| 160 m_paintOffsetForAbsolutePosition -= m_paintOffset; | |
| 161 if (m_clippedForAbsolutePosition) | |
| 162 m_clipRectForAbsolutePosition.move(-m_paintOffset); | |
| 163 } | |
| 160 } | 164 } |
| 161 | 165 |
| 162 m_clipped = false; // Will be updated in updateForChildren(). | 166 m_clipped = false; // Will be updated in updateForChildren(). |
| 163 m_paintOffset = LayoutSize(); | 167 m_paintOffset = LayoutSize(); |
| 164 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY | 168 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY |
| 165 m_canCheckFastPathSlowPathEquality = true; | 169 m_canCheckFastPathSlowPathEquality = true; |
| 166 #endif | 170 #endif |
| 167 return; | 171 return; |
| 168 } | 172 } |
| 169 | 173 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 m_paintOffset += toLayoutInline(container).offsetForInFlowPositioned Inline(toLayoutBox(m_currentObject)); | 226 m_paintOffset += toLayoutInline(container).offsetForInFlowPositioned Inline(toLayoutBox(m_currentObject)); |
| 223 } | 227 } |
| 224 | 228 |
| 225 if (m_currentObject.isBox()) | 229 if (m_currentObject.isBox()) |
| 226 m_paintOffset += toLayoutBox(m_currentObject).locationOffset(); | 230 m_paintOffset += toLayoutBox(m_currentObject).locationOffset(); |
| 227 | 231 |
| 228 if (m_currentObject.isInFlowPositioned() && m_currentObject.hasLayer()) | 232 if (m_currentObject.isInFlowPositioned() && m_currentObject.hasLayer()) |
| 229 m_paintOffset += toLayoutBoxModelObject(m_currentObject).layer()->offset ForInFlowPosition(); | 233 m_paintOffset += toLayoutBoxModelObject(m_currentObject).layer()->offset ForInFlowPosition(); |
| 230 } | 234 } |
| 231 | 235 |
| 232 void PaintInvalidationState::updateForChildren() | 236 void PaintInvalidationState::updateForChildren(PaintInvalidationReason reason) |
| 233 { | 237 { |
| 234 #if ENABLE(ASSERT) | 238 #if ENABLE(ASSERT) |
| 235 ASSERT(!m_didUpdateForChildren); | 239 ASSERT(!m_didUpdateForChildren); |
| 236 m_didUpdateForChildren = true; | 240 m_didUpdateForChildren = true; |
| 237 #endif | 241 #endif |
| 238 | 242 |
| 243 switch (reason) { | |
| 244 case PaintInvalidationDelayedFull: | |
| 245 pushDelayedPaintInvalidationTarget(const_cast<LayoutObject&>(m_currentOb ject)); | |
| 246 break; | |
| 247 case PaintInvalidationSubtree: | |
| 248 m_forcedSubtreeInvalidationFlags |= (FullInvalidation | FullInvalidation ForStackedContents); | |
| 249 break; | |
| 250 case PaintInvalidationSVGResourceChange: | |
| 251 setForceSubtreeInvalidationCheckingWithinContainer(); | |
| 252 break; | |
| 253 default: | |
| 254 break; | |
| 255 } | |
| 256 | |
| 239 updateForNormalChildren(); | 257 updateForNormalChildren(); |
| 240 | 258 |
| 241 if (m_currentObject == m_containerForAbsolutePosition) { | 259 if (m_currentObject == m_containerForAbsolutePosition) { |
| 242 if (m_paintInvalidationContainer == m_paintInvalidationContainerForStack edContents) { | 260 if (m_paintInvalidationContainer == m_paintInvalidationContainerForStack edContents) { |
| 243 m_cachedOffsetsForAbsolutePositionEnabled = m_cachedOffsetsEnabled; | 261 m_cachedOffsetsForAbsolutePositionEnabled = m_cachedOffsetsEnabled; |
| 244 if (m_cachedOffsetsEnabled) { | 262 if (m_cachedOffsetsEnabled) { |
| 245 m_paintOffsetForAbsolutePosition = m_paintOffset; | 263 m_paintOffsetForAbsolutePosition = m_paintOffset; |
| 246 m_clippedForAbsolutePosition = m_clipped; | 264 m_clippedForAbsolutePosition = m_clipped; |
| 247 m_clipRectForAbsolutePosition = m_clipRect; | 265 m_clipRectForAbsolutePosition = m_clipRect; |
| 248 } | 266 } |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 469 WTFLogAlways("Fast path paint invalidation rect differs from slow path: fast : %s vs slow: %s", | 487 WTFLogAlways("Fast path paint invalidation rect differs from slow path: fast : %s vs slow: %s", |
| 470 fastPathRect.toString().ascii().data(), slowPathRect.toString().ascii(). data()); | 488 fastPathRect.toString().ascii().data(), slowPathRect.toString().ascii(). data()); |
| 471 showLayoutTree(&m_currentObject); | 489 showLayoutTree(&m_currentObject); |
| 472 | 490 |
| 473 ASSERT_NOT_REACHED(); | 491 ASSERT_NOT_REACHED(); |
| 474 } | 492 } |
| 475 | 493 |
| 476 #endif // CHECK_FAST_PATH_SLOW_PATH_EQUALITY | 494 #endif // CHECK_FAST_PATH_SLOW_PATH_EQUALITY |
| 477 | 495 |
| 478 } // namespace blink | 496 } // namespace blink |
| OLD | NEW |