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 |