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