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 |