| 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/ObjectPaintInvalidator.h" | 5 #include "core/paint/ObjectPaintInvalidator.h" |
| 6 | 6 |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/frame/LocalFrame.h" | 8 #include "core/frame/LocalFrame.h" |
| 9 #include "core/layout/LayoutBlockFlow.h" | 9 #include "core/layout/LayoutBlockFlow.h" |
| 10 #include "core/layout/compositing/CompositedLayerMapping.h" | 10 #include "core/layout/compositing/CompositedLayerMapping.h" |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 m_object.getMutableForPainting().setPreviousBackgroundObscured(backgroun
dObscured); | 355 m_object.getMutableForPainting().setPreviousBackgroundObscured(backgroun
dObscured); |
| 356 backgroundObscurationChanged = true; | 356 backgroundObscurationChanged = true; |
| 357 } | 357 } |
| 358 | 358 |
| 359 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::Forc
edSubtreeFullInvalidation) | 359 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::Forc
edSubtreeFullInvalidation) |
| 360 return PaintInvalidationSubtree; | 360 return PaintInvalidationSubtree; |
| 361 | 361 |
| 362 if (m_object.shouldDoFullPaintInvalidation()) | 362 if (m_object.shouldDoFullPaintInvalidation()) |
| 363 return m_object.fullPaintInvalidationReason(); | 363 return m_object.fullPaintInvalidationReason(); |
| 364 | 364 |
| 365 if (m_context.oldBounds.isEmpty() && m_context.newBounds.isEmpty()) | 365 //if (m_context.oldBounds.isEmpty() && m_context.newBounds.isEmpty()) |
| 366 return PaintInvalidationNone; | 366 // return PaintInvalidationNone; |
| 367 | 367 |
| 368 if (backgroundObscurationChanged) | 368 if (backgroundObscurationChanged) |
| 369 return PaintInvalidationBackgroundObscurationChange; | 369 return PaintInvalidationBackgroundObscurationChange; |
| 370 | 370 |
| 371 if (m_object.paintedOutputOfObjectHasNoEffectRegardlessOfSize()) | 371 if (m_object.paintedOutputOfObjectHasNoEffectRegardlessOfSize()) |
| 372 return PaintInvalidationNone; | 372 return PaintInvalidationNone; |
| 373 | 373 |
| 374 const ComputedStyle& style = m_object.styleRef(); | 374 const ComputedStyle& style = m_object.styleRef(); |
| 375 | 375 |
| 376 // The outline may change shape because of position change of descendants. F
or simplicity, | 376 // The outline may change shape because of position change of descendants. F
or simplicity, |
| 377 // just force full paint invalidation if this object is marked for checking
paint invalidation | 377 // just force full paint invalidation if this object is marked for checking
paint invalidation |
| 378 // for any reason. | 378 // for any reason. |
| 379 // TODO(wangxianzhu): Optimize this. | 379 // TODO(wangxianzhu): Optimize this. |
| 380 if (style.hasOutline()) | 380 if (style.hasOutline()) |
| 381 return PaintInvalidationOutline; | 381 return PaintInvalidationOutline; |
| 382 | 382 |
| 383 bool locationChanged = m_context.newLocation != m_context.oldLocation; | 383 bool locationChanged = m_context.newLocation != m_context.oldLocation; |
| 384 | 384 |
| 385 // If the bounds are the same then we know that none of the statements below | 385 // If the bounds are the same then we know that none of the statements below |
| 386 // can match, so we can early out. However, we can't return PaintInvalidatio
nNone even if | 386 // can match, so we can early out. However, we can't return PaintInvalidatio
nNone even if |
| 387 // !locationChagned, but conservatively return PaintInvalidationIncremental
because we are | 387 // !locationChagned, but conservatively return PaintInvalidationIncremental
because we are |
| 388 // not sure whether paint invalidation is actually needed just based on info
rmation known | 388 // not sure whether paint invalidation is actually needed just based on info
rmation known |
| 389 // to LayoutObject. For example, a LayoutBox may need paint invalidation if
border box changes. | 389 // to LayoutObject. For example, a LayoutBox may need paint invalidation if
border box changes. |
| 390 if (m_context.oldBounds == m_context.newBounds) | 390 if (m_context.oldBounds == m_context.newBounds) |
| 391 return locationChanged ? PaintInvalidationLocationChange : PaintInvalida
tionIncremental; | 391 return locationChanged ? PaintInvalidationLocationChange : PaintInvalida
tionNone; |
| 392 |
| 393 // If we shifted, we don't know the exact reason so we are conservative and
trigger a full invalidation. Shifting could |
| 394 // be caused by some layout property (left / top) or some in-flow layoutObje
ct inserted / removed before us in the tree. |
| 395 if (m_context.newBounds.location() != m_context.oldBounds.location()) |
| 396 return PaintInvalidationBoundsChange; |
| 392 | 397 |
| 393 // If the size is zero on one of our bounds then we know we're going to have | 398 // If the size is zero on one of our bounds then we know we're going to have |
| 394 // to do a full invalidation of either old bounds or new bounds. | 399 // to do a full invalidation of either old bounds or new bounds. |
| 395 if (m_context.oldBounds.isEmpty()) | 400 if (m_context.oldBounds.isEmpty()) |
| 396 return PaintInvalidationBecameVisible; | 401 return PaintInvalidationBecameVisible; |
| 397 if (m_context.newBounds.isEmpty()) | 402 if (m_context.newBounds.isEmpty()) |
| 398 return PaintInvalidationBecameInvisible; | 403 return PaintInvalidationBecameInvisible; |
| 399 | 404 |
| 400 // If we shifted, we don't know the exact reason so we are conservative and
trigger a full invalidation. Shifting could | |
| 401 // be caused by some layout property (left / top) or some in-flow layoutObje
ct inserted / removed before us in the tree. | |
| 402 if (m_context.newBounds.location() != m_context.oldBounds.location()) | |
| 403 return PaintInvalidationBoundsChange; | |
| 404 | |
| 405 if (locationChanged) | 405 if (locationChanged) |
| 406 return PaintInvalidationLocationChange; | 406 return PaintInvalidationLocationChange; |
| 407 | 407 |
| 408 return PaintInvalidationIncremental; | 408 return PaintInvalidationIncremental; |
| 409 } | 409 } |
| 410 | 410 |
| 411 void ObjectPaintInvalidatorWithContext::invalidateSelectionIfNeeded(PaintInvalid
ationReason reason) | 411 void ObjectPaintInvalidatorWithContext::invalidateSelectionIfNeeded(PaintInvalid
ationReason reason) |
| 412 { | 412 { |
| 413 // Update selection rect when we are doing full invalidation (in case that t
he object is moved, | 413 // Update selection rect when we are doing full invalidation (in case that t
he object is moved, |
| 414 // composite status changed, etc.) or shouldInvalidationSelection is set (in
case that the | 414 // composite status changed, etc.) or shouldInvalidationSelection is set (in
case that the |
| 415 // selection itself changed). | 415 // selection itself changed). |
| 416 bool fullInvalidation = isImmediateFullPaintInvalidationReason(reason); | 416 bool fullInvalidation = isFullPaintInvalidationReason(reason); // isImmediat
eFullPaintInvalidationReason(reason); |
| 417 if (!fullInvalidation && !m_object.shouldInvalidateSelection()) | 417 if (!fullInvalidation && !m_object.shouldInvalidateSelection()) |
| 418 return; | 418 return; |
| 419 | 419 |
| 420 LayoutRect oldSelectionRect = selectionPaintInvalidationMap().get(&m_object)
; | 420 LayoutRect oldSelectionRect = selectionPaintInvalidationMap().get(&m_object)
; |
| 421 LayoutRect newSelectionRect = m_object.localSelectionRect(); | 421 LayoutRect newSelectionRect = m_object.localSelectionRect(); |
| 422 if (!newSelectionRect.isEmpty()) | 422 if (!newSelectionRect.isEmpty()) |
| 423 m_context.mapLocalRectToPaintInvalidationBacking(m_object, newSelectionR
ect); | 423 m_context.mapLocalRectToPaintInvalidationBacking(m_object, newSelectionR
ect); |
| 424 | 424 |
| 425 newSelectionRect.move(m_object.scrollAdjustmentForPaintInvalidation(*m_conte
xt.paintInvalidationContainer)); | 425 newSelectionRect.move(m_object.scrollAdjustmentForPaintInvalidation(*m_conte
xt.paintInvalidationContainer)); |
| 426 | 426 |
| 427 setPreviousSelectionPaintInvalidationRect(m_object, newSelectionRect); | 427 setPreviousSelectionPaintInvalidationRect(m_object, newSelectionRect); |
| 428 | 428 |
| 429 if (!fullInvalidation) { | 429 if (!fullInvalidation) { |
| 430 fullyInvalidatePaint(PaintInvalidationSelection, oldSelectionRect, newSe
lectionRect); | 430 fullyInvalidatePaint(PaintInvalidationSelection, oldSelectionRect, newSe
lectionRect); |
| 431 m_context.paintingLayer->setNeedsRepaint(); | 431 m_context.paintingLayer->setNeedsRepaint(); |
| 432 m_object.invalidateDisplayItemClients(PaintInvalidationSelection); | 432 m_object.invalidateDisplayItemClients(PaintInvalidationSelection); |
| 433 } | 433 } |
| 434 } | 434 } |
| 435 | 435 |
| 436 PaintInvalidationReason ObjectPaintInvalidatorWithContext::invalidatePaintIfNeed
edWithComputedReason(PaintInvalidationReason reason) | 436 PaintInvalidationReason ObjectPaintInvalidatorWithContext::invalidatePaintIfNeed
edWithComputedReason(PaintInvalidationReason reason) |
| 437 { | 437 { |
| 438 // We need to invalidate the selection before checking for whether we are do
ing a full invalidation. | 438 // We need to invalidate the selection before checking for whether we are do
ing a full invalidation. |
| 439 // This is because we need to update the previous selection rect regardless. | 439 // This is because we need to update the previous selection rect regardless. |
| 440 invalidateSelectionIfNeeded(reason); | 440 invalidateSelectionIfNeeded(reason); |
| 441 | 441 |
| 442 if (reason == PaintInvalidationIncremental && !incrementallyInvalidatePaint(
)) | 442 //if (reason == PaintInvalidationIncremental && !incrementallyInvalidatePain
t()) |
| 443 reason = PaintInvalidationNone; | 443 // reason = PaintInvalidationNone; |
| 444 | 444 |
| 445 switch (reason) { | 445 switch (reason) { |
| 446 case PaintInvalidationNone: | 446 case PaintInvalidationNone: |
| 447 // TODO(trchen): Currently we don't keep track of paint offset of layout
objects. | 447 // TODO(trchen): Currently we don't keep track of paint offset of layout
objects. |
| 448 // There are corner cases that the display items need to be invalidated
for paint offset | 448 // There are corner cases that the display items need to be invalidated
for paint offset |
| 449 // mutation, but incurs no pixel difference (i.e. bounds stay the same)
so no rect-based | 449 // mutation, but incurs no pixel difference (i.e. bounds stay the same)
so no rect-based |
| 450 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. | 450 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. |
| 451 // This is a workaround to force display items to update paint offset. | 451 // This is a workaround to force display items to update paint offset. |
| 452 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::
ForcedSubtreeInvalidationChecking) { | 452 if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::
ForcedSubtreeInvalidationChecking) { |
| 453 reason = PaintInvalidationLocationChange; | 453 reason = PaintInvalidationLocationChange; |
| 454 break; | 454 break; |
| 455 } | 455 } |
| 456 return PaintInvalidationNone; | 456 return PaintInvalidationNone; |
| 457 case PaintInvalidationIncremental: | 457 case PaintInvalidationIncremental: |
| 458 incrementallyInvalidatePaint(); |
| 458 break; | 459 break; |
| 459 case PaintInvalidationDelayedFull: | 460 case PaintInvalidationDelayedFull: |
| 460 return PaintInvalidationDelayedFull; | 461 return PaintInvalidationDelayedFull; |
| 461 default: | 462 default: |
| 462 DCHECK(isImmediateFullPaintInvalidationReason(reason)); | 463 DCHECK(isImmediateFullPaintInvalidationReason(reason)); |
| 463 fullyInvalidatePaint(reason, m_context.oldBounds, m_context.newBounds); | 464 fullyInvalidatePaint(reason, m_context.oldBounds, m_context.newBounds); |
| 464 } | 465 } |
| 465 | 466 |
| 466 m_context.paintingLayer->setNeedsRepaint(); | 467 m_context.paintingLayer->setNeedsRepaint(); |
| 467 m_object.invalidateDisplayItemClients(reason); | 468 m_object.invalidateDisplayItemClients(reason); |
| 468 return reason; | 469 return reason; |
| 469 } | 470 } |
| 470 | 471 |
| 471 DisablePaintInvalidationStateAsserts::DisablePaintInvalidationStateAsserts() | 472 DisablePaintInvalidationStateAsserts::DisablePaintInvalidationStateAsserts() |
| 472 : m_disabler(&gDisablePaintInvalidationStateAsserts, true) | 473 : m_disabler(&gDisablePaintInvalidationStateAsserts, true) |
| 473 { | 474 { |
| 474 } | 475 } |
| 475 | 476 |
| 476 } // namespace blink | 477 } // namespace blink |
| OLD | NEW |