| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/paint/PaintInvalidator.h" | 5 #include "core/paint/PaintInvalidator.h" |
| 6 | 6 |
| 7 #include "core/editing/FrameSelection.h" | 7 #include "core/editing/FrameSelection.h" |
| 8 #include "core/frame/FrameView.h" | 8 #include "core/frame/FrameView.h" |
| 9 #include "core/frame/LocalFrame.h" | 9 #include "core/frame/LocalFrame.h" |
| 10 #include "core/frame/Settings.h" | 10 #include "core/frame/Settings.h" |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 208 |
| 209 if (object.isTable()) { | 209 if (object.isTable()) { |
| 210 const LayoutTable& table = toLayoutTable(object); | 210 const LayoutTable& table = toLayoutTable(object); |
| 211 if (table.collapseBorders() && !table.collapsedBorders().isEmpty()) | 211 if (table.collapseBorders() && !table.collapsedBorders().isEmpty()) |
| 212 context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds(); | 212 context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds(); |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 | 215 |
| 216 namespace { | 216 namespace { |
| 217 | 217 |
| 218 // This is temporary to workaround paint invalidation issues in non-rootLayerScr
olls mode. | 218 // This is temporary to workaround paint invalidation issues in |
| 219 // It undos FrameView's content clip and scroll for paint invalidation of frame | 219 // non-rootLayerScrolls mode. |
| 220 // scroll controls and the LayoutView to which the content clip and scroll don't
apply. | 220 // It undoes FrameView's content clip and scroll for paint invalidation of frame |
| 221 // scroll controls and the LayoutView to which the content clip and scroll don't |
| 222 // apply. |
| 221 class ScopedUndoFrameViewContentClipAndScroll { | 223 class ScopedUndoFrameViewContentClipAndScroll { |
| 222 public: | 224 public: |
| 223 ScopedUndoFrameViewContentClipAndScroll(const FrameView& frameView, | 225 ScopedUndoFrameViewContentClipAndScroll(const FrameView& frameView, |
| 224 PaintInvalidatorContext& context) | 226 PaintInvalidatorContext& context) |
| 225 : m_treeBuilderContext(const_cast<PaintPropertyTreeBuilderContext&>( | 227 : m_treeBuilderContext(const_cast<PaintPropertyTreeBuilderContext&>( |
| 226 context.treeBuilderContext)), | 228 context.treeBuilderContext)), |
| 227 m_savedContext(m_treeBuilderContext.current) { | 229 m_savedContext(m_treeBuilderContext.current) { |
| 228 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); | 230 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); |
| 229 | 231 |
| 230 if (frameView.contentClip() == m_savedContext.clip) | 232 if (frameView.contentClip() == m_savedContext.clip) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 251 PaintInvalidatorContext& context) { | 253 PaintInvalidatorContext& context) { |
| 252 Optional<ScopedUndoFrameViewContentClipAndScroll> | 254 Optional<ScopedUndoFrameViewContentClipAndScroll> |
| 253 undoFrameViewContentClipAndScroll; | 255 undoFrameViewContentClipAndScroll; |
| 254 | 256 |
| 255 if (object.isPaintInvalidationContainer()) { | 257 if (object.isPaintInvalidationContainer()) { |
| 256 context.paintInvalidationContainer = toLayoutBoxModelObject(&object); | 258 context.paintInvalidationContainer = toLayoutBoxModelObject(&object); |
| 257 if (object.styleRef().isStackingContext()) | 259 if (object.styleRef().isStackingContext()) |
| 258 context.paintInvalidationContainerForStackedContents = | 260 context.paintInvalidationContainerForStackedContents = |
| 259 toLayoutBoxModelObject(&object); | 261 toLayoutBoxModelObject(&object); |
| 260 } else if (object.isLayoutView()) { | 262 } else if (object.isLayoutView()) { |
| 261 // paintInvalidationContainerForStackedContents is only for stacked descenda
nts in its own frame, | 263 // paintInvalidationContainerForStackedContents is only for stacked |
| 262 // because it doesn't establish stacking context for stacked contents in sub
-frames. | 264 // descendants in its own frame, because it doesn't establish stacking |
| 263 // Contents stacked in the root stacking context in this frame should use th
is frame's paintInvalidationContainer. | 265 // context for stacked contents in sub-frames. |
| 266 // Contents stacked in the root stacking context in this frame should use |
| 267 // this frame's paintInvalidationContainer. |
| 264 context.paintInvalidationContainerForStackedContents = | 268 context.paintInvalidationContainerForStackedContents = |
| 265 context.paintInvalidationContainer; | 269 context.paintInvalidationContainer; |
| 266 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) | 270 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) |
| 267 undoFrameViewContentClipAndScroll.emplace( | 271 undoFrameViewContentClipAndScroll.emplace( |
| 268 *toLayoutView(object).frameView(), context); | 272 *toLayoutView(object).frameView(), context); |
| 269 } else if ( | 273 } else if (object.styleRef().isStacked() && |
| 270 object.styleRef().isStacked() | 274 // This is to exclude some objects (e.g. LayoutText) inheriting |
| 271 // This is to exclude some objects (e.g. LayoutText) inheriting stacked st
yle from parent but aren't actually stacked. | 275 // stacked style from parent but aren't actually stacked. |
| 272 && object.hasLayer() && | 276 object.hasLayer() && |
| 273 context.paintInvalidationContainer != | 277 context.paintInvalidationContainer != |
| 274 context.paintInvalidationContainerForStackedContents) { | 278 context.paintInvalidationContainerForStackedContents) { |
| 275 // The current object is stacked, so we should use m_paintInvalidationContai
nerForStackedContents as its | 279 // The current object is stacked, so we should use |
| 276 // paint invalidation container on which the current object is painted. | 280 // m_paintInvalidationContainerForStackedContents as its paint invalidation |
| 281 // container on which the current object is painted. |
| 277 context.paintInvalidationContainer = | 282 context.paintInvalidationContainer = |
| 278 context.paintInvalidationContainerForStackedContents; | 283 context.paintInvalidationContainerForStackedContents; |
| 279 if (context.forcedSubtreeInvalidationFlags & | 284 if (context.forcedSubtreeInvalidationFlags & |
| 280 PaintInvalidatorContext:: | 285 PaintInvalidatorContext:: |
| 281 ForcedSubtreeFullInvalidationForStackedContents) | 286 ForcedSubtreeFullInvalidationForStackedContents) |
| 282 context.forcedSubtreeInvalidationFlags |= | 287 context.forcedSubtreeInvalidationFlags |= |
| 283 PaintInvalidatorContext::ForcedSubtreeFullInvalidation; | 288 PaintInvalidatorContext::ForcedSubtreeFullInvalidation; |
| 284 } | 289 } |
| 285 | 290 |
| 286 if (object == context.paintInvalidationContainer) { | 291 if (object == context.paintInvalidationContainer) { |
| 287 // When we hit a new paint invalidation container, we don't need to | 292 // When we hit a new paint invalidation container, we don't need to |
| 288 // continue forcing a check for paint invalidation, since we're | 293 // continue forcing a check for paint invalidation, since we're |
| 289 // descending into a different invalidation container. (For instance if | 294 // descending into a different invalidation container. (For instance if |
| 290 // our parents were moved, the entire container will just move.) | 295 // our parents were moved, the entire container will just move.) |
| 291 if (object != context.paintInvalidationContainerForStackedContents) { | 296 if (object != context.paintInvalidationContainerForStackedContents) { |
| 292 // However, we need to keep the ForcedSubtreeFullInvalidationForStackedCon
tents flag | 297 // However, we need to keep the |
| 293 // if the current object isn't the paint invalidation container of stacked
contents. | 298 // ForcedSubtreeFullInvalidationForStackedContents flag if the current |
| 299 // object isn't the paint invalidation container of stacked contents. |
| 294 context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: | 300 context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: |
| 295 ForcedSubtreeFullInvalidationForStackedContents; | 301 ForcedSubtreeFullInvalidationForStackedContents; |
| 296 } else { | 302 } else { |
| 297 context.forcedSubtreeInvalidationFlags = 0; | 303 context.forcedSubtreeInvalidationFlags = 0; |
| 298 } | 304 } |
| 299 } | 305 } |
| 300 | 306 |
| 301 DCHECK(context.paintInvalidationContainer == | 307 DCHECK(context.paintInvalidationContainer == |
| 302 object.containerForPaintInvalidation()); | 308 object.containerForPaintInvalidation()); |
| 303 DCHECK(context.paintingLayer == object.paintingLayer()); | 309 DCHECK(context.paintingLayer == object.paintingLayer()); |
| 304 | 310 |
| 305 if (object.mayNeedPaintInvalidationSubtree()) | 311 if (object.mayNeedPaintInvalidationSubtree()) |
| 306 context.forcedSubtreeInvalidationFlags |= | 312 context.forcedSubtreeInvalidationFlags |= |
| 307 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 313 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| 308 | 314 |
| 309 // TODO(crbug.com/637313): This is temporary before we support filters in pain
t property tree. | 315 // TODO(crbug.com/637313): This is temporary before we support filters in |
| 316 // paint property tree. |
| 310 // TODO(crbug.com/648274): This is a workaround for multi-column contents. | 317 // TODO(crbug.com/648274): This is a workaround for multi-column contents. |
| 311 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) | 318 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) |
| 312 context.forcedSubtreeInvalidationFlags |= | 319 context.forcedSubtreeInvalidationFlags |= |
| 313 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; | 320 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
| 314 | 321 |
| 315 context.oldBounds = object.previousPaintInvalidationRect(); | 322 context.oldBounds = object.previousPaintInvalidationRect(); |
| 316 context.oldLocation = object.previousPositionFromPaintInvalidationBacking(); | 323 context.oldLocation = object.previousPositionFromPaintInvalidationBacking(); |
| 317 context.newBounds = computePaintInvalidationRectInBacking(object, context); | 324 context.newBounds = computePaintInvalidationRectInBacking(object, context); |
| 318 context.newLocation = | 325 context.newLocation = |
| 319 computeLocationFromPaintInvalidationBacking(object, context); | 326 computeLocationFromPaintInvalidationBacking(object, context); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), | 393 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), |
| 387 "PaintInvalidator::invalidatePaintIfNeeded()", "object", | 394 "PaintInvalidator::invalidatePaintIfNeeded()", "object", |
| 388 object.debugName().ascii()); | 395 object.debugName().ascii()); |
| 389 | 396 |
| 390 updateContext(object, context); | 397 updateContext(object, context); |
| 391 | 398 |
| 392 if (!object | 399 if (!object |
| 393 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()
&& | 400 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()
&& |
| 394 context.forcedSubtreeInvalidationFlags == | 401 context.forcedSubtreeInvalidationFlags == |
| 395 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) { | 402 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) { |
| 396 // We are done updating the paint invalidation rect. No other paint invalida
tion work to do for this object. | 403 // We are done updating the paint invalidation rect. No other paint |
| 404 // invalidation work to do for this object. |
| 397 return; | 405 return; |
| 398 } | 406 } |
| 399 | 407 |
| 400 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); | 408 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); |
| 401 switch (reason) { | 409 switch (reason) { |
| 402 case PaintInvalidationDelayedFull: | 410 case PaintInvalidationDelayedFull: |
| 403 m_pendingDelayedPaintInvalidations.append(&object); | 411 m_pendingDelayedPaintInvalidations.append(&object); |
| 404 break; | 412 break; |
| 405 case PaintInvalidationSubtree: | 413 case PaintInvalidationSubtree: |
| 406 context.forcedSubtreeInvalidationFlags |= | 414 context.forcedSubtreeInvalidationFlags |= |
| 407 (PaintInvalidatorContext::ForcedSubtreeFullInvalidation | | 415 (PaintInvalidatorContext::ForcedSubtreeFullInvalidation | |
| 408 PaintInvalidatorContext:: | 416 PaintInvalidatorContext:: |
| 409 ForcedSubtreeFullInvalidationForStackedContents); | 417 ForcedSubtreeFullInvalidationForStackedContents); |
| 410 break; | 418 break; |
| 411 case PaintInvalidationSVGResourceChange: | 419 case PaintInvalidationSVGResourceChange: |
| 412 context.forcedSubtreeInvalidationFlags |= | 420 context.forcedSubtreeInvalidationFlags |= |
| 413 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 421 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| 414 break; | 422 break; |
| 415 default: | 423 default: |
| 416 break; | 424 break; |
| 417 } | 425 } |
| 418 | 426 |
| 419 if (context.oldLocation != context.newLocation) | 427 if (context.oldLocation != context.newLocation) |
| 420 context.forcedSubtreeInvalidationFlags |= | 428 context.forcedSubtreeInvalidationFlags |= |
| 421 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 429 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| 422 | 430 |
| 423 // TODO(crbug.com/533277): This is a workaround for the bug. Remove when we de
tect paint offset change. | 431 // TODO(crbug.com/533277): This is a workaround for the bug. Remove when we |
| 432 // detect paint offset change. |
| 424 if (reason != PaintInvalidationNone && | 433 if (reason != PaintInvalidationNone && |
| 425 hasPercentageTransform(object.styleRef())) | 434 hasPercentageTransform(object.styleRef())) |
| 426 context.forcedSubtreeInvalidationFlags |= | 435 context.forcedSubtreeInvalidationFlags |= |
| 427 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 436 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| 428 | 437 |
| 429 // TODO(crbug.com/490725): This is a workaround for the bug, to force descenda
nt to update paint invalidation | 438 // TODO(crbug.com/490725): This is a workaround for the bug, to force |
| 430 // rects on clipping change. | 439 // descendant to update paint invalidation rects on clipping change. |
| 431 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 440 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
| 432 context.oldBounds != context.newBounds | 441 context.oldBounds != context.newBounds |
| 433 // Note that isLayoutView() below becomes unnecessary after the launch of
root layer scrolling. | 442 // Note that isLayoutView() below becomes unnecessary after the launch of |
| 443 // root layer scrolling. |
| 434 && (object.hasOverflowClip() || object.isLayoutView()) && | 444 && (object.hasOverflowClip() || object.isLayoutView()) && |
| 435 !toLayoutBox(object).usesCompositedScrolling()) | 445 !toLayoutBox(object).usesCompositedScrolling()) |
| 436 context.forcedSubtreeInvalidationFlags |= | 446 context.forcedSubtreeInvalidationFlags |= |
| 437 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 447 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
| 438 | 448 |
| 439 object.getMutableForPainting().clearPaintInvalidationFlags(); | 449 object.getMutableForPainting().clearPaintInvalidationFlags(); |
| 440 } | 450 } |
| 441 | 451 |
| 442 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 452 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
| 443 for (auto target : m_pendingDelayedPaintInvalidations) | 453 for (auto target : m_pendingDelayedPaintInvalidations) |
| 444 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 454 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
| 445 PaintInvalidationDelayedFull); | 455 PaintInvalidationDelayedFull); |
| 446 } | 456 } |
| 447 | 457 |
| 448 } // namespace blink | 458 } // namespace blink |
| OLD | NEW |