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" |
11 #include "core/layout/LayoutBlockFlow.h" | 11 #include "core/layout/LayoutBlockFlow.h" |
12 #include "core/layout/LayoutObject.h" | |
13 #include "core/layout/LayoutTable.h" | 12 #include "core/layout/LayoutTable.h" |
14 #include "core/layout/LayoutView.h" | 13 #include "core/layout/LayoutView.h" |
15 #include "core/layout/svg/SVGLayoutSupport.h" | 14 #include "core/layout/svg/SVGLayoutSupport.h" |
| 15 #include "core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h" |
16 #include "core/paint/ObjectPaintProperties.h" | 16 #include "core/paint/ObjectPaintProperties.h" |
17 #include "core/paint/PaintLayer.h" | 17 #include "core/paint/PaintLayer.h" |
18 #include "core/paint/PaintLayerScrollableArea.h" | 18 #include "core/paint/PaintLayerScrollableArea.h" |
19 #include "core/paint/PaintPropertyTreeBuilder.h" | |
20 #include "wtf/Optional.h" | 19 #include "wtf/Optional.h" |
21 | 20 |
22 namespace blink { | 21 namespace blink { |
23 | 22 |
24 template <typename Rect> | 23 template <typename Rect> |
25 static LayoutRect slowMapToVisualRectInAncestorSpace( | 24 static LayoutRect slowMapToVisualRectInAncestorSpace( |
26 const LayoutObject& object, | 25 const LayoutObject& object, |
27 const LayoutBoxModelObject& ancestor, | 26 const LayoutBoxModelObject& ancestor, |
28 const Rect& rect) { | 27 const Rect& rect) { |
29 if (object.isSVGChild()) { | 28 if (object.isSVGChild()) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 result = LayoutRect(rect); | 99 result = LayoutRect(rect); |
101 } else { | 100 } else { |
102 // For non-root SVG, the input rect is in local SVG coordinates in which | 101 // For non-root SVG, the input rect is in local SVG coordinates in which |
103 // paint offset doesn't apply. | 102 // paint offset doesn't apply. |
104 if (!isSVGChild) | 103 if (!isSVGChild) |
105 rect.moveBy(Point(object.paintOffset())); | 104 rect.moveBy(Point(object.paintOffset())); |
106 | 105 |
107 const auto* containerContentsProperties = | 106 const auto* containerContentsProperties = |
108 context.paintInvalidationContainer->contentsProperties(); | 107 context.paintInvalidationContainer->contentsProperties(); |
109 | 108 |
110 if (context.m_treeBuilderContext.current.transform == | 109 if (context.m_treeBuilderContext->current.transform == |
111 containerContentsProperties->transform() && | 110 containerContentsProperties->transform() && |
112 context.m_treeBuilderContext.current.clip == | 111 context.m_treeBuilderContext->current.clip == |
113 containerContentsProperties->clip()) { | 112 containerContentsProperties->clip()) { |
114 result = LayoutRect(rect); | 113 result = LayoutRect(rect); |
115 } else { | 114 } else { |
116 // Use enclosingIntRect to ensure the final visual rect will cover the | 115 // Use enclosingIntRect to ensure the final visual rect will cover the |
117 // rect in source coordinates no matter if the painting will use pixel | 116 // rect in source coordinates no matter if the painting will use pixel |
118 // snapping, when transforms are applied. If there is no transform, | 117 // snapping, when transforms are applied. If there is no transform, |
119 // enclosingIntRect is applied in the last step of paint invalidation | 118 // enclosingIntRect is applied in the last step of paint invalidation |
120 // (see CompositedLayerMapping::setContentsNeedDisplayInRect()). | 119 // (see CompositedLayerMapping::setContentsNeedDisplayInRect()). |
121 if (!isSVGChild && context.m_treeBuilderContext.current.transform != | 120 if (!isSVGChild && context.m_treeBuilderContext->current.transform != |
122 containerContentsProperties->transform()) | 121 containerContentsProperties->transform()) |
123 rect = Rect(enclosingIntRect(rect)); | 122 rect = Rect(enclosingIntRect(rect)); |
124 | 123 |
125 PropertyTreeState currentTreeState( | 124 PropertyTreeState currentTreeState( |
126 context.m_treeBuilderContext.current.transform, | 125 context.m_treeBuilderContext->current.transform, |
127 context.m_treeBuilderContext.current.clip, nullptr); | 126 context.m_treeBuilderContext->current.clip, nullptr); |
128 | 127 |
129 FloatRect floatRect(rect); | 128 FloatRect floatRect(rect); |
130 context.m_geometryMapper.sourceToDestinationVisualRect( | 129 context.m_geometryMapper.sourceToDestinationVisualRect( |
131 currentTreeState, *containerContentsProperties, floatRect); | 130 currentTreeState, *containerContentsProperties, floatRect); |
132 result = LayoutRect(floatRect); | 131 result = LayoutRect(floatRect); |
133 } | 132 } |
134 | 133 |
135 // Convert the result to the container's contents space. | 134 // Convert the result to the container's contents space. |
136 result.moveBy(-context.paintInvalidationContainer->paintOffset()); | 135 result.moveBy(-context.paintInvalidationContainer->paintOffset()); |
137 } | 136 } |
138 | 137 |
139 object.adjustVisualRectForRasterEffects(result); | 138 object.adjustVisualRectForRasterEffects(result); |
140 | 139 |
141 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 140 PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
142 *context.paintInvalidationContainer, result); | 141 *context.paintInvalidationContainer, result); |
143 | 142 |
144 result.move(object.scrollAdjustmentForPaintInvalidation( | 143 result.move(object.scrollAdjustmentForPaintInvalidation( |
145 *context.paintInvalidationContainer)); | 144 *context.paintInvalidationContainer)); |
146 | 145 |
147 return result; | 146 return result; |
148 } | 147 } |
149 | 148 |
150 void PaintInvalidatorContext::mapLocalRectToVisualRectInBacking( | 149 void PaintInvalidatorContext::mapLocalRectToVisualRectInBacking( |
151 const LayoutObject& object, | 150 const LayoutObject& object, |
152 LayoutRect& rect) const { | 151 LayoutRect& rect) const { |
| 152 DCHECK(needsVisualRectUpdate(object)); |
| 153 std::unique_ptr<GeometryMapper> geometryMapper = GeometryMapper::create(); |
153 rect = PaintInvalidator::mapLocalRectToVisualRectInBacking<LayoutRect, | 154 rect = PaintInvalidator::mapLocalRectToVisualRectInBacking<LayoutRect, |
154 LayoutPoint>( | 155 LayoutPoint>( |
155 object, rect, *this); | 156 object, rect, *this); |
156 } | 157 } |
157 | 158 |
158 LayoutRect PaintInvalidator::computeVisualRectInBacking( | 159 LayoutRect PaintInvalidator::computeVisualRectInBacking( |
159 const LayoutObject& object, | 160 const LayoutObject& object, |
160 const PaintInvalidatorContext& context) { | 161 const PaintInvalidatorContext& context) { |
161 if (object.isSVGChild()) { | 162 if (object.isSVGChild()) { |
162 FloatRect localRect = SVGLayoutSupport::localVisualRect(object); | 163 FloatRect localRect = SVGLayoutSupport::localVisualRect(object); |
(...skipping 10 matching lines...) Expand all Loading... |
173 // In SPv2, locationInBacking is in the space of their local transform node. | 174 // In SPv2, locationInBacking is in the space of their local transform node. |
174 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 175 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
175 return object.paintOffset(); | 176 return object.paintOffset(); |
176 | 177 |
177 LayoutPoint point; | 178 LayoutPoint point; |
178 if (object != context.paintInvalidationContainer) { | 179 if (object != context.paintInvalidationContainer) { |
179 point.moveBy(object.paintOffset()); | 180 point.moveBy(object.paintOffset()); |
180 | 181 |
181 const auto* containerTransform = | 182 const auto* containerTransform = |
182 context.paintInvalidationContainer->contentsProperties()->transform(); | 183 context.paintInvalidationContainer->contentsProperties()->transform(); |
183 if (context.m_treeBuilderContext.current.transform != containerTransform) { | 184 if (context.m_treeBuilderContext->current.transform != containerTransform) { |
184 FloatRect rect = FloatRect(FloatPoint(point), FloatSize()); | 185 FloatRect rect = FloatRect(FloatPoint(point), FloatSize()); |
185 context.m_geometryMapper.sourceToDestinationRect( | 186 context.m_geometryMapper.sourceToDestinationRect( |
186 context.m_treeBuilderContext.current.transform, containerTransform, | 187 context.m_treeBuilderContext->current.transform, containerTransform, |
187 rect); | 188 rect); |
188 point = LayoutPoint(rect.location()); | 189 point = LayoutPoint(rect.location()); |
189 } | 190 } |
190 | 191 |
191 // Convert the result to the container's contents space. | 192 // Convert the result to the container's contents space. |
192 point.moveBy(-context.paintInvalidationContainer->paintOffset()); | 193 point.moveBy(-context.paintInvalidationContainer->paintOffset()); |
193 } | 194 } |
194 | 195 |
195 if (context.paintInvalidationContainer->layer()->groupedMapping()) { | 196 if (context.paintInvalidationContainer->layer()->groupedMapping()) { |
196 FloatPoint floatPoint(point); | 197 FloatPoint floatPoint(point); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 context.forcedSubtreeInvalidationFlags |= | 323 context.forcedSubtreeInvalidationFlags |= |
323 PaintInvalidatorContext::ForcedSubtreeFullInvalidation; | 324 PaintInvalidatorContext::ForcedSubtreeFullInvalidation; |
324 } | 325 } |
325 | 326 |
326 if (object == context.paintInvalidationContainer) { | 327 if (object == context.paintInvalidationContainer) { |
327 // When we hit a new paint invalidation container, we don't need to | 328 // When we hit a new paint invalidation container, we don't need to |
328 // continue forcing a check for paint invalidation, since we're | 329 // continue forcing a check for paint invalidation, since we're |
329 // descending into a different invalidation container. (For instance if | 330 // descending into a different invalidation container. (For instance if |
330 // our parents were moved, the entire container will just move.) | 331 // our parents were moved, the entire container will just move.) |
331 if (object != context.paintInvalidationContainerForStackedContents) { | 332 if (object != context.paintInvalidationContainerForStackedContents) { |
332 // However, we need to keep the | 333 // However, we need to keep ForcedSubtreeVisualRectUpdate and |
333 // ForcedSubtreeFullInvalidationForStackedContents flag if the current | 334 // ForcedSubtreeFullInvalidationForStackedContents flags if the current |
334 // object isn't the paint invalidation container of stacked contents. | 335 // object isn't the paint invalidation container of stacked contents. |
335 context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: | 336 context.forcedSubtreeInvalidationFlags &= |
336 ForcedSubtreeFullInvalidationForStackedContents; | 337 (PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate | |
| 338 PaintInvalidatorContext:: |
| 339 ForcedSubtreeFullInvalidationForStackedContents); |
337 } else { | 340 } else { |
338 context.forcedSubtreeInvalidationFlags = 0; | 341 context.forcedSubtreeInvalidationFlags = 0; |
339 } | 342 } |
340 } | 343 } |
341 | 344 |
342 DCHECK(context.paintInvalidationContainer == | 345 DCHECK(context.paintInvalidationContainer == |
343 object.containerForPaintInvalidation()); | 346 object.containerForPaintInvalidation()); |
344 DCHECK(context.paintingLayer == object.paintingLayer()); | 347 DCHECK(context.paintingLayer == object.paintingLayer()); |
345 } | 348 } |
346 | 349 |
| 350 void PaintInvalidator::updateVisualRectIfNeeded( |
| 351 const LayoutObject& object, |
| 352 PaintInvalidatorContext& context) { |
| 353 context.oldVisualRect = object.visualRect(); |
| 354 context.oldLocation = ObjectPaintInvalidator(object).locationInBacking(); |
| 355 |
| 356 #if DCHECK_IS_ON() |
| 357 FindObjectVisualRectNeedingUpdateScope finder(object, context); |
| 358 #endif |
| 359 |
| 360 if (!context.needsVisualRectUpdate(object)) { |
| 361 context.newLocation = context.oldLocation; |
| 362 return; |
| 363 } |
| 364 |
| 365 updateVisualRect(object, context); |
| 366 } |
| 367 |
347 void PaintInvalidator::updateVisualRect(const LayoutObject& object, | 368 void PaintInvalidator::updateVisualRect(const LayoutObject& object, |
348 PaintInvalidatorContext& context) { | 369 PaintInvalidatorContext& context) { |
| 370 // The paint offset should already be updated through |
| 371 // PaintPropertyTreeBuilder::updatePropertiesForSelf. |
| 372 DCHECK(context.m_treeBuilderContext); |
| 373 DCHECK(context.m_treeBuilderContext->current.paintOffset == |
| 374 object.paintOffset()); |
| 375 |
349 Optional<ScopedUndoFrameViewContentClipAndScroll> | 376 Optional<ScopedUndoFrameViewContentClipAndScroll> |
350 undoFrameViewContentClipAndScroll; | 377 undoFrameViewContentClipAndScroll; |
351 | 378 |
352 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && | 379 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
353 object.isLayoutView() && !object.isPaintInvalidationContainer()) { | 380 object.isLayoutView() && !object.isPaintInvalidationContainer()) { |
354 undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(), | 381 undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(), |
355 context.m_treeBuilderContext); | 382 *context.m_treeBuilderContext); |
356 } | 383 } |
357 | 384 |
358 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter | |
359 // geometry effects, after skia optimizes filter's mapRect operation. | |
360 // TODO(crbug.com/648274): This is a workaround for multi-column contents. | |
361 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { | |
362 context.forcedSubtreeInvalidationFlags |= | |
363 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; | |
364 } | |
365 | |
366 ObjectPaintInvalidator objectPaintInvalidator(object); | |
367 context.oldVisualRect = object.visualRect(); | |
368 context.oldLocation = objectPaintInvalidator.locationInBacking(); | |
369 | |
370 LayoutRect newVisualRect = computeVisualRectInBacking(object, context); | 385 LayoutRect newVisualRect = computeVisualRectInBacking(object, context); |
371 if (object.isBoxModelObject()) { | 386 if (object.isBoxModelObject()) { |
372 context.newLocation = computeLocationInBacking(object, context); | 387 context.newLocation = computeLocationInBacking(object, context); |
373 | |
374 // Location of empty visual rect doesn't affect paint invalidation. Set it | 388 // Location of empty visual rect doesn't affect paint invalidation. Set it |
375 // to newLocation to avoid saving the previous location separately in | 389 // to newLocation to avoid saving the previous location separately in |
376 // ObjectPaintInvalidator. | 390 // ObjectPaintInvalidator. |
377 if (newVisualRect.isEmpty()) | 391 if (newVisualRect.isEmpty()) |
378 newVisualRect.setLocation(context.newLocation); | 392 newVisualRect.setLocation(context.newLocation); |
379 } else { | 393 } else { |
380 // Use visual rect location for non-LayoutBoxModelObject because it suffices | 394 // Use visual rect location for non-LayoutBoxModelObject because it suffices |
381 // to check whether a visual rect changes for layout caused invalidation. | 395 // to check whether a visual rect changes for layout caused invalidation. |
382 context.newLocation = newVisualRect.location(); | 396 context.newLocation = newVisualRect.location(); |
383 } | 397 } |
384 | 398 |
385 object.getMutableForPainting().setVisualRect(newVisualRect); | 399 object.getMutableForPainting().setVisualRect(newVisualRect); |
386 objectPaintInvalidator.setLocationInBacking(context.newLocation); | 400 ObjectPaintInvalidator(object).setLocationInBacking(context.newLocation); |
387 } | 401 } |
388 | 402 |
389 void PaintInvalidator::invalidatePaintIfNeeded( | 403 void PaintInvalidator::invalidatePaintIfNeeded( |
390 FrameView& frameView, | 404 FrameView& frameView, |
391 PaintInvalidatorContext& context) { | 405 PaintInvalidatorContext& context) { |
392 LayoutView* layoutView = frameView.layoutView(); | 406 LayoutView* layoutView = frameView.layoutView(); |
393 CHECK(layoutView); | 407 CHECK(layoutView); |
394 | 408 |
395 context.paintInvalidationContainer = | 409 context.paintInvalidationContainer = |
396 context.paintInvalidationContainerForStackedContents = | 410 context.paintInvalidationContainerForStackedContents = |
397 &layoutView->containerForPaintInvalidation(); | 411 &layoutView->containerForPaintInvalidation(); |
398 context.paintingLayer = layoutView->layer(); | 412 context.paintingLayer = layoutView->layer(); |
399 | 413 |
400 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 414 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
401 ScopedUndoFrameViewContentClipAndScroll undo(frameView, | 415 Optional<ScopedUndoFrameViewContentClipAndScroll> undo; |
402 context.m_treeBuilderContext); | 416 if (context.m_treeBuilderContext) |
| 417 undo.emplace(frameView, *context.m_treeBuilderContext); |
403 frameView.invalidatePaintOfScrollControlsIfNeeded(context); | 418 frameView.invalidatePaintOfScrollControlsIfNeeded(context); |
404 } | 419 } |
405 } | 420 } |
406 | 421 |
407 void PaintInvalidator::invalidatePaintIfNeeded( | 422 void PaintInvalidator::invalidatePaintIfNeeded( |
408 const LayoutObject& object, | 423 const LayoutObject& object, |
409 PaintInvalidatorContext& context) { | 424 PaintInvalidatorContext& context) { |
410 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), | 425 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), |
411 "PaintInvalidator::invalidatePaintIfNeeded()", "object", | 426 "PaintInvalidator::invalidatePaintIfNeeded()", "object", |
412 object.debugName().ascii()); | 427 object.debugName().ascii()); |
413 | 428 |
414 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); | 429 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); |
415 | 430 |
416 // The paint offset should already be updated through | |
417 // PaintPropertyTreeBuilder::updatePropertiesForSelf. | |
418 DCHECK(context.m_treeBuilderContext.current.paintOffset == | |
419 object.paintOffset()); | |
420 | |
421 updatePaintingLayer(object, context); | 431 updatePaintingLayer(object, context); |
422 | 432 |
423 if (object.document().printing() && | 433 if (object.document().printing() && |
424 !RuntimeEnabledFeatures::printBrowserEnabled()) | 434 !RuntimeEnabledFeatures::printBrowserEnabled()) |
425 return; // Don't invalidate paints if we're printing. | 435 return; // Don't invalidate paints if we're printing. |
426 | 436 |
427 updatePaintInvalidationContainer(object, context); | 437 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter |
428 | 438 // geometry effects, after skia optimizes filter's mapRect operation. |
429 bool objectShouldCheckForPaintInvalidation = | 439 // TODO(crbug.com/648274): This is a workaround for multi-column contents. |
430 object.shouldCheckForPaintInvalidation(); | 440 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { |
431 if (!context.forcedSubtreeInvalidationFlags && | 441 context.forcedSubtreeInvalidationFlags |= |
432 !objectShouldCheckForPaintInvalidation) { | 442 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
433 #if CHECK_VISUAL_RECT_UPDATE | |
434 updateVisualRect(object, context); | |
435 DCHECK( | |
436 (context.oldVisualRect.isEmpty() && context.newVisualRect.isEmpty()) || | |
437 enclosingIntRect(context.oldVisualRect) == | |
438 enclosingIntRect(context.newVisualRect)) | |
439 << "Visual rect changed without needing paint invalidation:" | |
440 << " object=" << object.debugName() | |
441 << " old=" << context.oldVisualRect.toString() | |
442 << " new=" << context.newVisualRect.toString(); | |
443 DCHECK(object.isText() || context.oldLocation == context.newLocation) | |
444 << "Location changed without needing paint invalidation:" | |
445 << " old=" << context.oldLocation.toString() | |
446 << " new=" << context.newLocation.toString(); | |
447 #endif | |
448 return; | |
449 } | 443 } |
450 | 444 |
451 updateVisualRect(object, context); | 445 updatePaintInvalidationContainer(object, context); |
| 446 updateVisualRectIfNeeded(object, context); |
452 | 447 |
453 if (!objectShouldCheckForPaintInvalidation && | 448 if (!object.shouldCheckForPaintInvalidation() && |
454 context.forcedSubtreeInvalidationFlags == | 449 !(context.forcedSubtreeInvalidationFlags & |
455 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) { | 450 ~PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate)) { |
456 // We are done updating the visual rect. No other paint invalidation work to | 451 // We are done updating anything needed. No other paint invalidation work to |
457 // do for this object. | 452 // do for this object. |
458 return; | 453 return; |
459 } | 454 } |
460 | 455 |
461 if (object.isSVGHiddenContainer()) { | 456 if (object.isSVGHiddenContainer()) { |
462 context.forcedSubtreeInvalidationFlags |= | 457 context.forcedSubtreeInvalidationFlags |= |
463 PaintInvalidatorContext::ForcedSubtreeNoRasterInvalidation; | 458 PaintInvalidatorContext::ForcedSubtreeNoRasterInvalidation; |
464 } | 459 } |
465 | 460 |
466 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); | 461 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); |
(...skipping 17 matching lines...) Expand all Loading... |
484 | 479 |
485 if (object.mayNeedPaintInvalidationSubtree()) { | 480 if (object.mayNeedPaintInvalidationSubtree()) { |
486 context.forcedSubtreeInvalidationFlags |= | 481 context.forcedSubtreeInvalidationFlags |= |
487 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 482 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
488 } | 483 } |
489 | 484 |
490 if (context.oldLocation != context.newLocation) { | 485 if (context.oldLocation != context.newLocation) { |
491 context.forcedSubtreeInvalidationFlags |= | 486 context.forcedSubtreeInvalidationFlags |= |
492 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 487 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
493 } | 488 } |
| 489 |
| 490 if (context.forcedSubtreeInvalidationFlags && |
| 491 context.needsVisualRectUpdate(object)) { |
| 492 // If any subtree flag is set, we also need to pass needsVisualRectUpdate |
| 493 // requirement to the subtree. |
| 494 context.forcedSubtreeInvalidationFlags |= |
| 495 PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate; |
| 496 } |
494 } | 497 } |
495 | 498 |
496 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 499 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
497 for (auto target : m_pendingDelayedPaintInvalidations) | 500 for (auto target : m_pendingDelayedPaintInvalidations) { |
498 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 501 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
499 PaintInvalidationDelayedFull); | 502 PaintInvalidationDelayedFull); |
| 503 } |
500 } | 504 } |
501 | 505 |
502 } // namespace blink | 506 } // namespace blink |
OLD | NEW |