Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp

Issue 1833493003: Remove ForceHorriblySlowRectMapping (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pi
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "core/layout/LayoutView.h" 11 #include "core/layout/LayoutView.h"
12 #include "core/layout/svg/LayoutSVGModelObject.h" 12 #include "core/layout/svg/LayoutSVGModelObject.h"
13 #include "core/layout/svg/LayoutSVGRoot.h" 13 #include "core/layout/svg/LayoutSVGRoot.h"
14 #include "core/layout/svg/SVGLayoutSupport.h" 14 #include "core/layout/svg/SVGLayoutSupport.h"
15 #include "core/paint/PaintLayer.h" 15 #include "core/paint/PaintLayer.h"
16 16
17 // We can't enable this by default because saturated operations of LayoutUnit 17 // We can't enable this by default because saturated operations of LayoutUnit
18 // don't conform commutative law for overflowing results, preventing us from 18 // don't conform commutative law for overflowing results, preventing us from
19 // making fast-path and slow-path always return the same result. 19 // making fast-path and slow-path always return the same result.
20 #define ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH (0 && ENABLE(ASSERT)) 20 #define ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH (0 && ENABLE(ASSERT))
21 21
22 namespace blink { 22 namespace blink {
23 23
24 static bool isAbsolutePositionUnderRelativePositionInline(const LayoutObject& ob ject)
25 {
26 if (object.styleRef().position() != AbsolutePosition)
27 return false;
28 if (LayoutObject* container = object.container())
29 return container->isAnonymousBlock() && container->styleRef().position() == RelativePosition;
30 return false;
31 }
32
33 static bool supportsCachedOffsets(const LayoutObject& object) 24 static bool supportsCachedOffsets(const LayoutObject& object)
34 { 25 {
35 // TODO(wangxianzhu): Move some conditions to fast path if possible.
36 return !object.hasTransformRelatedProperty() 26 return !object.hasTransformRelatedProperty()
37 && !object.hasReflection() 27 && !object.hasReflection()
38 && !object.hasFilter() 28 && !object.hasFilter()
39 && !object.isLayoutFlowThread() 29 && !object.isLayoutFlowThread()
40 && !object.isLayoutMultiColumnSpannerPlaceholder() 30 && !object.isLayoutMultiColumnSpannerPlaceholder()
41 && object.styleRef().position() != FixedPosition
42 && !object.styleRef().isFlippedBlocksWritingMode() 31 && !object.styleRef().isFlippedBlocksWritingMode()
43 // TODO(crbug.com/598094): Handle this in fast path. 32 && !(object.isLayoutBlock() && object.isSVG());
44 && !isAbsolutePositionUnderRelativePositionInline(object);
45 } 33 }
46 34
47 PaintInvalidationState::PaintInvalidationState(const LayoutView& layoutView, Vec tor<LayoutObject*>& pendingDelayedPaintInvalidations) 35 PaintInvalidationState::PaintInvalidationState(const LayoutView& layoutView, Vec tor<LayoutObject*>& pendingDelayedPaintInvalidations)
48 : m_currentObject(layoutView) 36 : m_currentObject(layoutView)
49 , m_clipped(false)
50 , m_cachedOffsetsEnabled(true)
51 , m_forcedSubtreeInvalidationWithinContainer(false) 37 , m_forcedSubtreeInvalidationWithinContainer(false)
52 , m_forcedSubtreeInvalidationRectUpdateWithinContainer(false) 38 , m_forcedSubtreeInvalidationRectUpdateWithinContainer(false)
53 , m_paintInvalidationContainer(layoutView.containerForPaintInvalidation()) 39 , m_clipped(false)
40 , m_clippedForAbsolutePosition(false)
41 , m_cachedOffsetsEnabled(true)
42 , m_cachedOffsetsForAbsolutePositionEnabled(true)
43 , m_paintInvalidationContainer(&layoutView.containerForPaintInvalidation())
44 , m_paintInvalidationContainerForStackedContents(m_paintInvalidationContaine r)
45 , m_containerForAbsolutePosition(layoutView)
54 , m_pendingDelayedPaintInvalidations(pendingDelayedPaintInvalidations) 46 , m_pendingDelayedPaintInvalidations(pendingDelayedPaintInvalidations)
55 , m_enclosingSelfPaintingLayer(*layoutView.layer()) 47 , m_enclosingSelfPaintingLayer(*layoutView.layer())
56 #if ENABLE(ASSERT) 48 #if ENABLE(ASSERT)
57 , m_didUpdateForChildren(false) 49 , m_didUpdateForChildren(false)
58 #endif 50 #endif
59 { 51 {
60 if (!supportsCachedOffsets(layoutView)) { 52 if (!supportsCachedOffsets(layoutView)) {
61 m_cachedOffsetsEnabled = false; 53 m_cachedOffsetsEnabled = false;
62 return; 54 return;
63 } 55 }
64 56
65 FloatPoint point = layoutView.localToAncestorPoint(FloatPoint(), &m_paintInv alidationContainer, TraverseDocumentBoundaries | InputIsInFrameCoordinates); 57 FloatPoint point = layoutView.localToAncestorPoint(FloatPoint(), m_paintInva lidationContainer, TraverseDocumentBoundaries | InputIsInFrameCoordinates);
66 m_paintOffset = LayoutSize(point.x(), point.y()); 58 m_paintOffset = LayoutSize(point.x(), point.y());
67 } 59 m_paintOffsetForAbsolutePosition = m_paintOffset;
68
69 // TODO(wangxianzhu): This is temporary for positioned object whose paintInvalid ationContainer is different from
70 // the one we find during tree walk. Remove this after we fix the issue with tre e walk in DOM-order.
71 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par entState, const LayoutBoxModelObject& currentObject, const LayoutBoxModelObject& paintInvalidationContainer)
72 : m_currentObject(currentObject)
73 , m_clipped(parentState.m_clipped)
74 , m_cachedOffsetsEnabled(parentState.m_cachedOffsetsEnabled)
75 , m_forcedSubtreeInvalidationWithinContainer(parentState.m_forcedSubtreeInva lidationWithinContainer)
76 , m_forcedSubtreeInvalidationRectUpdateWithinContainer(parentState.m_forcedS ubtreeInvalidationRectUpdateWithinContainer)
77 , m_clipRect(parentState.m_clipRect)
78 , m_paintOffset(parentState.m_paintOffset)
79 , m_paintInvalidationContainer(paintInvalidationContainer)
80 , m_svgTransform(parentState.m_svgTransform)
81 , m_pendingDelayedPaintInvalidations(parentState.pendingDelayedPaintInvalida tionTargets())
82 , m_enclosingSelfPaintingLayer(parentState.enclosingSelfPaintingLayer(curren tObject))
83 #if ENABLE(ASSERT)
84 , m_didUpdateForChildren(true)
85 #endif
86 {
87 ASSERT(parentState.m_didUpdateForChildren);
88 ASSERT(!m_cachedOffsetsEnabled);
89 } 60 }
90 61
91 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par entState, const LayoutObject& currentObject) 62 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& par entState, const LayoutObject& currentObject)
92 : m_currentObject(currentObject) 63 : m_currentObject(currentObject)
93 , m_clipped(parentState.m_clipped)
94 , m_cachedOffsetsEnabled(parentState.m_cachedOffsetsEnabled)
95 , m_forcedSubtreeInvalidationWithinContainer(parentState.m_forcedSubtreeInva lidationWithinContainer) 64 , m_forcedSubtreeInvalidationWithinContainer(parentState.m_forcedSubtreeInva lidationWithinContainer)
96 , m_forcedSubtreeInvalidationRectUpdateWithinContainer(parentState.m_forcedS ubtreeInvalidationRectUpdateWithinContainer) 65 , m_forcedSubtreeInvalidationRectUpdateWithinContainer(parentState.m_forcedS ubtreeInvalidationRectUpdateWithinContainer)
66 , m_clipped(parentState.m_clipped)
67 , m_clippedForAbsolutePosition(parentState.m_clippedForAbsolutePosition)
97 , m_clipRect(parentState.m_clipRect) 68 , m_clipRect(parentState.m_clipRect)
69 , m_clipRectForAbsolutePosition(parentState.m_clipRectForAbsolutePosition)
98 , m_paintOffset(parentState.m_paintOffset) 70 , m_paintOffset(parentState.m_paintOffset)
99 , m_paintInvalidationContainer(currentObject.isPaintInvalidationContainer() ? toLayoutBoxModelObject(currentObject) : parentState.m_paintInvalidationContain er) 71 , m_paintOffsetForAbsolutePosition(parentState.m_paintOffsetForAbsolutePosit ion)
72 , m_cachedOffsetsEnabled(parentState.m_cachedOffsetsEnabled)
73 , m_cachedOffsetsForAbsolutePositionEnabled(parentState.m_cachedOffsetsForAb solutePositionEnabled)
74 , m_paintInvalidationContainer(parentState.m_paintInvalidationContainer)
75 , m_paintInvalidationContainerForStackedContents(parentState.m_paintInvalida tionContainerForStackedContents)
76 , m_containerForAbsolutePosition(currentObject.canContainAbsolutePositionObj ects() ? currentObject : parentState.m_containerForAbsolutePosition)
100 , m_svgTransform(parentState.m_svgTransform) 77 , m_svgTransform(parentState.m_svgTransform)
101 , m_pendingDelayedPaintInvalidations(parentState.pendingDelayedPaintInvalida tionTargets()) 78 , m_pendingDelayedPaintInvalidations(parentState.pendingDelayedPaintInvalida tionTargets())
102 , m_enclosingSelfPaintingLayer(parentState.enclosingSelfPaintingLayer(curren tObject)) 79 , m_enclosingSelfPaintingLayer(parentState.enclosingSelfPaintingLayer(curren tObject))
103 #if ENABLE(ASSERT) 80 #if ENABLE(ASSERT)
104 , m_didUpdateForChildren(false) 81 , m_didUpdateForChildren(false)
105 #endif 82 #endif
106 { 83 {
107 if (currentObject == parentState.m_currentObject) { 84 if (currentObject == parentState.m_currentObject) {
108 // Sometimes we create a new PaintInvalidationState from parentState on the same object 85 // Sometimes we create a new PaintInvalidationState from parentState on the same object
109 // (e.g. LayoutView, and the HorriblySlowRectMapping cases in LayoutBloc k::invalidatePaintOfSubtreesIfNeeded()). 86 // (e.g. LayoutView, and the HorriblySlowRectMapping cases in LayoutBloc k::invalidatePaintOfSubtreesIfNeeded()).
110 // TODO(wangxianzhu): Avoid this for RuntimeEnabledFeatures::slimmingPai ntInvalidationEnabled(). 87 // TODO(wangxianzhu): Avoid this for RuntimeEnabledFeatures::slimmingPai ntInvalidationEnabled().
111 #if ENABLE(ASSERT) 88 #if ENABLE(ASSERT)
112 m_didUpdateForChildren = parentState.m_didUpdateForChildren; 89 m_didUpdateForChildren = parentState.m_didUpdateForChildren;
113 #endif 90 #endif
114 return; 91 return;
115 } 92 }
116 93
117 ASSERT(parentState.m_didUpdateForChildren); 94 ASSERT(parentState.m_didUpdateForChildren);
118 95
96 EPosition position = currentObject.styleRef().position();
97
98 if (currentObject.isPaintInvalidationContainer()) {
99 m_paintInvalidationContainer = toLayoutBoxModelObject(&currentObject);
100 if (currentObject.styleRef().isStackingContext()) {
101 m_paintInvalidationContainerForStackedContents = toLayoutBoxModelObj ect(&currentObject);
102
103 // Disable cached offsets for absolute-position objects if this obje ct is not a container for
104 // absolute-position because absolute-position objects' locations ar e determined by something
105 // above their paint invalidation container.
106 if (m_currentObject != m_containerForAbsolutePosition)
107 m_cachedOffsetsForAbsolutePositionEnabled = false;
108 }
109 } else if (currentObject.isLayoutView()) {
110 // m_paintInvalidationContainerForStackedContents doesn't cross frame bo undary.
chrishtr 2016/03/31 00:15:02 Why?
Xianzhu 2016/03/31 01:41:28 Added explanation as comment: // m_paintInvalidat
111 m_paintInvalidationContainerForStackedContents = m_paintInvalidationCont ainer;
112 } else if (currentObject.styleRef().isStacked()
113 // This is to exclude some objects (e.g. LayoutText) inheriting stacked style from parent but aren't actually stacked.
114 && currentObject.hasLayer()
115 && m_paintInvalidationContainer != m_paintInvalidationContainerForStacke dContents) {
chrishtr 2016/03/31 00:15:02 Can you explain in detail what this logic is doing
Xianzhu 2016/03/31 01:41:28 Added explanation as comment: // The current objec
116 m_paintInvalidationContainer = m_paintInvalidationContainerForStackedCon tents;
117 // We are changing paint invalidation container, but didn't track paint offset from
118 // m_paintInvalidationContainerForStackedContents, so disable cached off sets.
119 m_cachedOffsetsEnabled = false;
120 }
121
119 if (!currentObject.isBoxModelObject() && !currentObject.isSVG()) 122 if (!currentObject.isBoxModelObject() && !currentObject.isSVG())
120 return; 123 return;
121 124
122 if (m_cachedOffsetsEnabled && !supportsCachedOffsets(currentObject)) 125 if (m_cachedOffsetsEnabled || currentObject == m_paintInvalidationContainer)
123 m_cachedOffsetsEnabled = false; 126 m_cachedOffsetsEnabled = supportsCachedOffsets(currentObject);
124 127
125 if (currentObject.isSVG()) { 128 if (currentObject.isSVG()) {
126 if (currentObject.isSVGRoot()) { 129 if (currentObject.isSVGRoot()) {
127 m_svgTransform = toLayoutSVGRoot(currentObject).localToBorderBoxTran sform(); 130 m_svgTransform = toLayoutSVGRoot(currentObject).localToBorderBoxTran sform();
128 // 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
129 // as a normal LayoutBox. 132 // as a normal LayoutBox.
130 } else { 133 } else {
131 ASSERT(currentObject != m_paintInvalidationContainer); 134 ASSERT(currentObject != m_paintInvalidationContainer);
132 m_svgTransform *= currentObject.localToSVGParentTransform(); 135 m_svgTransform *= currentObject.localToSVGParentTransform();
133 return; 136 return;
(...skipping 17 matching lines...) Expand all
151 return; 154 return;
152 155
153 if (currentObject.isLayoutView()) { 156 if (currentObject.isLayoutView()) {
154 ASSERT(&parentState.m_currentObject == toLayoutView(currentObject).frame ()->ownerLayoutObject()); 157 ASSERT(&parentState.m_currentObject == toLayoutView(currentObject).frame ()->ownerLayoutObject());
155 m_paintOffset += toLayoutBox(parentState.m_currentObject).contentBoxOffs et(); 158 m_paintOffset += toLayoutBox(parentState.m_currentObject).contentBoxOffs et();
156 // a LayoutView paints with a defined size but a pixel-rounded offset. 159 // a LayoutView paints with a defined size but a pixel-rounded offset.
157 m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset)); 160 m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset));
158 return; 161 return;
159 } 162 }
160 163
164 if (position == FixedPosition) {
165 if (m_paintInvalidationContainer != currentObject.view() && m_paintInval idationContainer->view() == currentObject.view()) {
166 // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for f ixed-position when paintInvalidationContainer
167 // is under the containing LayoutView.
168 m_cachedOffsetsEnabled = false;
169 return;
170 }
171 FloatPoint fixedOffset = currentObject.localToAncestorPoint(FloatPoint() , m_paintInvalidationContainer, TraverseDocumentBoundaries);
172 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
173 // Ancestor clippings are ignored for simplicity.
174 m_clipped = false;
175 return;
176 }
177
178 if (position == AbsolutePosition) {
179 m_cachedOffsetsEnabled = m_cachedOffsetsForAbsolutePositionEnabled;
180 if (!m_cachedOffsetsEnabled)
181 return;
182
183 m_paintOffset = m_paintOffsetForAbsolutePosition;
184 m_clipped = m_clippedForAbsolutePosition;
185 m_clipRect = m_clipRectForAbsolutePosition;
186
187 const LayoutObject& container = parentState.m_containerForAbsolutePositi on;
188 if (container.isInFlowPositioned() && container.isLayoutInline())
189 m_paintOffset += toLayoutInline(container).offsetForInFlowPositioned Inline(toLayoutBox(m_currentObject));
190 }
191
161 if (currentObject.isBox()) 192 if (currentObject.isBox())
162 m_paintOffset += toLayoutBox(currentObject).locationOffset(); 193 m_paintOffset += toLayoutBox(currentObject).locationOffset();
163 194
164 if (currentObject.isInFlowPositioned() && currentObject.hasLayer()) 195 if (currentObject.isInFlowPositioned() && currentObject.hasLayer())
165 m_paintOffset += toLayoutBoxModelObject(currentObject).layer()->offsetFo rInFlowPosition(); 196 m_paintOffset += toLayoutBoxModelObject(currentObject).layer()->offsetFo rInFlowPosition();
166 } 197 }
167 198
168 void PaintInvalidationState::updateForChildren() 199 void PaintInvalidationState::updateForChildren()
169 { 200 {
170 #if ENABLE(ASSERT) 201 #if ENABLE(ASSERT)
171 ASSERT(!m_didUpdateForChildren); 202 ASSERT(!m_didUpdateForChildren);
172 m_didUpdateForChildren = true; 203 m_didUpdateForChildren = true;
173 #endif 204 #endif
174 205
206 updateForNormalChildren();
207
208 if (m_currentObject == m_containerForAbsolutePosition) {
209 if (m_paintInvalidationContainer == m_paintInvalidationContainerForStack edContents) {
210 m_cachedOffsetsForAbsolutePositionEnabled = m_cachedOffsetsEnabled;
211 if (m_cachedOffsetsEnabled) {
212 m_paintOffsetForAbsolutePosition = m_paintOffset;
213 m_clippedForAbsolutePosition = m_clipped;
214 m_clipRectForAbsolutePosition = m_clipRect;
215 }
216 } else {
217 m_cachedOffsetsForAbsolutePositionEnabled = false;
218 }
219 }
220 }
221
222 void PaintInvalidationState::updateForNormalChildren()
223 {
175 if (!m_cachedOffsetsEnabled) 224 if (!m_cachedOffsetsEnabled)
176 return; 225 return;
177 226
178 if (!m_currentObject.isBoxModelObject() && !m_currentObject.isSVG()) 227 if (!m_currentObject.isBoxModelObject() && !m_currentObject.isSVG())
179 return; 228 return;
180 229
181 if (m_currentObject.isLayoutView()) { 230 if (m_currentObject.isLayoutView()) {
182 if (!m_currentObject.document().settings() || !m_currentObject.document( ).settings()->rootLayerScrolls()) { 231 if (!m_currentObject.document().settings() || !m_currentObject.document( ).settings()->rootLayerScrolls()) {
183 if (m_currentObject != m_paintInvalidationContainer) { 232 if (m_currentObject != m_paintInvalidationContainer) {
184 m_paintOffset -= toLayoutView(m_currentObject).frameView()->scro llOffset(); 233 m_paintOffset -= toLayoutView(m_currentObject).frameView()->scro llOffset();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 if (object.isLayoutView()) 266 if (object.isLayoutView())
218 return toLayoutView(object).localToAncestorPoint(point, &ancestor, Trave rseDocumentBoundaries | InputIsInFrameCoordinates); 267 return toLayoutView(object).localToAncestorPoint(point, &ancestor, Trave rseDocumentBoundaries | InputIsInFrameCoordinates);
219 return object.localToAncestorPoint(point, &ancestor, TraverseDocumentBoundar ies); 268 return object.localToAncestorPoint(point, &ancestor, TraverseDocumentBoundar ies);
220 } 269 }
221 270
222 LayoutPoint PaintInvalidationState::computePositionFromPaintInvalidationBacking( ) const 271 LayoutPoint PaintInvalidationState::computePositionFromPaintInvalidationBacking( ) const
223 { 272 {
224 ASSERT(!m_didUpdateForChildren); 273 ASSERT(!m_didUpdateForChildren);
225 274
226 FloatPoint point; 275 FloatPoint point;
227 if (m_paintInvalidationContainer != m_currentObject) { 276 if (m_paintInvalidationContainer != &m_currentObject) {
228 if (m_cachedOffsetsEnabled) { 277 if (m_cachedOffsetsEnabled) {
229 if (m_currentObject.isSVG() && !m_currentObject.isSVGRoot()) 278 if (m_currentObject.isSVG() && !m_currentObject.isSVGRoot())
230 point = m_svgTransform.mapPoint(point); 279 point = m_svgTransform.mapPoint(point);
231 point += FloatPoint(m_paintOffset); 280 point += FloatPoint(m_paintOffset);
232 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH 281 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH
233 // TODO(wangxianzhu): We can't enable this ASSERT for now because of crbug.com/597745. 282 // TODO(wangxianzhu): We can't enable this ASSERT for now because of crbug.com/597745.
234 // ASSERT(point == slowLocalOriginToAncestorPoint(m_currentObject, m _paintInvalidationContainer, FloatPoint()); 283 // ASSERT(point == slowLocalOriginToAncestorPoint(m_currentObject, m _paintInvalidationContainer, FloatPoint());
235 #endif 284 #endif
236 } else { 285 } else {
237 point = slowLocalToAncestorPoint(m_currentObject, m_paintInvalidatio nContainer, FloatPoint()); 286 point = slowLocalToAncestorPoint(m_currentObject, *m_paintInvalidati onContainer, FloatPoint());
238 } 287 }
239 } 288 }
240 289
241 if (m_paintInvalidationContainer.layer()->groupedMapping()) 290 if (m_paintInvalidationContainer->layer()->groupedMapping())
242 PaintLayer::mapPointInPaintInvalidationContainerToBacking(m_paintInvalid ationContainer, point); 291 PaintLayer::mapPointInPaintInvalidationContainerToBacking(*m_paintInvali dationContainer, point);
243 292
244 return LayoutPoint(point); 293 return LayoutPoint(point);
245 } 294 }
246 295
247 LayoutRect PaintInvalidationState::computePaintInvalidationRectInBacking() const 296 LayoutRect PaintInvalidationState::computePaintInvalidationRectInBacking() const
248 { 297 {
249 ASSERT(!m_didUpdateForChildren); 298 ASSERT(!m_didUpdateForChildren);
250 299
251 if (m_currentObject.isSVG() && !m_currentObject.isSVGRoot()) 300 if (m_currentObject.isSVG() && !m_currentObject.isSVGRoot())
252 return computePaintInvalidationRectInBackingForSVG(); 301 return computePaintInvalidationRectInBackingForSVG();
253 302
254 LayoutRect rect = m_currentObject.localOverflowRectForPaintInvalidation(); 303 LayoutRect rect = m_currentObject.localOverflowRectForPaintInvalidation();
255 mapLocalRectToPaintInvalidationBacking(rect); 304 mapLocalRectToPaintInvalidationBacking(rect);
256 return rect; 305 return rect;
257 } 306 }
258 307
259 LayoutRect PaintInvalidationState::computePaintInvalidationRectInBackingForSVG() const 308 LayoutRect PaintInvalidationState::computePaintInvalidationRectInBackingForSVG() const
260 { 309 {
261 LayoutRect rect; 310 LayoutRect rect;
262 if (m_cachedOffsetsEnabled) { 311 if (m_cachedOffsetsEnabled) {
263 FloatRect svgRect = SVGLayoutSupport::localOverflowRectForPaintInvalidat ion(m_currentObject); 312 FloatRect svgRect = SVGLayoutSupport::localOverflowRectForPaintInvalidat ion(m_currentObject);
264 rect = SVGLayoutSupport::transformPaintInvalidationRect(m_currentObject, m_svgTransform, svgRect); 313 rect = SVGLayoutSupport::transformPaintInvalidationRect(m_currentObject, m_svgTransform, svgRect);
265 rect.move(m_paintOffset); 314 rect.move(m_paintOffset);
266 if (m_clipped) 315 if (m_clipped)
267 rect.intersect(m_clipRect); 316 rect.intersect(m_clipRect);
268 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH 317 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH
269 LayoutRect slowPathRect = SVGLayoutSupport::clippedOverflowRectForPaintI nvalidation(m_currentObject, m_paintInvalidationContainer); 318 LayoutRect slowPathRect = SVGLayoutSupport::clippedOverflowRectForPaintI nvalidation(m_currentObject, *m_paintInvalidationContainer);
270 // TODO(crbug.com/597902): Slow path misses clipping of paintInvalidatio nContainer. 319 // TODO(crbug.com/597902): Slow path misses clipping of paintInvalidatio nContainer.
271 if (m_clipped) 320 if (m_clipped)
272 slowPathRect.intersect(m_clipRect); 321 slowPathRect.intersect(m_clipRect);
273 // TODO(crbug.com/597903): Fast path and slow path should generate equal empty rects. 322 // TODO(crbug.com/597903): Fast path and slow path should generate equal empty rects.
274 ASSERT((rect.isEmpty() && slowPathRect.isEmpty()) || rect == slowPathRec t); 323 ASSERT((rect.isEmpty() && slowPathRect.isEmpty()) || rect == slowPathRec t);
275 #endif 324 #endif
276 } else { 325 } else {
277 // TODO(wangxianzhu): Sometimes m_cachedOffsetsEnabled==false doesn't me an we can't use cached 326 // TODO(wangxianzhu): Sometimes m_cachedOffsetsEnabled==false doesn't me an we can't use cached
278 // m_svgTransform. We can use hybrid fast-path (for SVG) and slow-path ( for things above the SVGRoot). 327 // m_svgTransform. We can use hybrid fast-path (for SVG) and slow-path ( for things above the SVGRoot).
279 rect = SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(m_curre ntObject, m_paintInvalidationContainer); 328 rect = SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(m_curre ntObject, *m_paintInvalidationContainer);
280 } 329 }
281 330
282 if (m_paintInvalidationContainer.layer()->groupedMapping()) 331 if (m_paintInvalidationContainer->layer()->groupedMapping())
283 PaintLayer::mapRectInPaintInvalidationContainerToBacking(m_paintInvalida tionContainer, rect); 332 PaintLayer::mapRectInPaintInvalidationContainerToBacking(*m_paintInvalid ationContainer, rect);
284 return rect; 333 return rect;
285 } 334 }
286 335
287 static void slowMapToVisibleRectInAncestorSpace(const LayoutObject& object, cons t LayoutBoxModelObject& ancestor, LayoutRect& rect) 336 static void slowMapToVisibleRectInAncestorSpace(const LayoutObject& object, cons t LayoutBoxModelObject& ancestor, LayoutRect& rect)
288 { 337 {
289 // TODO(crbug.com/597965): LayoutBox::mapToVisibleRectInAncestorSpace() inco rrectly flips a rect 338 // TODO(crbug.com/597965): LayoutBox::mapToVisibleRectInAncestorSpace() inco rrectly flips a rect
290 // in its own space for writing mode. Here flip to workaround the flip. 339 // in its own space for writing mode. Here flip to workaround the flip.
291 if (object.isBox() && (toLayoutBox(object).isWritingModeRoot() || (ancestor == object && object.styleRef().isFlippedBlocksWritingMode()))) 340 if (object.isBox() && (toLayoutBox(object).isWritingModeRoot() || (ancestor == object && object.styleRef().isFlippedBlocksWritingMode())))
292 toLayoutBox(object).flipForWritingMode(rect); 341 toLayoutBox(object).flipForWritingMode(rect);
293 342
294 if (object.isLayoutView()) { 343 if (object.isLayoutView()) {
295 toLayoutView(object).mapToVisibleRectInAncestorSpace(&ancestor, rect, In putIsInFrameCoordinates, DefaultVisibleRectFlags); 344 toLayoutView(object).mapToVisibleRectInAncestorSpace(&ancestor, rect, In putIsInFrameCoordinates, DefaultVisibleRectFlags);
296 } else if (object.isSVGRoot()) { 345 } else if (object.isSVGRoot()) {
297 // TODO(crbug.com/597813): This is to avoid the extra clip applied in La youtSVGRoot::mapVisibleRectInAncestorSpace(). 346 // TODO(crbug.com/597813): This is to avoid the extra clip applied in La youtSVGRoot::mapVisibleRectInAncestorSpace().
298 toLayoutSVGRoot(object).LayoutReplaced::mapToVisibleRectInAncestorSpace( &ancestor, rect); 347 toLayoutSVGRoot(object).LayoutReplaced::mapToVisibleRectInAncestorSpace( &ancestor, rect);
299 } else { 348 } else {
300 object.mapToVisibleRectInAncestorSpace(&ancestor, rect); 349 object.mapToVisibleRectInAncestorSpace(&ancestor, rect);
301 } 350 }
302 } 351 }
303 352
304 void PaintInvalidationState::mapLocalRectToPaintInvalidationBacking(LayoutRect& rect) const 353 void PaintInvalidationState::mapLocalRectToPaintInvalidationBacking(LayoutRect& rect) const
305 { 354 {
306 ASSERT(!m_didUpdateForChildren); 355 ASSERT(!m_didUpdateForChildren);
307 356
308 if (m_cachedOffsetsEnabled) { 357 if (m_cachedOffsetsEnabled) {
309 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH 358 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH
310 LayoutRect slowPathRect(rect); 359 LayoutRect slowPathRect(rect);
311 slowMapToVisibleRectInAncestorSpace(m_currentObject, m_paintInvalidation Container, slowPathRect); 360 slowMapToVisibleRectInAncestorSpace(m_currentObject, *m_paintInvalidatio nContainer, slowPathRect);
312 #endif 361 #endif
313 rect.move(m_paintOffset); 362 rect.move(m_paintOffset);
314 if (m_clipped) 363 if (m_clipped)
315 rect.intersect(m_clipRect); 364 rect.intersect(m_clipRect);
316 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH 365 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH
317 // Make sure that the fast path and the slow path generate the same rect . 366 // Make sure that the fast path and the slow path generate the same rect .
318 // TODO(crbug.com/597902): Slow path misses clipping of paintInvalidatio nContainer. 367 // TODO(crbug.com/597902): Slow path misses clipping of paintInvalidatio nContainer.
319 if (m_clipped) 368 if (m_clipped)
320 slowPathRect.intersect(m_clipRect); 369 slowPathRect.intersect(m_clipRect);
321 // TODO(wangxianzhu): The isLayoutView() condition is for cases that a s ub-frame creates a 370 // TODO(wangxianzhu): The isLayoutView() condition is for cases that a s ub-frame creates a
322 // root PaintInvalidationState which doesn't inherit clip from ancestor frames. 371 // root PaintInvalidationState which doesn't inherit clip from ancestor frames.
323 // Remove the condition when we eliminate the latter case of PaintInvali dationState(const LayoutView&, ...). 372 // Remove the condition when we eliminate the latter case of PaintInvali dationState(const LayoutView&, ...).
373 // We ignore ancestor clipping for FixedPosition in fast path.
324 // TODO(crbug.com/597903): Fast path and slow path should generate equal empty rects. 374 // TODO(crbug.com/597903): Fast path and slow path should generate equal empty rects.
325 ASSERT(m_currentObject.isLayoutView() || (rect.isEmpty() && slowPathRect .isEmpty()) || rect == slowPathRect); 375 ASSERT(m_currentObject.isLayoutView() || m_currentObject.styleRef().posi tion() == FixedPosition || (rect.isEmpty() && slowPathRect.isEmpty()) || rect == slowPathRect);
326 #endif 376 #endif
327 } else { 377 } else {
328 slowMapToVisibleRectInAncestorSpace(m_currentObject, m_paintInvalidation Container, rect); 378 slowMapToVisibleRectInAncestorSpace(m_currentObject, *m_paintInvalidatio nContainer, rect);
329 } 379 }
330 380
331 if (m_paintInvalidationContainer.layer()->groupedMapping()) 381 if (m_paintInvalidationContainer->layer()->groupedMapping())
332 PaintLayer::mapRectInPaintInvalidationContainerToBacking(m_paintInvalida tionContainer, rect); 382 PaintLayer::mapRectInPaintInvalidationContainerToBacking(*m_paintInvalid ationContainer, rect);
333 } 383 }
334 384
335 void PaintInvalidationState::addClipRectRelativeToPaintOffset(const LayoutRect& localClipRect) 385 void PaintInvalidationState::addClipRectRelativeToPaintOffset(const LayoutRect& localClipRect)
336 { 386 {
337 LayoutRect clipRect = localClipRect; 387 LayoutRect clipRect = localClipRect;
338 clipRect.move(m_paintOffset); 388 clipRect.move(m_paintOffset);
339 if (m_clipped) { 389 if (m_clipped) {
340 m_clipRect.intersect(clipRect); 390 m_clipRect.intersect(clipRect);
341 } else { 391 } else {
342 m_clipRect = clipRect; 392 m_clipRect = clipRect;
343 m_clipped = true; 393 m_clipped = true;
344 } 394 }
345 } 395 }
346 396
347 PaintLayer& PaintInvalidationState::enclosingSelfPaintingLayer(const LayoutObjec t& layoutObject) const 397 PaintLayer& PaintInvalidationState::enclosingSelfPaintingLayer(const LayoutObjec t& layoutObject) const
348 { 398 {
349 if (layoutObject.hasLayer() && toLayoutBoxModelObject(layoutObject).hasSelfP aintingLayer()) 399 if (layoutObject.hasLayer() && toLayoutBoxModelObject(layoutObject).hasSelfP aintingLayer())
350 return *toLayoutBoxModelObject(layoutObject).layer(); 400 return *toLayoutBoxModelObject(layoutObject).layer();
351 401
352 return m_enclosingSelfPaintingLayer; 402 return m_enclosingSelfPaintingLayer;
353 } 403 }
354 404
355 } // namespace blink 405 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698