| 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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 m_treeBuilderContext.current = m_savedContext; | 266 m_treeBuilderContext.current = m_savedContext; |
| 267 } | 267 } |
| 268 | 268 |
| 269 private: | 269 private: |
| 270 PaintPropertyTreeBuilderContext& m_treeBuilderContext; | 270 PaintPropertyTreeBuilderContext& m_treeBuilderContext; |
| 271 PaintPropertyTreeBuilderContext::ContainingBlockContext m_savedContext; | 271 PaintPropertyTreeBuilderContext::ContainingBlockContext m_savedContext; |
| 272 }; | 272 }; |
| 273 | 273 |
| 274 } // namespace | 274 } // namespace |
| 275 | 275 |
| 276 void PaintInvalidator::updateContext(const LayoutObject& object, | 276 void PaintInvalidator::updatePaintInvalidationContainer( |
| 277 PaintInvalidatorContext& context) { | 277 const LayoutObject& object, |
| 278 Optional<ScopedUndoFrameViewContentClipAndScroll> | 278 PaintInvalidatorContext& context) { |
| 279 undoFrameViewContentClipAndScroll; | |
| 280 | |
| 281 if (object.isPaintInvalidationContainer()) { | 279 if (object.isPaintInvalidationContainer()) { |
| 282 context.paintInvalidationContainer = toLayoutBoxModelObject(&object); | 280 context.paintInvalidationContainer = toLayoutBoxModelObject(&object); |
| 283 if (object.styleRef().isStackingContext()) | 281 if (object.styleRef().isStackingContext()) |
| 284 context.paintInvalidationContainerForStackedContents = | 282 context.paintInvalidationContainerForStackedContents = |
| 285 toLayoutBoxModelObject(&object); | 283 toLayoutBoxModelObject(&object); |
| 286 } else if (object.isLayoutView()) { | 284 } else if (object.isLayoutView()) { |
| 287 // paintInvalidationContainerForStackedContents is only for stacked | 285 // paintInvalidationContainerForStackedContents is only for stacked |
| 288 // descendants in its own frame, because it doesn't establish stacking | 286 // descendants in its own frame, because it doesn't establish stacking |
| 289 // context for stacked contents in sub-frames. | 287 // context for stacked contents in sub-frames. |
| 290 // Contents stacked in the root stacking context in this frame should use | 288 // Contents stacked in the root stacking context in this frame should use |
| 291 // this frame's paintInvalidationContainer. | 289 // this frame's paintInvalidationContainer. |
| 292 context.paintInvalidationContainerForStackedContents = | 290 context.paintInvalidationContainerForStackedContents = |
| 293 context.paintInvalidationContainer; | 291 context.paintInvalidationContainer; |
| 294 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) | |
| 295 undoFrameViewContentClipAndScroll.emplace( | |
| 296 *toLayoutView(object).frameView(), context); | |
| 297 } else if (object.isFloatingWithNonContainingBlockParent()) { | 292 } else if (object.isFloatingWithNonContainingBlockParent()) { |
| 298 context.paintInvalidationContainer = | 293 context.paintInvalidationContainer = |
| 299 &object.containerForPaintInvalidation(); | 294 &object.containerForPaintInvalidation(); |
| 300 } else if (object.styleRef().isStacked() && | 295 } else if (object.styleRef().isStacked() && |
| 301 // This is to exclude some objects (e.g. LayoutText) inheriting | 296 // This is to exclude some objects (e.g. LayoutText) inheriting |
| 302 // stacked style from parent but aren't actually stacked. | 297 // stacked style from parent but aren't actually stacked. |
| 303 object.hasLayer() && | 298 object.hasLayer() && |
| 304 context.paintInvalidationContainer != | 299 context.paintInvalidationContainer != |
| 305 context.paintInvalidationContainerForStackedContents) { | 300 context.paintInvalidationContainerForStackedContents) { |
| 306 // The current object is stacked, so we should use | 301 // The current object is stacked, so we should use |
| (...skipping 20 matching lines...) Expand all Loading... |
| 327 context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: | 322 context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: |
| 328 ForcedSubtreeFullInvalidationForStackedContents; | 323 ForcedSubtreeFullInvalidationForStackedContents; |
| 329 } else { | 324 } else { |
| 330 context.forcedSubtreeInvalidationFlags = 0; | 325 context.forcedSubtreeInvalidationFlags = 0; |
| 331 } | 326 } |
| 332 } | 327 } |
| 333 | 328 |
| 334 DCHECK(context.paintInvalidationContainer == | 329 DCHECK(context.paintInvalidationContainer == |
| 335 object.containerForPaintInvalidation()); | 330 object.containerForPaintInvalidation()); |
| 336 DCHECK(context.paintingLayer == object.paintingLayer()); | 331 DCHECK(context.paintingLayer == object.paintingLayer()); |
| 332 } |
| 337 | 333 |
| 338 if (object.mayNeedPaintInvalidationSubtree()) | 334 void PaintInvalidator::updateVisualRect(const LayoutObject& object, |
| 339 context.forcedSubtreeInvalidationFlags |= | 335 PaintInvalidatorContext& context) { |
| 340 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 336 Optional<ScopedUndoFrameViewContentClipAndScroll> |
| 337 undoFrameViewContentClipAndScroll; |
| 338 |
| 339 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
| 340 object.isLayoutView() && !object.isPaintInvalidationContainer()) { |
| 341 undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(), |
| 342 context); |
| 343 } |
| 341 | 344 |
| 342 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter | 345 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter |
| 343 // geometry effects, after skia optimizes filter's mapRect operation. | 346 // geometry effects, after skia optimizes filter's mapRect operation. |
| 344 // TODO(crbug.com/648274): This is a workaround for multi-column contents. | 347 // TODO(crbug.com/648274): This is a workaround for multi-column contents. |
| 345 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { | 348 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { |
| 346 context.forcedSubtreeInvalidationFlags |= | 349 context.forcedSubtreeInvalidationFlags |= |
| 347 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; | 350 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
| 348 } | 351 } |
| 349 | 352 |
| 350 ObjectPaintInvalidator objectPaintInvalidator(object); | 353 ObjectPaintInvalidator objectPaintInvalidator(object); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 | 391 |
| 389 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 392 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 390 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); | 393 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); |
| 391 frameView.invalidatePaintOfScrollControlsIfNeeded(context); | 394 frameView.invalidatePaintOfScrollControlsIfNeeded(context); |
| 392 } | 395 } |
| 393 } | 396 } |
| 394 | 397 |
| 395 void PaintInvalidator::invalidatePaintIfNeeded( | 398 void PaintInvalidator::invalidatePaintIfNeeded( |
| 396 const LayoutObject& object, | 399 const LayoutObject& object, |
| 397 PaintInvalidatorContext& context) { | 400 PaintInvalidatorContext& context) { |
| 401 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), |
| 402 "PaintInvalidator::invalidatePaintIfNeeded()", "object", |
| 403 object.debugName().ascii()); |
| 404 |
| 398 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); | 405 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); |
| 399 | 406 |
| 400 // The paint offset should already be updated through | 407 // The paint offset should already be updated through |
| 401 // PaintPropertyTreeBuilder::updatePropertiesForSelf. | 408 // PaintPropertyTreeBuilder::updatePropertiesForSelf. |
| 402 DCHECK(context.treeBuilderContext.current.paintOffset == | 409 DCHECK(context.treeBuilderContext.current.paintOffset == |
| 403 object.paintOffset()); | 410 object.paintOffset()); |
| 404 | 411 |
| 405 if (!context.forcedSubtreeInvalidationFlags && | |
| 406 !object | |
| 407 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) | |
| 408 return; | |
| 409 | |
| 410 updatePaintingLayer(object, context); | 412 updatePaintingLayer(object, context); |
| 411 | 413 |
| 412 if (object.document().printing() && | 414 if (object.document().printing() && |
| 413 !RuntimeEnabledFeatures::printBrowserEnabled()) | 415 !RuntimeEnabledFeatures::printBrowserEnabled()) |
| 414 return; // Don't invalidate paints if we're printing. | 416 return; // Don't invalidate paints if we're printing. |
| 415 | 417 |
| 416 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), | 418 updatePaintInvalidationContainer(object, context); |
| 417 "PaintInvalidator::invalidatePaintIfNeeded()", "object", | |
| 418 object.debugName().ascii()); | |
| 419 | 419 |
| 420 updateContext(object, context); | 420 bool objectShouldCheckForPaintInvalidation = |
| 421 object |
| 422 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState(); |
| 423 if (!context.forcedSubtreeInvalidationFlags && |
| 424 !objectShouldCheckForPaintInvalidation) |
| 425 return; |
| 421 | 426 |
| 422 if (!object | 427 updateVisualRect(object, context); |
| 423 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()
&& | 428 |
| 429 if (!objectShouldCheckForPaintInvalidation && |
| 424 context.forcedSubtreeInvalidationFlags == | 430 context.forcedSubtreeInvalidationFlags == |
| 425 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) { | 431 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) { |
| 426 // We are done updating the visual rect. No other paint invalidation work to | 432 // We are done updating the visual rect. No other paint invalidation work to |
| 427 // do for this object. | 433 // do for this object. |
| 428 return; | 434 return; |
| 429 } | 435 } |
| 430 | 436 |
| 431 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); | 437 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); |
| 432 switch (reason) { | 438 switch (reason) { |
| 433 case PaintInvalidationDelayedFull: | 439 case PaintInvalidationDelayedFull: |
| 434 m_pendingDelayedPaintInvalidations.push_back(&object); | 440 m_pendingDelayedPaintInvalidations.push_back(&object); |
| 435 break; | 441 break; |
| 436 case PaintInvalidationSubtree: | 442 case PaintInvalidationSubtree: |
| 437 context.forcedSubtreeInvalidationFlags |= | 443 context.forcedSubtreeInvalidationFlags |= |
| 438 (PaintInvalidatorContext::ForcedSubtreeFullInvalidation | | 444 (PaintInvalidatorContext::ForcedSubtreeFullInvalidation | |
| 439 PaintInvalidatorContext:: | 445 PaintInvalidatorContext:: |
| 440 ForcedSubtreeFullInvalidationForStackedContents); | 446 ForcedSubtreeFullInvalidationForStackedContents); |
| 441 break; | 447 break; |
| 442 case PaintInvalidationSVGResourceChange: | 448 case PaintInvalidationSVGResourceChange: |
| 443 context.forcedSubtreeInvalidationFlags |= | 449 context.forcedSubtreeInvalidationFlags |= |
| 444 PaintInvalidatorContext::ForcedSubtreeSVGResourceChange; | 450 PaintInvalidatorContext::ForcedSubtreeSVGResourceChange; |
| 445 break; | 451 break; |
| 446 default: | 452 default: |
| 447 break; | 453 break; |
| 448 } | 454 } |
| 449 | 455 |
| 456 if (object.mayNeedPaintInvalidationSubtree()) { |
| 457 context.forcedSubtreeInvalidationFlags |= |
| 458 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| 459 } |
| 460 |
| 450 if (context.oldLocation != context.newLocation) { | 461 if (context.oldLocation != context.newLocation) { |
| 451 context.forcedSubtreeInvalidationFlags |= | 462 context.forcedSubtreeInvalidationFlags |= |
| 452 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 463 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| 453 } | 464 } |
| 454 | |
| 455 // TODO(crbug.com/490725): This is a workaround for the bug, to force | |
| 456 // descendant to update visual rects on clipping change. | |
| 457 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | |
| 458 context.oldVisualRect != context.newVisualRect | |
| 459 // Note that isLayoutView() below becomes unnecessary after the launch of | |
| 460 // root layer scrolling. | |
| 461 && (object.hasOverflowClip() || object.isLayoutView()) && | |
| 462 !toLayoutBox(object).usesCompositedScrolling()) | |
| 463 context.forcedSubtreeInvalidationFlags |= | |
| 464 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | |
| 465 } | 465 } |
| 466 | 466 |
| 467 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 467 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
| 468 for (auto target : m_pendingDelayedPaintInvalidations) | 468 for (auto target : m_pendingDelayedPaintInvalidations) |
| 469 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 469 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
| 470 PaintInvalidationDelayedFull); | 470 PaintInvalidationDelayedFull); |
| 471 } | 471 } |
| 472 | 472 |
| 473 } // namespace blink | 473 } // namespace blink |
| OLD | NEW |