| 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 |