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