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/LocalFrame.h" | 8 #include "core/frame/LocalFrame.h" |
9 #include "core/frame/Settings.h" | 9 #include "core/frame/Settings.h" |
10 #include "core/layout/LayoutInline.h" | 10 #include "core/layout/LayoutInline.h" |
11 #include "core/layout/LayoutPart.h" | 11 #include "core/layout/LayoutPart.h" |
12 #include "core/layout/LayoutView.h" | 12 #include "core/layout/LayoutView.h" |
13 #include "core/layout/api/LayoutAPIShim.h" | 13 #include "core/layout/api/LayoutAPIShim.h" |
14 #include "core/layout/api/LayoutPartItem.h" | 14 #include "core/layout/api/LayoutPartItem.h" |
15 #include "core/layout/svg/LayoutSVGRoot.h" | 15 #include "core/layout/svg/LayoutSVGRoot.h" |
16 #include "core/layout/svg/SVGLayoutSupport.h" | 16 #include "core/layout/svg/SVGLayoutSupport.h" |
17 #include "core/paint/PaintInvalidator.h" | 17 #include "core/paint/PaintInvalidator.h" |
18 #include "core/paint/PaintLayer.h" | 18 #include "core/paint/PaintLayer.h" |
19 #include "core/paint/PaintPropertyTreeBuilder.h" | 19 #include "core/paint/PaintPropertyTreeBuilder.h" |
20 | 20 |
21 namespace blink { | 21 namespace blink { |
22 | 22 |
23 static bool supportsCachedOffsets(const LayoutObject& object) { | 23 static bool supportsCachedOffsets(const LayoutObject& object) { |
24 // Can't compute paint offsets across objects with transforms, but if they are
paint invalidation containers, we don't actually need | 24 // Can't compute paint offsets across objects with transforms, but if they are |
25 // to compute *across* the container, just up to it. (Also, such objects are t
he containing block for all children.) | 25 // paint invalidation containers, we don't actually need to compute *across* |
| 26 // the container, just up to it. (Also, such objects are the containing block |
| 27 // for all children.) |
26 return !(object.hasTransformRelatedProperty() && | 28 return !(object.hasTransformRelatedProperty() && |
27 !object.isPaintInvalidationContainer()) && | 29 !object.isPaintInvalidationContainer()) && |
28 !object.hasFilterInducingProperty() && !object.isLayoutFlowThread() && | 30 !object.hasFilterInducingProperty() && !object.isLayoutFlowThread() && |
29 !object.isLayoutMultiColumnSpannerPlaceholder() && | 31 !object.isLayoutMultiColumnSpannerPlaceholder() && |
30 !object.styleRef().isFlippedBlocksWritingMode() && | 32 !object.styleRef().isFlippedBlocksWritingMode() && |
31 !(object.isLayoutBlock() && object.isSVG()); | 33 !(object.isLayoutBlock() && object.isSVG()); |
32 } | 34 } |
33 | 35 |
34 PaintInvalidationState::PaintInvalidationState( | 36 PaintInvalidationState::PaintInvalidationState( |
35 const LayoutView& layoutView, | 37 const LayoutView& layoutView, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY | 110 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY |
109 , | 111 , |
110 m_canCheckFastPathSlowPathEquality( | 112 m_canCheckFastPathSlowPathEquality( |
111 parentState.m_canCheckFastPathSlowPathEquality) | 113 parentState.m_canCheckFastPathSlowPathEquality) |
112 #endif | 114 #endif |
113 { | 115 { |
114 DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); | 116 DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); |
115 DCHECK(&m_paintingLayer == currentObject.paintingLayer()); | 117 DCHECK(&m_paintingLayer == currentObject.paintingLayer()); |
116 | 118 |
117 if (currentObject == parentState.m_currentObject) { | 119 if (currentObject == parentState.m_currentObject) { |
118 // Sometimes we create a new PaintInvalidationState from parentState on the same
object | 120 // Sometimes we create a new PaintInvalidationState from parentState on the same |
119 // (e.g. LayoutView, and the HorriblySlowRectMapping cases in LayoutBlock::inval
idatePaintOfSubtreesIfNeeded()). | 121 // object (e.g. LayoutView, and the HorriblySlowRectMapping cases in |
120 // TODO(wangxianzhu): Avoid this for RuntimeEnabledFeatures::slimmingPaintInvali
dationEnabled(). | 122 // LayoutBlock::invalidatePaintOfSubtreesIfNeeded()). |
| 123 // TODO(wangxianzhu): Avoid this for |
| 124 // RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled(). |
121 #if ENABLE(ASSERT) | 125 #if ENABLE(ASSERT) |
122 m_didUpdateForChildren = parentState.m_didUpdateForChildren; | 126 m_didUpdateForChildren = parentState.m_didUpdateForChildren; |
123 #endif | 127 #endif |
124 return; | 128 return; |
125 } | 129 } |
126 | 130 |
127 #if ENABLE(ASSERT) | 131 #if ENABLE(ASSERT) |
128 DCHECK(parentState.m_didUpdateForChildren); | 132 DCHECK(parentState.m_didUpdateForChildren); |
129 #endif | 133 #endif |
130 | 134 |
131 if (currentObject.isPaintInvalidationContainer()) { | 135 if (currentObject.isPaintInvalidationContainer()) { |
132 m_paintInvalidationContainer = toLayoutBoxModelObject(¤tObject); | 136 m_paintInvalidationContainer = toLayoutBoxModelObject(¤tObject); |
133 if (currentObject.styleRef().isStackingContext()) | 137 if (currentObject.styleRef().isStackingContext()) |
134 m_paintInvalidationContainerForStackedContents = | 138 m_paintInvalidationContainerForStackedContents = |
135 toLayoutBoxModelObject(¤tObject); | 139 toLayoutBoxModelObject(¤tObject); |
136 } else if (currentObject.isLayoutView()) { | 140 } else if (currentObject.isLayoutView()) { |
137 // m_paintInvalidationContainerForStackedContents is only for stacked descen
dants in its own frame, | 141 // m_paintInvalidationContainerForStackedContents is only for stacked |
138 // because it doesn't establish stacking context for stacked contents in sub
-frames. | 142 // descendants in its own frame, because it doesn't establish stacking |
139 // Contents stacked in the root stacking context in this frame should use th
is frame's paintInvalidationContainer. | 143 // context for stacked contents in sub-frames. Contents stacked in the root |
| 144 // stacking context in this frame should use this frame's |
| 145 // paintInvalidationContainer. |
140 m_paintInvalidationContainerForStackedContents = | 146 m_paintInvalidationContainerForStackedContents = |
141 m_paintInvalidationContainer; | 147 m_paintInvalidationContainer; |
142 } else if ( | 148 } else if (currentObject.styleRef().isStacked() && |
143 currentObject.styleRef().isStacked() | 149 // This is to exclude some objects (e.g. LayoutText) inheriting |
144 // This is to exclude some objects (e.g. LayoutText) inheriting stacked st
yle from parent but aren't actually stacked. | 150 // stacked style from parent but aren't actually stacked. |
145 && currentObject.hasLayer() && | 151 currentObject.hasLayer() && |
146 m_paintInvalidationContainer != | 152 m_paintInvalidationContainer != |
147 m_paintInvalidationContainerForStackedContents) { | 153 m_paintInvalidationContainerForStackedContents) { |
148 // The current object is stacked, so we should use m_paintInvalidationContai
nerForStackedContents as its | 154 // The current object is stacked, so we should use |
149 // paint invalidation container on which the current object is painted. | 155 // m_paintInvalidationContainerForStackedContents as its paint invalidation |
| 156 // container on which the current object is painted. |
150 m_paintInvalidationContainer = | 157 m_paintInvalidationContainer = |
151 m_paintInvalidationContainerForStackedContents; | 158 m_paintInvalidationContainerForStackedContents; |
152 // We are changing paintInvalidationContainer to m_paintInvalidationContaine
rForStackedContents. Must disable | 159 // We are changing paintInvalidationContainer to |
153 // cached offsets because we didn't track paint offset from m_paintInvalidat
ionContainerForStackedContents. | 160 // m_paintInvalidationContainerForStackedContents. Must disable cached |
| 161 // offsets because we didn't track paint offset from |
| 162 // m_paintInvalidationContainerForStackedContents. |
154 // TODO(wangxianzhu): There are optimization opportunities: | 163 // TODO(wangxianzhu): There are optimization opportunities: |
155 // - Like what we do for fixed-position, calculate the paint offset in slow
path and enable fast path for | 164 // - Like what we do for fixed-position, calculate the paint offset in slow |
156 // descendants if possible; or | 165 // path and enable fast path for descendants if possible; or |
157 // - Track offset between the two paintInvalidationContainers. | 166 // - Track offset between the two paintInvalidationContainers. |
158 m_cachedOffsetsEnabled = false; | 167 m_cachedOffsetsEnabled = false; |
159 if (m_forcedSubtreeInvalidationFlags & | 168 if (m_forcedSubtreeInvalidationFlags & |
160 PaintInvalidatorContext:: | 169 PaintInvalidatorContext:: |
161 ForcedSubtreeFullInvalidationForStackedContents) | 170 ForcedSubtreeFullInvalidationForStackedContents) |
162 m_forcedSubtreeInvalidationFlags |= | 171 m_forcedSubtreeInvalidationFlags |= |
163 PaintInvalidatorContext::ForcedSubtreeFullInvalidation; | 172 PaintInvalidatorContext::ForcedSubtreeFullInvalidation; |
164 } | 173 } |
165 | 174 |
166 if (!currentObject.isBoxModelObject() && !currentObject.isSVG()) | 175 if (!currentObject.isBoxModelObject() && !currentObject.isSVG()) |
167 return; | 176 return; |
168 | 177 |
169 if (m_cachedOffsetsEnabled || currentObject == m_paintInvalidationContainer) | 178 if (m_cachedOffsetsEnabled || currentObject == m_paintInvalidationContainer) |
170 m_cachedOffsetsEnabled = supportsCachedOffsets(currentObject); | 179 m_cachedOffsetsEnabled = supportsCachedOffsets(currentObject); |
171 | 180 |
172 if (currentObject.isSVG()) { | 181 if (currentObject.isSVG()) { |
173 if (currentObject.isSVGRoot()) { | 182 if (currentObject.isSVGRoot()) { |
174 m_svgTransform = | 183 m_svgTransform = |
175 toLayoutSVGRoot(currentObject).localToBorderBoxTransform(); | 184 toLayoutSVGRoot(currentObject).localToBorderBoxTransform(); |
176 // Don't early return here, because the SVGRoot object needs to execute th
e later code | 185 // Don't early return here, because the SVGRoot object needs to execute |
177 // as a normal LayoutBox. | 186 // the later code as a normal LayoutBox. |
178 } else { | 187 } else { |
179 DCHECK(currentObject != m_paintInvalidationContainer); | 188 DCHECK(currentObject != m_paintInvalidationContainer); |
180 m_svgTransform *= currentObject.localToSVGParentTransform(); | 189 m_svgTransform *= currentObject.localToSVGParentTransform(); |
181 return; | 190 return; |
182 } | 191 } |
183 } | 192 } |
184 | 193 |
185 if (currentObject == m_paintInvalidationContainer) { | 194 if (currentObject == m_paintInvalidationContainer) { |
186 // When we hit a new paint invalidation container, we don't need to | 195 // When we hit a new paint invalidation container, we don't need to |
187 // continue forcing a check for paint invalidation, since we're | 196 // continue forcing a check for paint invalidation, since we're |
188 // descending into a different invalidation container. (For instance if | 197 // descending into a different invalidation container. (For instance if |
189 // our parents were moved, the entire container will just move.) | 198 // our parents were moved, the entire container will just move.) |
190 if (currentObject != m_paintInvalidationContainerForStackedContents) { | 199 if (currentObject != m_paintInvalidationContainerForStackedContents) { |
191 // However, we need to keep the FullInvalidationForStackedContents flag | 200 // However, we need to keep the FullInvalidationForStackedContents flag |
192 // if the current object isn't the paint invalidation container of | 201 // if the current object isn't the paint invalidation container of |
193 // stacked contents. | 202 // stacked contents. |
194 m_forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: | 203 m_forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: |
195 ForcedSubtreeFullInvalidationForStackedContents; | 204 ForcedSubtreeFullInvalidationForStackedContents; |
196 } else { | 205 } else { |
197 m_forcedSubtreeInvalidationFlags = 0; | 206 m_forcedSubtreeInvalidationFlags = 0; |
198 if (currentObject != m_containerForAbsolutePosition && | 207 if (currentObject != m_containerForAbsolutePosition && |
199 m_cachedOffsetsForAbsolutePositionEnabled && m_cachedOffsetsEnabled) { | 208 m_cachedOffsetsForAbsolutePositionEnabled && m_cachedOffsetsEnabled) { |
200 // The current object is the new paintInvalidationContainer for absolute
-position descendants but is not their container. | 209 // The current object is the new paintInvalidationContainer for |
201 // Call updateForCurrentObject() before resetting m_paintOffset to get p
aint offset of the current object | 210 // absolute-position descendants but is not their container. |
202 // from the original paintInvalidationContainerForStackingContents, then
use this paint offset to adjust | 211 // Call updateForCurrentObject() before resetting m_paintOffset to get |
203 // m_paintOffsetForAbsolutePosition. | 212 // paint offset of the current object from the original |
| 213 // paintInvalidationContainerForStackingContents, then use this paint |
| 214 // offset to adjust m_paintOffsetForAbsolutePosition. |
204 updateForCurrentObject(parentState); | 215 updateForCurrentObject(parentState); |
205 m_paintOffsetForAbsolutePosition -= m_paintOffset; | 216 m_paintOffsetForAbsolutePosition -= m_paintOffset; |
206 if (m_clippedForAbsolutePosition) | 217 if (m_clippedForAbsolutePosition) |
207 m_clipRectForAbsolutePosition.move(-m_paintOffset); | 218 m_clipRectForAbsolutePosition.move(-m_paintOffset); |
208 } | 219 } |
209 } | 220 } |
210 | 221 |
211 m_clipped = false; // Will be updated in updateForChildren(). | 222 m_clipped = false; // Will be updated in updateForChildren(). |
212 m_paintOffset = LayoutSize(); | 223 m_paintOffset = LayoutSize(); |
213 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY | 224 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY |
(...skipping 19 matching lines...) Expand all Loading... |
233 // a LayoutView paints with a defined size but a pixel-rounded offset. | 244 // a LayoutView paints with a defined size but a pixel-rounded offset. |
234 m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset)); | 245 m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset)); |
235 return; | 246 return; |
236 } | 247 } |
237 | 248 |
238 EPosition position = m_currentObject.styleRef().position(); | 249 EPosition position = m_currentObject.styleRef().position(); |
239 | 250 |
240 if (position == FixedPosition) { | 251 if (position == FixedPosition) { |
241 if (m_paintInvalidationContainer != m_currentObject.view() && | 252 if (m_paintInvalidationContainer != m_currentObject.view() && |
242 m_paintInvalidationContainer->view() == m_currentObject.view()) { | 253 m_paintInvalidationContainer->view() == m_currentObject.view()) { |
243 // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for fixed-p
osition when paintInvalidationContainer | 254 // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for |
244 // is under the containing LayoutView. | 255 // fixed-position when paintInvalidationContainer is under the containing |
| 256 // LayoutView. |
245 m_cachedOffsetsEnabled = false; | 257 m_cachedOffsetsEnabled = false; |
246 return; | 258 return; |
247 } | 259 } |
248 // Use slow path to get the offset of the fixed-position, and enable fast pa
th for descendants. | 260 // Use slow path to get the offset of the fixed-position, and enable fast |
| 261 // path for descendants. |
249 FloatPoint fixedOffset = m_currentObject.localToAncestorPoint( | 262 FloatPoint fixedOffset = m_currentObject.localToAncestorPoint( |
250 FloatPoint(), m_paintInvalidationContainer, TraverseDocumentBoundaries); | 263 FloatPoint(), m_paintInvalidationContainer, TraverseDocumentBoundaries); |
251 if (m_paintInvalidationContainer->isBox()) { | 264 if (m_paintInvalidationContainer->isBox()) { |
252 const LayoutBox* box = toLayoutBox(m_paintInvalidationContainer); | 265 const LayoutBox* box = toLayoutBox(m_paintInvalidationContainer); |
253 if (box->hasOverflowClip()) | 266 if (box->hasOverflowClip()) |
254 fixedOffset.move(box->scrolledContentOffset()); | 267 fixedOffset.move(box->scrolledContentOffset()); |
255 } | 268 } |
256 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()); | 269 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()); |
257 // In the above way to get paint offset, we can't get accurate clip rect, so
just assume no clip. | 270 // In the above way to get paint offset, we can't get accurate clip rect, so |
258 // Clip on fixed-position is rare, in case that paintInvalidationContainer c
rosses frame boundary | 271 // just assume no clip. Clip on fixed-position is rare, in case that |
259 // and the LayoutView is clipped by something in owner document. | 272 // paintInvalidationContainer crosses frame boundary and the LayoutView is |
| 273 // clipped by something in owner document. |
260 if (m_clipped) { | 274 if (m_clipped) { |
261 m_clipped = false; | 275 m_clipped = false; |
262 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY | 276 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY |
263 m_canCheckFastPathSlowPathEquality = false; | 277 m_canCheckFastPathSlowPathEquality = false; |
264 #endif | 278 #endif |
265 } | 279 } |
266 return; | 280 return; |
267 } | 281 } |
268 | 282 |
269 if (position == AbsolutePosition) { | 283 if (position == AbsolutePosition) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 if (m_currentObject == m_containerForAbsolutePosition) { | 334 if (m_currentObject == m_containerForAbsolutePosition) { |
321 if (m_paintInvalidationContainer == | 335 if (m_paintInvalidationContainer == |
322 m_paintInvalidationContainerForStackedContents) { | 336 m_paintInvalidationContainerForStackedContents) { |
323 m_cachedOffsetsForAbsolutePositionEnabled = m_cachedOffsetsEnabled; | 337 m_cachedOffsetsForAbsolutePositionEnabled = m_cachedOffsetsEnabled; |
324 if (m_cachedOffsetsEnabled) { | 338 if (m_cachedOffsetsEnabled) { |
325 m_paintOffsetForAbsolutePosition = m_paintOffset; | 339 m_paintOffsetForAbsolutePosition = m_paintOffset; |
326 m_clippedForAbsolutePosition = m_clipped; | 340 m_clippedForAbsolutePosition = m_clipped; |
327 m_clipRectForAbsolutePosition = m_clipRect; | 341 m_clipRectForAbsolutePosition = m_clipRect; |
328 } | 342 } |
329 } else { | 343 } else { |
330 // Cached offsets for absolute-position are from m_paintInvalidationContai
ner, | 344 // Cached offsets for absolute-position are from |
331 // which can't be used if the absolute-position descendants will use a dif
ferent | 345 // m_paintInvalidationContainer, which can't be used if the |
| 346 // absolute-position descendants will use a different |
332 // paintInvalidationContainer. | 347 // paintInvalidationContainer. |
333 // TODO(wangxianzhu): Same optimization opportunities as under isStacked()
condition | 348 // TODO(wangxianzhu): Same optimization opportunities as under isStacked() |
334 // in the PaintInvalidationState::PaintInvalidationState(... LayoutObject&
...). | 349 // condition in the PaintInvalidationState::PaintInvalidationState(... |
| 350 // LayoutObject&...). |
335 m_cachedOffsetsForAbsolutePositionEnabled = false; | 351 m_cachedOffsetsForAbsolutePositionEnabled = false; |
336 } | 352 } |
337 } | 353 } |
338 } | 354 } |
339 | 355 |
340 void PaintInvalidationState::updateForNormalChildren() { | 356 void PaintInvalidationState::updateForNormalChildren() { |
341 if (!m_cachedOffsetsEnabled) | 357 if (!m_cachedOffsetsEnabled) |
342 return; | 358 return; |
343 | 359 |
344 if (!m_currentObject.isBox()) | 360 if (!m_currentObject.isBox()) |
(...skipping 15 matching lines...) Expand all Loading... |
360 addClipRectRelativeToPaintOffset( | 376 addClipRectRelativeToPaintOffset( |
361 LayoutRect(LayoutPoint(), LayoutSize(svgRoot.pixelSnappedSize()))); | 377 LayoutRect(LayoutPoint(), LayoutSize(svgRoot.pixelSnappedSize()))); |
362 } else if (box.isTableRow()) { | 378 } else if (box.isTableRow()) { |
363 // Child table cell's locationOffset() includes its row's locationOffset(). | 379 // Child table cell's locationOffset() includes its row's locationOffset(). |
364 m_paintOffset -= box.locationOffset(); | 380 m_paintOffset -= box.locationOffset(); |
365 } | 381 } |
366 | 382 |
367 if (!box.hasClipRelatedProperty()) | 383 if (!box.hasClipRelatedProperty()) |
368 return; | 384 return; |
369 | 385 |
370 // Do not clip or scroll for the paint invalidation container, because the sem
antics of visual rects do not include clipping or | 386 // Do not clip or scroll for the paint invalidation container, because the |
371 // scrolling on that object. | 387 // semantics of visual rects do not include clipping or scrolling on that |
| 388 // object. |
372 if (box != m_paintInvalidationContainer) { | 389 if (box != m_paintInvalidationContainer) { |
373 // This won't work fully correctly for fixed-position elements, who should r
eceive CSS clip but for whom the current object | 390 // This won't work fully correctly for fixed-position elements, who should |
374 // is not in the containing block chain. | 391 // receive CSS clip but for whom the current object is not in the containing |
| 392 // block chain. |
375 addClipRectRelativeToPaintOffset(box.clippingRect()); | 393 addClipRectRelativeToPaintOffset(box.clippingRect()); |
376 if (box.hasOverflowClip()) | 394 if (box.hasOverflowClip()) |
377 m_paintOffset -= box.scrolledContentOffset(); | 395 m_paintOffset -= box.scrolledContentOffset(); |
378 } | 396 } |
379 | 397 |
380 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if
present. | 398 // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if |
| 399 // present. |
381 } | 400 } |
382 | 401 |
383 static FloatPoint slowLocalToAncestorPoint(const LayoutObject& object, | 402 static FloatPoint slowLocalToAncestorPoint(const LayoutObject& object, |
384 const LayoutBoxModelObject& ancestor, | 403 const LayoutBoxModelObject& ancestor, |
385 const FloatPoint& point) { | 404 const FloatPoint& point) { |
386 if (object.isLayoutView()) | 405 if (object.isLayoutView()) |
387 return toLayoutView(object).localToAncestorPoint( | 406 return toLayoutView(object).localToAncestorPoint( |
388 point, &ancestor, | 407 point, &ancestor, |
389 TraverseDocumentBoundaries | InputIsInFrameCoordinates); | 408 TraverseDocumentBoundaries | InputIsInFrameCoordinates); |
390 FloatPoint result = | 409 FloatPoint result = |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 rect.move(m_paintOffset); | 470 rect.move(m_paintOffset); |
452 if (m_clipped) | 471 if (m_clipped) |
453 rect.intersect(m_clipRect); | 472 rect.intersect(m_clipRect); |
454 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY | 473 #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY |
455 LayoutRect slowPathRect = | 474 LayoutRect slowPathRect = |
456 SVGLayoutSupport::clippedOverflowRectForPaintInvalidation( | 475 SVGLayoutSupport::clippedOverflowRectForPaintInvalidation( |
457 m_currentObject, *m_paintInvalidationContainer); | 476 m_currentObject, *m_paintInvalidationContainer); |
458 assertFastPathAndSlowPathRectsEqual(rect, slowPathRect); | 477 assertFastPathAndSlowPathRectsEqual(rect, slowPathRect); |
459 #endif | 478 #endif |
460 } else { | 479 } else { |
461 // TODO(wangxianzhu): Sometimes m_cachedOffsetsEnabled==false doesn't mean w
e can't use cached | 480 // TODO(wangxianzhu): Sometimes m_cachedOffsetsEnabled==false doesn't mean |
462 // m_svgTransform. We can use hybrid fast path (for SVG) and slow path (for
things above the SVGRoot). | 481 // we can't use cached m_svgTransform. We can use hybrid fast path (for SVG) |
| 482 // and slow path (for things above the SVGRoot). |
463 rect = SVGLayoutSupport::clippedOverflowRectForPaintInvalidation( | 483 rect = SVGLayoutSupport::clippedOverflowRectForPaintInvalidation( |
464 m_currentObject, *m_paintInvalidationContainer); | 484 m_currentObject, *m_paintInvalidationContainer); |
465 } | 485 } |
466 | 486 |
467 if (m_paintInvalidationContainer->layer()->groupedMapping()) | 487 if (m_paintInvalidationContainer->layer()->groupedMapping()) |
468 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 488 PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
469 *m_paintInvalidationContainer, rect); | 489 *m_paintInvalidationContainer, rect); |
470 return rect; | 490 return rect; |
471 } | 491 } |
472 | 492 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 mayHaveBeenSaturated(rect.width()) || | 570 mayHaveBeenSaturated(rect.width()) || |
551 mayHaveBeenSaturated(rect.height()); | 571 mayHaveBeenSaturated(rect.height()); |
552 } | 572 } |
553 | 573 |
554 void PaintInvalidationState::assertFastPathAndSlowPathRectsEqual( | 574 void PaintInvalidationState::assertFastPathAndSlowPathRectsEqual( |
555 const LayoutRect& fastPathRect, | 575 const LayoutRect& fastPathRect, |
556 const LayoutRect& slowPathRect) const { | 576 const LayoutRect& slowPathRect) const { |
557 if (!m_canCheckFastPathSlowPathEquality) | 577 if (!m_canCheckFastPathSlowPathEquality) |
558 return; | 578 return; |
559 | 579 |
560 // TODO(crbug.com/597903): Fast path and slow path should generate equal empty
rects. | 580 // TODO(crbug.com/597903): Fast path and slow path should generate equal empty |
| 581 // rects. |
561 if (fastPathRect.isEmpty() && slowPathRect.isEmpty()) | 582 if (fastPathRect.isEmpty() && slowPathRect.isEmpty()) |
562 return; | 583 return; |
563 | 584 |
564 if (fastPathRect == slowPathRect) | 585 if (fastPathRect == slowPathRect) |
565 return; | 586 return; |
566 | 587 |
567 // LayoutUnit uses saturated arithmetic operations. If any interim or final re
sult is saturated, | 588 // LayoutUnit uses saturated arithmetic operations. If any interim or final |
568 // the same operations in different order produce different results. Don't com
pare results | 589 // result is saturated, the same operations in different order produce |
569 // if any of them may have been saturated. | 590 // different results. Don't compare results if any of them may have been |
| 591 // saturated. |
570 if (mayHaveBeenSaturated(fastPathRect) || mayHaveBeenSaturated(slowPathRect)) | 592 if (mayHaveBeenSaturated(fastPathRect) || mayHaveBeenSaturated(slowPathRect)) |
571 return; | 593 return; |
572 | 594 |
573 // Tolerate the difference between the two paths when crossing frame boundarie
s. | 595 // Tolerate the difference between the two paths when crossing frame |
| 596 // boundaries. |
574 if (m_currentObject.view() != m_paintInvalidationContainer->view()) { | 597 if (m_currentObject.view() != m_paintInvalidationContainer->view()) { |
575 LayoutRect inflatedFastPathRect = fastPathRect; | 598 LayoutRect inflatedFastPathRect = fastPathRect; |
576 inflatedFastPathRect.inflate(1); | 599 inflatedFastPathRect.inflate(1); |
577 if (inflatedFastPathRect.contains(slowPathRect)) | 600 if (inflatedFastPathRect.contains(slowPathRect)) |
578 return; | 601 return; |
579 LayoutRect inflatedSlowPathRect = slowPathRect; | 602 LayoutRect inflatedSlowPathRect = slowPathRect; |
580 inflatedSlowPathRect.inflate(1); | 603 inflatedSlowPathRect.inflate(1); |
581 if (inflatedSlowPathRect.contains(fastPathRect)) | 604 if (inflatedSlowPathRect.contains(fastPathRect)) |
582 return; | 605 return; |
583 } | 606 } |
(...skipping 27 matching lines...) Expand all Loading... |
611 } | 634 } |
612 | 635 |
613 void PaintInvalidatorContextAdapter::mapLocalRectToPaintInvalidationBacking( | 636 void PaintInvalidatorContextAdapter::mapLocalRectToPaintInvalidationBacking( |
614 const LayoutObject& object, | 637 const LayoutObject& object, |
615 LayoutRect& rect) const { | 638 LayoutRect& rect) const { |
616 DCHECK(&object == &m_paintInvalidationState.currentObject()); | 639 DCHECK(&object == &m_paintInvalidationState.currentObject()); |
617 m_paintInvalidationState.mapLocalRectToPaintInvalidationBacking(rect); | 640 m_paintInvalidationState.mapLocalRectToPaintInvalidationBacking(rect); |
618 } | 641 } |
619 | 642 |
620 } // namespace blink | 643 } // namespace blink |
OLD | NEW |