| 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 "config.h" | 5 #include "config.h" |
| 6 #include "platform/graphics/paint/DisplayItemList.h" | 6 #include "platform/graphics/paint/DisplayItemList.h" |
| 7 | 7 |
| 8 #include "platform/NotImplemented.h" | 8 #include "platform/NotImplemented.h" |
| 9 #include "platform/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
| 10 #include "platform/TraceEvent.h" | 10 #include "platform/TraceEvent.h" |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con
st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems
& list) | 142 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con
st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems
& list) |
| 143 { | 143 { |
| 144 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(id.client); | 144 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(id.client); |
| 145 if (it == displayItemIndicesByClient.end()) | 145 if (it == displayItemIndicesByClient.end()) |
| 146 return kNotFound; | 146 return kNotFound; |
| 147 | 147 |
| 148 const Vector<size_t>& indices = it->value; | 148 const Vector<size_t>& indices = it->value; |
| 149 for (size_t index : indices) { | 149 for (size_t index : indices) { |
| 150 // TODO(pdr): elementAt is not cheap so this should be refactored (See c
rbug.com/505965). | 150 // TODO(pdr): elementAt is not cheap so this should be refactored (See c
rbug.com/505965). |
| 151 const DisplayItem& existingItem = list[index]; | 151 const DisplayItem& existingItem = list[index]; |
| 152 ASSERT(existingItem.ignoreFromDisplayList() || existingItem.client() ==
id.client); | 152 ASSERT(!existingItem.isValid() || existingItem.client() == id.client); |
| 153 if (!existingItem.ignoreFromDisplayList() && id.matches(existingItem)) | 153 if (existingItem.isValid() && id.matches(existingItem)) |
| 154 return index; | 154 return index; |
| 155 } | 155 } |
| 156 | 156 |
| 157 return kNotFound; | 157 return kNotFound; |
| 158 } | 158 } |
| 159 | 159 |
| 160 void DisplayItemList::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz
e_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient) | 160 void DisplayItemList::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz
e_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient) |
| 161 { | 161 { |
| 162 if (!displayItem.isCacheable()) | 162 if (!displayItem.isCacheable()) |
| 163 return; | 163 return; |
| 164 | 164 |
| 165 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find
(displayItem.client()); | 165 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find
(displayItem.client()); |
| 166 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? | 166 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? |
| 167 displayItemIndicesByClient.add(displayItem.client(), Vector<size_t>()).s
toredValue->value : it->value; | 167 displayItemIndicesByClient.add(displayItem.client(), Vector<size_t>()).s
toredValue->value : it->value; |
| 168 indices.append(index); | 168 indices.append(index); |
| 169 } | 169 } |
| 170 | 170 |
| 171 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::i
terator currentIt, const DisplayItem::Id& id, DisplayItemIndicesByClientMap& dis
playItemIndicesByClient) | 171 struct DisplayItemList::OutOfOrderIndexContext { |
| 172 OutOfOrderIndexContext(DisplayItems::iterator begin) : nextItemToIndex(begin
) { } |
| 173 |
| 174 DisplayItems::iterator nextItemToIndex; |
| 175 DisplayItemIndicesByClientMap displayItemIndicesByClient; |
| 176 }; |
| 177 |
| 178 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::i
terator currentIt, const DisplayItem::Id& id, OutOfOrderIndexContext& context) |
| 172 { | 179 { |
| 173 ASSERT(clientCacheIsValid(id.client)); | 180 ASSERT(clientCacheIsValid(id.client)); |
| 174 | 181 |
| 175 size_t foundIndex = findMatchingItemFromIndex(id, displayItemIndicesByClient
, m_currentDisplayItems); | 182 // Skip indexing of copied items. |
| 183 if (currentIt - context.nextItemToIndex > 0) |
| 184 context.nextItemToIndex = currentIt; |
| 185 |
| 186 size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndices
ByClient, m_currentDisplayItems); |
| 176 if (foundIndex != kNotFound) | 187 if (foundIndex != kNotFound) |
| 177 return m_currentDisplayItems.begin() + foundIndex; | 188 return m_currentDisplayItems.begin() + foundIndex; |
| 178 | 189 |
| 179 return findOutOfOrderCachedItemForward(currentIt, id, displayItemIndicesByCl
ient); | 190 return findOutOfOrderCachedItemForward(id, context); |
| 180 } | 191 } |
| 181 | 192 |
| 182 // Find forward for the item and index all skipped indexable items. | 193 // Find forward for the item and index all skipped indexable items. |
| 183 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(DisplayI
tems::iterator currentIt, const DisplayItem::Id& id, DisplayItemIndicesByClientM
ap& displayItemIndicesByClient) | 194 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(const Di
splayItem::Id& id, OutOfOrderIndexContext& context) |
| 184 { | 195 { |
| 185 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 196 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); |
| 186 for (; currentIt != currentEnd; ++currentIt) { | 197 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { |
| 187 const DisplayItem& item = *currentIt; | 198 const DisplayItem& item = *context.nextItemToIndex; |
| 188 if (!item.ignoreFromDisplayList() | 199 ASSERT(item.isValid()); |
| 189 && item.isCacheable() | 200 if (item.isCacheable() && clientCacheIsValid(item.client())) { |
| 190 && m_validlyCachedClients.contains(item.client())) { | |
| 191 if (id.matches(item)) | 201 if (id.matches(item)) |
| 192 return currentIt; | 202 return context.nextItemToIndex++; |
| 193 | 203 |
| 194 addItemToIndexIfNeeded(item, currentIt - m_currentDisplayItems.begin
(), displayItemIndicesByClient); | 204 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentDisp
layItems.begin(), context.displayItemIndicesByClient); |
| 195 } | 205 } |
| 196 } | 206 } |
| 197 return currentEnd; | 207 return currentEnd; |
| 198 } | 208 } |
| 199 | 209 |
| 200 void DisplayItemList::copyCachedSubtree(DisplayItems::iterator& currentIt, Displ
ayItems& updatedList) | 210 void DisplayItemList::copyCachedSubtree(DisplayItems::iterator& currentIt, Displ
ayItems& updatedList) |
| 201 { | 211 { |
| 202 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 212 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 203 ASSERT(currentIt->isBeginSubtree()); | 213 ASSERT(currentIt->isBeginSubtree()); |
| 204 ASSERT(!currentIt->scope()); | 214 ASSERT(!currentIt->scope()); |
| 205 DisplayItem::Id endSubtreeId(currentIt->client(), DisplayItem::beginSubtreeT
ypeToEndSubtreeType(currentIt->type()), 0); | 215 DisplayItem::Id endSubtreeId(currentIt->client(), DisplayItem::beginSubtreeT
ypeToEndSubtreeType(currentIt->type()), 0); |
| 206 while (true) { | 216 do { |
| 207 updatedList.appendByMoving(*currentIt, currentIt->derivedSize()); | |
| 208 if (endSubtreeId.matches(updatedList.last())) | |
| 209 break; | |
| 210 ++currentIt; | |
| 211 // We should always find the EndSubtree display item. | 217 // We should always find the EndSubtree display item. |
| 212 ASSERT(currentIt != m_currentDisplayItems.end()); | 218 ASSERT(currentIt != m_currentDisplayItems.end()); |
| 213 } | 219 updatedList.appendByMoving(*currentIt, currentIt->derivedSize()); |
| 220 ++currentIt; |
| 221 } while (!endSubtreeId.matches(updatedList.last())); |
| 214 } | 222 } |
| 215 | 223 |
| 216 // Update the existing display items by removing invalidated entries, updating | 224 // Update the existing display items by removing invalidated entries, updating |
| 217 // repainted ones, and appending new items. | 225 // repainted ones, and appending new items. |
| 218 // - For CachedDisplayItem, copy the corresponding cached DrawingDisplayItem; | 226 // - For CachedDisplayItem, copy the corresponding cached DrawingDisplayItem; |
| 219 // - For SubtreeCachedDisplayItem, copy the cached display items between the | 227 // - For SubtreeCachedDisplayItem, copy the cached display items between the |
| 220 // corresponding BeginSubtreeDisplayItem and EndSubtreeDisplayItem (incl.); | 228 // corresponding BeginSubtreeDisplayItem and EndSubtreeDisplayItem (incl.); |
| 221 // - Otherwise, copy the new display item. | 229 // - Otherwise, copy the new display item. |
| 222 // | 230 // |
| 223 // The algorithm is O(|m_currentDisplayItems| + |m_newDisplayItems|). | 231 // The algorithm is O(|m_currentDisplayItems| + |m_newDisplayItems|). |
| (...skipping 26 matching lines...) Expand all Loading... |
| 250 return; | 258 return; |
| 251 } | 259 } |
| 252 | 260 |
| 253 updateValidlyCachedClientsIfNeeded(); | 261 updateValidlyCachedClientsIfNeeded(); |
| 254 | 262 |
| 255 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched | 263 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched |
| 256 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched | 264 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched |
| 257 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when | 265 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when |
| 258 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems | 266 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems |
| 259 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. | 267 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. |
| 260 DisplayItemIndicesByClientMap displayItemIndicesByClient; | 268 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin())
; |
| 261 | 269 |
| 262 #if ENABLE(ASSERT) | 270 #if ENABLE(ASSERT) |
| 263 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ | 271 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ |
| 264 // Under-invalidation checking requires a full index of m_currentDisplay
Items. | 272 // Under-invalidation checking requires a full index of m_currentDisplay
Items. |
| 265 size_t i = 0; | 273 size_t i = 0; |
| 266 for (const auto& item : m_currentDisplayItems) { | 274 for (const auto& item : m_currentDisplayItems) { |
| 267 addItemToIndexIfNeeded(item, i, displayItemIndicesByClient); | 275 addItemToIndexIfNeeded(item, i, outOfOrderIndexContext.displayItemIn
dicesByClient); |
| 268 ++i; | 276 ++i; |
| 269 } | 277 } |
| 270 } | 278 } |
| 271 #endif // ENABLE(ASSERT) | 279 #endif // ENABLE(ASSERT) |
| 272 | 280 |
| 273 // TODO(jbroman): Consider revisiting this heuristic. | 281 // TODO(jbroman): Consider revisiting this heuristic. |
| 274 DisplayItems updatedList( | 282 DisplayItems updatedList( |
| 275 kMaximumDisplayItemSize, | 283 kMaximumDisplayItemSize, |
| 276 std::max(m_currentDisplayItems.usedCapacityInBytes(), m_newDisplayItems.
usedCapacityInBytes())); | 284 std::max(m_currentDisplayItems.usedCapacityInBytes(), m_newDisplayItems.
usedCapacityInBytes())); |
| 277 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); | 285 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); |
| 278 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 286 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); |
| 279 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { | 287 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { |
| 280 const DisplayItem& newDisplayItem = *newIt; | 288 const DisplayItem& newDisplayItem = *newIt; |
| 281 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 289 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
| 282 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; | 290 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; |
| 283 | 291 |
| 284 bool isSynchronized = currentIt != currentEnd | 292 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); |
| 285 && !currentIt->ignoreFromDisplayList() | |
| 286 && newDisplayItemId.matches(*currentIt); | |
| 287 | 293 |
| 288 if (newDisplayItemHasCachedType) { | 294 if (newDisplayItemHasCachedType) { |
| 289 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki
ngEnabled()); | 295 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki
ngEnabled()); |
| 290 ASSERT(newDisplayItem.isCached()); | 296 ASSERT(newDisplayItem.isCached()); |
| 291 ASSERT(clientCacheIsValid(newDisplayItem.client())); | 297 ASSERT(clientCacheIsValid(newDisplayItem.client())); |
| 292 if (!isSynchronized) { | 298 if (!isSynchronized) { |
| 293 DisplayItems::iterator foundIt = findOutOfOrderCachedItem(curren
tIt, newDisplayItemId, displayItemIndicesByClient); | 299 DisplayItems::iterator foundIt = findOutOfOrderCachedItem(curren
tIt, newDisplayItemId, outOfOrderIndexContext); |
| 294 ASSERT(foundIt != currentIt); | |
| 295 | 300 |
| 296 if (foundIt == currentEnd) { | 301 if (foundIt == currentEnd) { |
| 297 #ifndef NDEBUG | 302 #ifndef NDEBUG |
| 298 showDebugData(); | 303 showDebugData(); |
| 299 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD
isplayItem.asDebugString().utf8().data()); | 304 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD
isplayItem.asDebugString().utf8().data()); |
| 300 #endif | 305 #endif |
| 301 ASSERT_NOT_REACHED(); | 306 ASSERT_NOT_REACHED(); |
| 302 | 307 |
| 303 // If foundIt == currentEnd, it means that we did not find t
he cached display item. This should be impossible, but may occur | 308 // If foundIt == currentEnd, it means that we did not find t
he cached display item. This should be impossible, but may occur |
| 304 // if there is a bug in the system, such as under-invalidati
on, incorrect cache checking or duplicate display ids. In this case, | 309 // if there is a bug in the system, such as under-invalidati
on, incorrect cache checking or duplicate display ids. In this case, |
| 305 // attempt to recover rather than crashing or bailing on dis
play of the rest of the display list. | 310 // attempt to recover rather than crashing or bailing on dis
play of the rest of the display list. |
| 306 continue; | 311 continue; |
| 307 } | 312 } |
| 313 |
| 314 ASSERT(foundIt != currentIt); // because we are in 'if (!isSynch
ronized)' |
| 308 currentIt = foundIt; | 315 currentIt = foundIt; |
| 309 } | 316 } |
| 310 | 317 |
| 311 if (newDisplayItem.isCachedDrawing()) { | 318 if (newDisplayItem.isCachedDrawing()) { |
| 312 updatedList.appendByMoving(*currentIt, currentIt->derivedSize())
; | 319 updatedList.appendByMoving(*currentIt, currentIt->derivedSize())
; |
| 320 ++currentIt; |
| 313 } else { | 321 } else { |
| 314 ASSERT(newDisplayItem.isCachedSubtree()); | 322 ASSERT(newDisplayItem.isCachedSubtree()); |
| 315 copyCachedSubtree(currentIt, updatedList); | 323 copyCachedSubtree(currentIt, updatedList); |
| 316 ASSERT(updatedList.last().isEndSubtree()); | 324 ASSERT(updatedList.last().isEndSubtree()); |
| 317 } | 325 } |
| 318 } else { | 326 } else { |
| 319 #if ENABLE(ASSERT) | 327 #if ENABLE(ASSERT) |
| 320 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn
abled()) | 328 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn
abled()) |
| 321 checkCachedDisplayItemIsUnchanged(newDisplayItem, displayItemInd
icesByClient); | 329 checkCachedDisplayItemIsUnchanged(newDisplayItem, outOfOrderInde
xContext.displayItemIndicesByClient); |
| 322 else | 330 else |
| 323 ASSERT(!newDisplayItem.isDrawing() || newDisplayItem.skippedCach
e() || !clientCacheIsValid(newDisplayItem.client())); | 331 ASSERT(!newDisplayItem.isDrawing() || newDisplayItem.skippedCach
e() || !clientCacheIsValid(newDisplayItem.client())); |
| 324 #endif // ENABLE(ASSERT) | 332 #endif // ENABLE(ASSERT) |
| 325 updatedList.appendByMoving(*newIt, newIt->derivedSize()); | 333 updatedList.appendByMoving(*newIt, newIt->derivedSize()); |
| 334 |
| 335 if (isSynchronized) |
| 336 ++currentIt; |
| 326 } | 337 } |
| 327 | |
| 328 if (isSynchronized) | |
| 329 ++currentIt; | |
| 330 } | 338 } |
| 331 | 339 |
| 332 #if ENABLE(ASSERT) | 340 #if ENABLE(ASSERT) |
| 333 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 341 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
| 334 checkNoRemainingCachedDisplayItems(); | 342 checkNoRemainingCachedDisplayItems(); |
| 335 #endif // ENABLE(ASSERT) | 343 #endif // ENABLE(ASSERT) |
| 336 | 344 |
| 337 m_newDisplayItems.clear(); | 345 m_newDisplayItems.clear(); |
| 338 m_validlyCachedClientsDirty = true; | 346 m_validlyCachedClientsDirty = true; |
| 339 m_currentDisplayItems.swap(updatedList); | 347 m_currentDisplayItems.swap(updatedList); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 size_t index = findMatchingItemFromIndex(displayItem.nonCachedId(), displayI
temIndicesByClient, m_currentDisplayItems); | 441 size_t index = findMatchingItemFromIndex(displayItem.nonCachedId(), displayI
temIndicesByClient, m_currentDisplayItems); |
| 434 if (index == kNotFound) { | 442 if (index == kNotFound) { |
| 435 showUnderInvalidationError("ERROR: under-invalidation: no cached display
item", displayItem); | 443 showUnderInvalidationError("ERROR: under-invalidation: no cached display
item", displayItem); |
| 436 ASSERT_NOT_REACHED(); | 444 ASSERT_NOT_REACHED(); |
| 437 return; | 445 return; |
| 438 } | 446 } |
| 439 | 447 |
| 440 DisplayItems::iterator foundItem = m_currentDisplayItems.begin() + index; | 448 DisplayItems::iterator foundItem = m_currentDisplayItems.begin() + index; |
| 441 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>(
displayItem).picture(); | 449 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>(
displayItem).picture(); |
| 442 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(
*foundItem).picture(); | 450 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(
*foundItem).picture(); |
| 443 // Mark the display item as ignored so that we can check if there are any re
maining cached display items after merging. | 451 // Invalidate the display item so that we can check if there are any remaini
ng cached display items after merging. |
| 444 foundItem->setIgnoredFromDisplayList(); | 452 foundItem->clearClientForUnderInvalidationChecking(); |
| 445 | 453 |
| 446 if (!newPicture && !oldPicture) | 454 if (!newPicture && !oldPicture) |
| 447 return; | 455 return; |
| 448 if (newPicture && oldPicture) { | 456 if (newPicture && oldPicture) { |
| 449 switch (static_cast<const DrawingDisplayItem&>(displayItem).underInvalid
ationCheckingMode()) { | 457 switch (static_cast<const DrawingDisplayItem&>(displayItem).underInvalid
ationCheckingMode()) { |
| 450 case DrawingDisplayItem::CheckPicture: | 458 case DrawingDisplayItem::CheckPicture: |
| 451 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou
nt()) { | 459 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou
nt()) { |
| 452 SkDynamicMemoryWStream newPictureSerialized; | 460 SkDynamicMemoryWStream newPictureSerialized; |
| 453 newPicture->serialize(&newPictureSerialized); | 461 newPicture->serialize(&newPictureSerialized); |
| 454 SkDynamicMemoryWStream oldPictureSerialized; | 462 SkDynamicMemoryWStream oldPictureSerialized; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 #endif // NDEBUG | 498 #endif // NDEBUG |
| 491 | 499 |
| 492 ASSERT_NOT_REACHED(); | 500 ASSERT_NOT_REACHED(); |
| 493 } | 501 } |
| 494 | 502 |
| 495 void DisplayItemList::checkNoRemainingCachedDisplayItems() | 503 void DisplayItemList::checkNoRemainingCachedDisplayItems() |
| 496 { | 504 { |
| 497 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); | 505 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); |
| 498 | 506 |
| 499 for (const auto& displayItem : m_currentDisplayItems) { | 507 for (const auto& displayItem : m_currentDisplayItems) { |
| 500 if (displayItem.ignoreFromDisplayList() || !displayItem.isDrawing() || !
clientCacheIsValid(displayItem.client())) | 508 if (!displayItem.isValid() || !displayItem.isDrawing() || !clientCacheIs
Valid(displayItem.client())) |
| 501 continue; | 509 continue; |
| 502 showUnderInvalidationError("May be under-invalidation: no new display it
em", displayItem); | 510 showUnderInvalidationError("May be under-invalidation: no new display it
em", displayItem); |
| 503 } | 511 } |
| 504 } | 512 } |
| 505 | 513 |
| 506 #endif // ENABLE(ASSERT) | 514 #endif // ENABLE(ASSERT) |
| 507 | 515 |
| 508 #ifndef NDEBUG | 516 #ifndef NDEBUG |
| 509 | 517 |
| 510 WTF::String DisplayItemList::displayItemsAsDebugString(const DisplayItems& list)
const | 518 WTF::String DisplayItemList::displayItemsAsDebugString(const DisplayItems& list)
const |
| 511 { | 519 { |
| 512 StringBuilder stringBuilder; | 520 StringBuilder stringBuilder; |
| 513 size_t i = 0; | 521 size_t i = 0; |
| 514 for (auto it = list.begin(); it != list.end(); ++it, ++i) { | 522 for (auto it = list.begin(); it != list.end(); ++it, ++i) { |
| 515 const DisplayItem& displayItem = *it; | 523 const DisplayItem& displayItem = *it; |
| 516 if (i) | 524 if (i) |
| 517 stringBuilder.append(",\n"); | 525 stringBuilder.append(",\n"); |
| 518 if (displayItem.ignoreFromDisplayList()) { | 526 if (!displayItem.isValid()) { |
| 519 stringBuilder.append("null"); | 527 stringBuilder.append("null"); |
| 520 continue; | 528 continue; |
| 521 } | 529 } |
| 522 stringBuilder.append(String::format("{index: %d, ", (int)i)); | 530 stringBuilder.append(String::format("{index: %d, ", (int)i)); |
| 523 displayItem.dumpPropertiesAsDebugString(stringBuilder); | 531 displayItem.dumpPropertiesAsDebugString(stringBuilder); |
| 524 stringBuilder.append(", cacheIsValid: "); | 532 stringBuilder.append(", cacheIsValid: "); |
| 525 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" :
"false"); | 533 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" :
"false"); |
| 526 stringBuilder.append('}'); | 534 stringBuilder.append('}'); |
| 527 } | 535 } |
| 528 return stringBuilder.toString(); | 536 return stringBuilder.toString(); |
| 529 } | 537 } |
| 530 | 538 |
| 531 void DisplayItemList::showDebugData() const | 539 void DisplayItemList::showDebugData() const |
| 532 { | 540 { |
| 533 WTFLogAlways("current display items: [%s]\n", displayItemsAsDebugString(m_cu
rrentDisplayItems).utf8().data()); | 541 WTFLogAlways("current display items: [%s]\n", displayItemsAsDebugString(m_cu
rrentDisplayItems).utf8().data()); |
| 534 WTFLogAlways("new display items: [%s]\n", displayItemsAsDebugString(m_newDis
playItems).utf8().data()); | 542 WTFLogAlways("new display items: [%s]\n", displayItemsAsDebugString(m_newDis
playItems).utf8().data()); |
| 535 } | 543 } |
| 536 | 544 |
| 537 #endif // ifndef NDEBUG | 545 #endif // ifndef NDEBUG |
| 538 | 546 |
| 539 void DisplayItemList::replay(GraphicsContext& context) | 547 void DisplayItemList::replay(GraphicsContext& context) |
| 540 { | 548 { |
| 541 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 549 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
| 542 ASSERT(m_newDisplayItems.isEmpty()); | 550 ASSERT(m_newDisplayItems.isEmpty()); |
| 543 for (DisplayItem& displayItem : m_currentDisplayItems) | 551 for (DisplayItem& displayItem : m_currentDisplayItems) |
| 544 displayItem.replay(context); | 552 displayItem.replay(context); |
| 545 } | 553 } |
| 546 | 554 |
| 547 } // namespace blink | 555 } // namespace blink |
| OLD | NEW |