| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "platform/graphics/paint/PaintController.h" | 5 #include "platform/graphics/paint/PaintController.h" |
| 6 | 6 |
| 7 #include "platform/TraceEvent.h" | 7 #include "platform/TraceEvent.h" |
| 8 #include "platform/graphics/GraphicsLayer.h" | 8 #include "platform/graphics/GraphicsLayer.h" |
| 9 #include "platform/graphics/paint/DrawingDisplayItem.h" | 9 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 10 #include "third_party/skia/include/core/SkPictureAnalyzer.h" | 10 #include "third_party/skia/include/core/SkPictureAnalyzer.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client
, DisplayItem::Type type) | 34 bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client
, DisplayItem::Type type) |
| 35 { | 35 { |
| 36 DCHECK(DisplayItem::isDrawingType(type)); | 36 DCHECK(DisplayItem::isDrawingType(type)); |
| 37 | 37 |
| 38 if (displayItemConstructionIsDisabled()) | 38 if (displayItemConstructionIsDisabled()) |
| 39 return false; | 39 return false; |
| 40 | 40 |
| 41 if (!clientCacheIsValid(client)) | 41 if (!clientCacheIsValid(client)) |
| 42 return false; | 42 return false; |
| 43 | 43 |
| 44 #if ENABLE(ASSERT) | 44 #if DCHECK_IS_ON() |
| 45 // When under-invalidation checking is enabled, we output CachedDrawing disp
lay item | 45 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
&& isCheckingUnderInvalidation()) { |
| 46 // followed by the display item containing forced painting. | 46 // We are checking under-invalidation of a subsequence enclosing this di
splay item. |
| 47 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 47 // Let the client continue to actually paint the display item. |
| 48 return false; | 48 return false; |
| 49 } |
| 49 #endif | 50 #endif |
| 50 | 51 |
| 51 DisplayItemList::iterator cachedItem = findCachedItem(DisplayItem::Id(client
, type)); | 52 DisplayItemList::iterator cachedItem = findCachedItem(DisplayItem::Id(client
, type)); |
| 52 if (cachedItem == m_currentPaintArtifact.getDisplayItemList().end()) { | 53 if (cachedItem == m_currentPaintArtifact.getDisplayItemList().end()) { |
| 53 NOTREACHED(); | 54 NOTREACHED(); |
| 54 return false; | 55 return false; |
| 55 } | 56 } |
| 56 | 57 |
| 57 ++m_numCachedNewItems; | 58 ++m_numCachedNewItems; |
| 58 ensureNewDisplayItemListInitialCapacity(); | 59 ensureNewDisplayItemListInitialCapacity(); |
| 59 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem)); | 60 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidati
onCheckingEnabled()) |
| 61 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem)); |
| 60 | 62 |
| 61 m_nextItemToMatch = cachedItem + 1; | 63 m_nextItemToMatch = cachedItem + 1; |
| 62 // Items before m_nextItemToMatch have been copied so we don't need to index
them. | 64 // Items before m_nextItemToMatch have been copied so we don't need to index
them. |
| 63 if (m_nextItemToMatch - m_nextItemToIndex > 0) | 65 if (m_nextItemToMatch - m_nextItemToIndex > 0) |
| 64 m_nextItemToIndex = m_nextItemToMatch; | 66 m_nextItemToIndex = m_nextItemToMatch; |
| 65 | 67 |
| 68 #if DCHECK_IS_ON() |
| 69 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ |
| 70 if (!isCheckingUnderInvalidation()) { |
| 71 m_underInvalidationCheckingBegin = cachedItem; |
| 72 m_underInvalidationCheckingEnd = cachedItem + 1; |
| 73 m_underInvalidationMessagePrefix = ""; |
| 74 } |
| 75 // Return false to let the painter actually paint, and we will check if
the new painting |
| 76 // is the same as the cached. |
| 77 return false; |
| 78 } |
| 79 #endif |
| 80 |
| 66 return true; | 81 return true; |
| 67 } | 82 } |
| 68 | 83 |
| 69 bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl
ient) | 84 bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl
ient) |
| 70 { | 85 { |
| 71 // TODO(crbug.com/596983): Implement subsequence caching for spv2. | 86 // TODO(crbug.com/596983): Implement subsequence caching for spv2. |
| 72 // The problem is in copyCachedSubsequence() which fails to handle PaintChun
kProperties | 87 // The problem is in copyCachedSubsequence() which fails to handle PaintChun
kProperties |
| 73 // of chunks containing cached display items. We need to find the previous | 88 // of chunks containing cached display items. We need to find the previous |
| 74 // PaintChunkProperties and ensure they are valid in the current paint prope
rty tree. | 89 // PaintChunkProperties and ensure they are valid in the current paint prope
rty tree. |
| 75 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 90 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 76 return false; | 91 return false; |
| 77 | 92 |
| 78 if (displayItemConstructionIsDisabled() || subsequenceCachingIsDisabled()) | 93 if (displayItemConstructionIsDisabled() || subsequenceCachingIsDisabled()) |
| 79 return false; | 94 return false; |
| 80 | 95 |
| 81 if (!clientCacheIsValid(client)) | 96 if (!clientCacheIsValid(client)) |
| 82 return false; | 97 return false; |
| 83 | 98 |
| 84 #if ENABLE(ASSERT) | 99 #if DCHECK_IS_ON() |
| 85 // When under-invalidation checking is enabled, we output CachedDrawing disp
lay item | 100 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
&& isCheckingUnderInvalidation()) { |
| 86 // followed by the display item containing forced painting. | 101 // We are checking under-invalidation of an ancestor subsequence enclosi
ng this one. |
| 87 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 102 // The ancestor subsequence is supposed to have already "copied", so we
should let the |
| 103 // client continue to actually paint the descendant subsequences without
"copying". |
| 88 return false; | 104 return false; |
| 105 } |
| 89 #endif | 106 #endif |
| 90 | 107 |
| 91 DisplayItemList::iterator cachedItem = findCachedItem(DisplayItem::Id(client
, DisplayItem::Subsequence)); | 108 DisplayItemList::iterator cachedItem = findCachedItem(DisplayItem::Id(client
, DisplayItem::Subsequence)); |
| 92 if (cachedItem == m_currentPaintArtifact.getDisplayItemList().end()) { | 109 if (cachedItem == m_currentPaintArtifact.getDisplayItemList().end()) { |
| 93 NOTREACHED(); | 110 NOTREACHED(); |
| 94 return false; | 111 return false; |
| 95 } | 112 } |
| 96 | 113 |
| 97 // |cachedItem| will point to the first item after the subsequence or end of
the current list. | 114 // |cachedItem| will point to the first item after the subsequence or end of
the current list. |
| 98 ensureNewDisplayItemListInitialCapacity(); | 115 ensureNewDisplayItemListInitialCapacity(); |
| 99 copyCachedSubsequence(cachedItem); | 116 copyCachedSubsequence(cachedItem); |
| 100 | 117 |
| 101 m_nextItemToMatch = cachedItem; | 118 m_nextItemToMatch = cachedItem; |
| 102 // Items before |cachedItem| have been copied so we don't need to index them
. | 119 // Items before |cachedItem| have been copied so we don't need to index them
. |
| 103 if (cachedItem - m_nextItemToIndex > 0) | 120 if (cachedItem - m_nextItemToIndex > 0) |
| 104 m_nextItemToIndex = cachedItem; | 121 m_nextItemToIndex = cachedItem; |
| 105 | 122 |
| 123 #if DCHECK_IS_ON() |
| 124 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ |
| 125 // Return false to let the painter actually paint, and we will check if
the new painting |
| 126 // is the same as the cached. |
| 127 return false; |
| 128 } |
| 129 #endif |
| 130 |
| 106 return true; | 131 return true; |
| 107 } | 132 } |
| 108 | 133 |
| 109 bool PaintController::lastDisplayItemIsNoopBegin() const | 134 bool PaintController::lastDisplayItemIsNoopBegin() const |
| 110 { | 135 { |
| 111 if (m_newDisplayItemList.isEmpty()) | 136 if (m_newDisplayItemList.isEmpty()) |
| 112 return false; | 137 return false; |
| 113 | 138 |
| 114 const auto& lastDisplayItem = m_newDisplayItemList.last(); | 139 const auto& lastDisplayItem = m_newDisplayItemList.last(); |
| 115 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); | 140 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt
emIndicesByClient, m_newDisplayItemList); | 203 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt
emIndicesByClient, m_newDisplayItemList); |
| 179 if (index != kNotFound) { | 204 if (index != kNotFound) { |
| 180 #ifndef NDEBUG | 205 #ifndef NDEBUG |
| 181 showDebugData(); | 206 showDebugData(); |
| 182 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", | 207 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", |
| 183 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde
x].asDebugString().utf8().data(), static_cast<int>(index)); | 208 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde
x].asDebugString().utf8().data(), static_cast<int>(index)); |
| 184 #endif | 209 #endif |
| 185 NOTREACHED(); | 210 NOTREACHED(); |
| 186 } | 211 } |
| 187 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi
splayItemIndicesByClient); | 212 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi
splayItemIndicesByClient); |
| 213 |
| 214 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
| 215 checkUnderInvalidation(); |
| 188 #endif // DCHECK_IS_ON() | 216 #endif // DCHECK_IS_ON() |
| 189 | 217 |
| 190 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 218 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 191 m_newPaintChunks.incrementDisplayItemIndex(behaviorOfItemType(displayIte
m.getType())); | 219 m_newPaintChunks.incrementDisplayItemIndex(behaviorOfItemType(displayIte
m.getType())); |
| 192 } | 220 } |
| 193 | 221 |
| 194 void PaintController::updateCurrentPaintChunkProperties(const PaintChunkProperti
es& newProperties) | 222 void PaintController::updateCurrentPaintChunkProperties(const PaintChunkProperti
es& newProperties) |
| 195 { | 223 { |
| 196 m_newPaintChunks.updateCurrentPaintChunkProperties(newProperties); | 224 m_newPaintChunks.updateCurrentPaintChunkProperties(newProperties); |
| 197 } | 225 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 showDebugData(); | 334 showDebugData(); |
| 307 LOG(ERROR) << id.client.debugName() << ":" << DisplayItem::typeAsDebugString
(id.type) << " not found in current display item list"; | 335 LOG(ERROR) << id.client.debugName() << ":" << DisplayItem::typeAsDebugString
(id.type) << " not found in current display item list"; |
| 308 #endif | 336 #endif |
| 309 NOTREACHED(); | 337 NOTREACHED(); |
| 310 // We did not find the cached display item. This should be impossible, but m
ay occur if there is a bug | 338 // We did not find the cached display item. This should be impossible, but m
ay occur if there is a bug |
| 311 // in the system, such as under-invalidation, incorrect cache checking or du
plicate display ids. | 339 // in the system, such as under-invalidation, incorrect cache checking or du
plicate display ids. |
| 312 // In this case, the caller should fall back to repaint the display item. | 340 // In this case, the caller should fall back to repaint the display item. |
| 313 return end; | 341 return end; |
| 314 } | 342 } |
| 315 | 343 |
| 344 // Copies a cached subsequence from current list to the new list. |
| 316 // On return, |it| points to the item after the EndSubsequence item of the subse
quence. | 345 // On return, |it| points to the item after the EndSubsequence item of the subse
quence. |
| 346 // When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subs
equence, |
| 347 // but mark the begin and end of the subsequence for under-invalidation checking
. |
| 317 void PaintController::copyCachedSubsequence(DisplayItemList::iterator& it) | 348 void PaintController::copyCachedSubsequence(DisplayItemList::iterator& it) |
| 318 { | 349 { |
| 350 #if DCHECK_IS_ON() |
| 319 DCHECK(it->getType() == DisplayItem::Subsequence); | 351 DCHECK(it->getType() == DisplayItem::Subsequence); |
| 352 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ |
| 353 DCHECK(!isCheckingUnderInvalidation()); |
| 354 m_underInvalidationCheckingBegin = it; |
| 355 #ifndef NDEBUG |
| 356 m_underInvalidationMessagePrefix = "(In CachedSubsequence of " + it->cli
entDebugString() + ")"; |
| 357 #else |
| 358 m_underInvalidationMessagePrefix = "(In CachedSubsequence)"; |
| 359 #endif |
| 360 } |
| 361 #endif |
| 362 |
| 320 DisplayItem::Id endSubsequenceId(it->client(), DisplayItem::EndSubsequence); | 363 DisplayItem::Id endSubsequenceId(it->client(), DisplayItem::EndSubsequence); |
| 364 bool metEndSubsequence = false; |
| 321 do { | 365 do { |
| 322 // We should always find the EndSubsequence display item. | 366 // We should always find the EndSubsequence display item. |
| 323 DCHECK(it != m_currentPaintArtifact.getDisplayItemList().end()); | 367 DCHECK(it != m_currentPaintArtifact.getDisplayItemList().end()); |
| 324 DCHECK(it->hasValidClient()); | 368 DCHECK(it->hasValidClient()); |
| 325 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 369 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
| 326 CHECK(it->client().isAlive()); | 370 CHECK(it->client().isAlive()); |
| 327 #endif | 371 #endif |
| 328 ++m_numCachedNewItems; | 372 ++m_numCachedNewItems; |
| 329 processNewItem(m_newDisplayItemList.appendByMoving(*it)); | 373 if (it->getId() == endSubsequenceId) |
| 374 metEndSubsequence = true; |
| 375 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali
dationCheckingEnabled()) |
| 376 processNewItem(m_newDisplayItemList.appendByMoving(*it)); |
| 330 ++it; | 377 ++it; |
| 331 } while (endSubsequenceId != m_newDisplayItemList.last().getId()); | 378 } while (!metEndSubsequence); |
| 379 |
| 380 #if DCHECK_IS_ON() |
| 381 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ |
| 382 m_underInvalidationCheckingEnd = it; |
| 383 DCHECK(isCheckingUnderInvalidation()); |
| 384 } |
| 385 #endif |
| 332 } | 386 } |
| 333 | 387 |
| 334 static IntRect visualRectForDisplayItem(const DisplayItem& displayItem, const La
youtSize& offsetFromLayoutObject) | 388 static IntRect visualRectForDisplayItem(const DisplayItem& displayItem, const La
youtSize& offsetFromLayoutObject) |
| 335 { | 389 { |
| 336 LayoutRect visualRect = displayItem.client().visualRect(); | 390 LayoutRect visualRect = displayItem.client().visualRect(); |
| 337 visualRect.move(-offsetFromLayoutObject); | 391 visualRect.move(-offsetFromLayoutObject); |
| 338 return enclosingIntRect(visualRect); | 392 return enclosingIntRect(visualRect); |
| 339 } | 393 } |
| 340 | 394 |
| 341 void PaintController::resetCurrentListIterators() | 395 void PaintController::resetCurrentListIterators() |
| 342 { | 396 { |
| 343 m_nextItemToMatch = m_currentPaintArtifact.getDisplayItemList().begin(); | 397 m_nextItemToMatch = m_currentPaintArtifact.getDisplayItemList().begin(); |
| 344 m_nextItemToIndex = m_nextItemToMatch; | 398 m_nextItemToIndex = m_nextItemToMatch; |
| 399 #if DCHECK_IS_ON() |
| 400 m_underInvalidationCheckingBegin = m_currentPaintArtifact.getDisplayItemList
().end(); |
| 401 m_underInvalidationCheckingEnd = m_currentPaintArtifact.getDisplayItemList()
.begin(); |
| 402 #endif |
| 345 } | 403 } |
| 346 | 404 |
| 347 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb
ject) | 405 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb
ject) |
| 348 { | 406 { |
| 349 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", | 407 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", |
| 350 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL
ist().size(), | 408 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL
ist().size(), |
| 351 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach
edNewItems); | 409 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach
edNewItems); |
| 352 m_numCachedNewItems = 0; | 410 m_numCachedNewItems = 0; |
| 353 | 411 |
| 354 // These data structures are used during painting only. | 412 // These data structures are used during painting only. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 { | 479 { |
| 422 DCHECK(m_newDisplayItemList.isEmpty()); | 480 DCHECK(m_newDisplayItemList.isEmpty()); |
| 423 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList(
).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::Debug
Drawing, picture); | 481 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList(
).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::Debug
Drawing, picture); |
| 424 displayItem.setSkippedCache(); | 482 displayItem.setSkippedCache(); |
| 425 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi
splayItem(displayItem, offsetFromLayoutObject)); | 483 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi
splayItem(displayItem, offsetFromLayoutObject)); |
| 426 | 484 |
| 427 // Need to reset the iterators after mutation of the DisplayItemList. | 485 // Need to reset the iterators after mutation of the DisplayItemList. |
| 428 resetCurrentListIterators(); | 486 resetCurrentListIterators(); |
| 429 } | 487 } |
| 430 | 488 |
| 431 #if 0 // DCHECK_IS_ON() | 489 #if DCHECK_IS_ON() |
| 432 // TODO(wangxianzhu): Fix under-invalidation checking for the new caching method
. | |
| 433 | 490 |
| 434 void PaintController::checkUnderInvalidation(DisplayItemList::iterator& newIt, D
isplayItemList::iterator& currentIt) | 491 void PaintController::showUnderInvalidationError(const char* reason, const Displ
ayItem& newItem, const DisplayItem& oldItem) const |
| 435 { | 492 { |
| 436 DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); | 493 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; |
| 437 | |
| 438 // When under-invalidation-checking is enabled, the forced painting is follo
wing the cached display item. | |
| 439 DisplayItem::Type nextItemType = DisplayItem::nonCachedType(newIt->getType()
); | |
| 440 ++newIt; | |
| 441 DCHECK(newIt->getType() == nextItemType); | |
| 442 | |
| 443 if (newIt->isDrawing()) { | |
| 444 checkCachedDisplayItemIsUnchanged("", *newIt, *currentIt); | |
| 445 return; | |
| 446 } | |
| 447 | |
| 448 DCHECK(newIt->getType() == DisplayItem::Subsequence); | |
| 449 | |
| 450 #ifndef NDEBUG | 494 #ifndef NDEBUG |
| 451 CString messagePrefix = String::format("(In CachedSubsequence of %s)", newIt
->clientDebugString().utf8().data()).utf8(); | 495 LOG(ERROR) << "New display item: " << newItem.asDebugString(); |
| 496 LOG(ERROR) << "Old display item: " << oldItem.asDebugString(); |
| 452 #else | 497 #else |
| 453 CString messagePrefix = "(In CachedSubsequence)"; | 498 LOG(ERROR) << "Run debug build to get more details."; |
| 454 #endif | 499 #endif |
| 455 | 500 LOG(ERROR) << "See http://crbug.com/619103."; |
| 456 DisplayItem::Id endSubsequenceId(newIt->client(), DisplayItem::EndSubsequenc
e); | |
| 457 while (true) { | |
| 458 DCHECK(newIt != m_newDisplayItemList.end()); | |
| 459 if (newIt->isCached()) | |
| 460 checkUnderInvalidation(newIt, currentIt); | |
| 461 else | |
| 462 checkCachedDisplayItemIsUnchanged(messagePrefix.data(), *newIt, *cur
rentIt); | |
| 463 | |
| 464 if (endSubsequenceId.matches(*newIt)) | |
| 465 break; | |
| 466 | |
| 467 ++newIt; | |
| 468 ++currentIt; | |
| 469 } | |
| 470 } | |
| 471 | |
| 472 static void showUnderInvalidationError(const char* messagePrefix, const char* re
ason, const DisplayItem* newItem, const DisplayItem* oldItem) | |
| 473 { | |
| 474 #ifndef NDEBUG | |
| 475 WTFLogAlways("%s %s:\nNew display item: %s\nOld display item: %s\nSee http:/
/crbug.com/450725.", messagePrefix, reason, | |
| 476 newItem ? newItem->asDebugString().utf8().data() : "None", | |
| 477 oldItem ? oldItem->asDebugString().utf8().data() : "None"); | |
| 478 #else | |
| 479 WTFLogAlways("%s %s. Run debug build to get more details\nSee http://crbug.c
om/450725.", messagePrefix, reason); | |
| 480 #endif // NDEBUG | |
| 481 } | |
| 482 | |
| 483 void PaintController::checkCachedDisplayItemIsUnchanged(const char* messagePrefi
x, const DisplayItem& newItem, const DisplayItem& oldItem) | |
| 484 { | |
| 485 DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); | |
| 486 DCHECK(!newItem.isCached()); | |
| 487 DCHECK(!oldItem.isCached()); | |
| 488 | |
| 489 if (newItem.skippedCache()) { | |
| 490 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: sk
ipped-cache in cached subsequence", &newItem, &oldItem); | |
| 491 NOTREACHED(); | |
| 492 } | |
| 493 | |
| 494 if (newItem.isCacheable() && !clientCacheIsValid(newItem.client())) { | |
| 495 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: in
validated in cached subsequence", &newItem, &oldItem); | |
| 496 NOTREACHED(); | |
| 497 } | |
| 498 | |
| 499 if (newItem.equals(oldItem)) | |
| 500 return; | |
| 501 | |
| 502 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: displa
y item changed", &newItem, &oldItem); | |
| 503 | 501 |
| 504 #ifndef NDEBUG | 502 #ifndef NDEBUG |
| 505 if (newItem.isDrawing()) { | 503 if (newItem.isDrawing()) { |
| 506 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayIte
m&>(newItem).picture(); | 504 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayIte
m&>(newItem).picture(); |
| 507 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayIte
m&>(oldItem).picture(); | 505 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayIte
m&>(oldItem).picture(); |
| 508 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPict
ure.get()) : "None"; | 506 LOG(INFO) << "new picture:\n" << (newPicture ? pictureAsDebugString(newP
icture.get()) : "None"); |
| 509 String newPictureDebugString = newPicture ? pictureAsDebugString(newPict
ure.get()) : "None"; | 507 LOG(INFO) << "old picture:\n" << (oldPicture ? pictureAsDebugString(oldP
icture.get()) : "None"); |
| 510 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data()); | |
| 511 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); | |
| 512 } | 508 } |
| 513 #endif // NDEBUG | 509 #endif // NDEBUG |
| 510 } |
| 514 | 511 |
| 515 NOTREACHED(); | 512 void PaintController::checkUnderInvalidation() |
| 513 { |
| 514 DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); |
| 515 |
| 516 if (!isCheckingUnderInvalidation()) |
| 517 return; |
| 518 |
| 519 const DisplayItem& newItem = m_newDisplayItemList.last(); |
| 520 const DisplayItem& oldItem = *m_underInvalidationCheckingBegin++; |
| 521 |
| 522 if (newItem.isCacheable() && !clientCacheIsValid(newItem.client())) { |
| 523 showUnderInvalidationError("under-invalidation of PaintLayer: invalidate
d in cached subsequence", newItem, oldItem); |
| 524 NOTREACHED(); |
| 525 } |
| 526 if (!newItem.equals(oldItem)) { |
| 527 showUnderInvalidationError("under-invalidation: display item changed", n
ewItem, oldItem); |
| 528 NOTREACHED(); |
| 529 } |
| 516 } | 530 } |
| 517 | 531 |
| 518 #endif // DCHECK_IS_ON() | 532 #endif // DCHECK_IS_ON() |
| 519 | 533 |
| 520 #ifndef NDEBUG | 534 #ifndef NDEBUG |
| 521 | 535 |
| 522 String PaintController::displayItemListAsDebugString(const DisplayItemList& list
) const | 536 String PaintController::displayItemListAsDebugString(const DisplayItemList& list
) const |
| 523 { | 537 { |
| 524 StringBuilder stringBuilder; | 538 StringBuilder stringBuilder; |
| 525 size_t i = 0; | 539 size_t i = 0; |
| 526 for (auto it = list.begin(); it != list.end(); ++it, ++i) { | 540 for (auto it = list.begin(); it != list.end(); ++it, ++i) { |
| 527 const DisplayItem& displayItem = *it; | 541 const DisplayItem& displayItem = *it; |
| 528 if (i) | 542 if (i) |
| 529 stringBuilder.append(",\n"); | 543 stringBuilder.append(",\n"); |
| 530 stringBuilder.append(String::format("{index: %d, ", (int)i)); | 544 stringBuilder.append(String::format("{index: %d, ", (int)i)); |
| 531 displayItem.dumpPropertiesAsDebugString(stringBuilder); | 545 displayItem.dumpPropertiesAsDebugString(stringBuilder); |
| 532 if (displayItem.hasValidClient()) { | 546 if (displayItem.hasValidClient()) { |
| 533 stringBuilder.append(", cacheIsValid: "); | 547 stringBuilder.append(", cacheIsValid: "); |
| 534 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "tru
e" : "false"); | 548 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "tru
e" : "false"); |
| 535 } | 549 } |
| 536 IntRect visualRect = list.visualRect(i); | 550 if (list.hasVisualRect(i)) { |
| 537 stringBuilder.append(String::format(", visualRect: [%d,%d %dx%d]", | 551 IntRect visualRect = list.visualRect(i); |
| 538 visualRect.x(), visualRect.y(), | 552 stringBuilder.append(String::format(", visualRect: [%d,%d %dx%d]", |
| 539 visualRect.width(), visualRect.height())); | 553 visualRect.x(), visualRect.y(), |
| 554 visualRect.width(), visualRect.height())); |
| 555 } |
| 540 stringBuilder.append('}'); | 556 stringBuilder.append('}'); |
| 541 } | 557 } |
| 542 return stringBuilder.toString(); | 558 return stringBuilder.toString(); |
| 543 } | 559 } |
| 544 | 560 |
| 545 void PaintController::showDebugData() const | 561 void PaintController::showDebugData() const |
| 546 { | 562 { |
| 547 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); | 563 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); |
| 548 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); | 564 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); |
| 549 } | 565 } |
| 550 | 566 |
| 551 #endif // ifndef NDEBUG | 567 #endif // ifndef NDEBUG |
| 552 | 568 |
| 553 } // namespace blink | 569 } // namespace blink |
| OLD | NEW |