| 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 18 matching lines...) Expand all Loading... |
| 29 { | 29 { |
| 30 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 30 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
| 31 ASSERT(m_newDisplayItems.isEmpty()); | 31 ASSERT(m_newDisplayItems.isEmpty()); |
| 32 return m_currentDisplayItems; | 32 return m_currentDisplayItems; |
| 33 } | 33 } |
| 34 | 34 |
| 35 void DisplayItemList::add(WTF::PassOwnPtr<DisplayItem> displayItem) | 35 void DisplayItemList::add(WTF::PassOwnPtr<DisplayItem> displayItem) |
| 36 { | 36 { |
| 37 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 37 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
| 38 ASSERT(!m_constructionDisabled); | 38 ASSERT(!m_constructionDisabled); |
| 39 ASSERT(!skippingCache() || !displayItem->isCached()); |
| 39 | 40 |
| 40 if (displayItem->isEnd()) { | 41 if (displayItem->isEnd()) { |
| 41 ASSERT(!m_newDisplayItems.isEmpty()); | 42 ASSERT(!m_newDisplayItems.isEmpty()); |
| 42 if (m_newDisplayItems.last()->isBegin() && !m_newDisplayItems.last()->dr
awsContent()) { | 43 if (m_newDisplayItems.last()->isBegin() && !m_newDisplayItems.last()->dr
awsContent()) { |
| 43 ASSERT(displayItem->isEndAndPairedWith(*m_newDisplayItems.last())); | 44 ASSERT(displayItem->isEndAndPairedWith(*m_newDisplayItems.last())); |
| 44 // Remove the beginning display item of this empty pair. | 45 // Remove the beginning display item of this empty pair. |
| 45 m_newDisplayItems.removeLast(); | 46 m_newDisplayItems.removeLast(); |
| 46 #if ENABLE(ASSERT) | 47 #if ENABLE(ASSERT) |
| 47 // Also remove the index pointing to the removed display item. | 48 // Also remove the index pointing to the removed display item. |
| 48 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndices
ByClient.find(displayItem->client()); | 49 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndices
ByClient.find(displayItem->client()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 63 size_t index = findMatchingItemFromIndex(*displayItem, displayItem->type(),
m_newDisplayItemIndicesByClient, m_newDisplayItems); | 64 size_t index = findMatchingItemFromIndex(*displayItem, displayItem->type(),
m_newDisplayItemIndicesByClient, m_newDisplayItems); |
| 64 if (index != kNotFound) { | 65 if (index != kNotFound) { |
| 65 #ifndef NDEBUG | 66 #ifndef NDEBUG |
| 66 showDebugData(); | 67 showDebugData(); |
| 67 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", | 68 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", |
| 68 displayItem->asDebugString().utf8().data(), m_newDisplayItems[index]
->asDebugString().utf8().data(), static_cast<int>(index)); | 69 displayItem->asDebugString().utf8().data(), m_newDisplayItems[index]
->asDebugString().utf8().data(), static_cast<int>(index)); |
| 69 #endif | 70 #endif |
| 70 ASSERT_NOT_REACHED(); | 71 ASSERT_NOT_REACHED(); |
| 71 } | 72 } |
| 72 addItemToIndex(*displayItem, m_newDisplayItems.size(), m_newDisplayItemIndic
esByClient); | 73 addItemToIndex(*displayItem, m_newDisplayItems.size(), m_newDisplayItemIndic
esByClient); |
| 73 #endif | 74 #endif // ENABLE(ASSERT) |
| 75 |
| 76 if (skippingCache()) |
| 77 displayItem->setSkippedCache(); |
| 74 | 78 |
| 75 m_newDisplayItems.append(displayItem); | 79 m_newDisplayItems.append(displayItem); |
| 76 } | 80 } |
| 77 | 81 |
| 78 void DisplayItemList::beginScope(DisplayItemClient client) | 82 void DisplayItemList::beginScope(DisplayItemClient client) |
| 79 { | 83 { |
| 80 ClientScopeIdMap::iterator it = m_clientScopeIdMap.find(client); | 84 ClientScopeIdMap::iterator it = m_clientScopeIdMap.find(client); |
| 81 int scopeId; | 85 int scopeId; |
| 82 if (it == m_clientScopeIdMap.end()) { | 86 if (it == m_clientScopeIdMap.end()) { |
| 83 m_clientScopeIdMap.add(client, 0); | 87 m_clientScopeIdMap.add(client, 0); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 107 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 111 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
| 108 // Can only be called during layout/paintInvalidation, not during painting. | 112 // Can only be called during layout/paintInvalidation, not during painting. |
| 109 ASSERT(m_newDisplayItems.isEmpty()); | 113 ASSERT(m_newDisplayItems.isEmpty()); |
| 110 m_currentDisplayItems.clear(); | 114 m_currentDisplayItems.clear(); |
| 111 m_validlyCachedClients.clear(); | 115 m_validlyCachedClients.clear(); |
| 112 m_validlyCachedClientsDirty = false; | 116 m_validlyCachedClientsDirty = false; |
| 113 } | 117 } |
| 114 | 118 |
| 115 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const | 119 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const |
| 116 { | 120 { |
| 121 if (skippingCache()) |
| 122 return false; |
| 117 updateValidlyCachedClientsIfNeeded(); | 123 updateValidlyCachedClientsIfNeeded(); |
| 118 return m_validlyCachedClients.contains(client); | 124 return m_validlyCachedClients.contains(client); |
| 119 } | 125 } |
| 120 | 126 |
| 121 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem& displayItem
, DisplayItem::Type matchingType, const DisplayItemIndicesByClientMap& displayIt
emIndicesByClient, const DisplayItems& list) | 127 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem& displayItem
, DisplayItem::Type matchingType, const DisplayItemIndicesByClientMap& displayIt
emIndicesByClient, const DisplayItems& list) |
| 122 { | 128 { |
| 123 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(displayItem.client()); | 129 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(displayItem.client()); |
| 124 if (it == displayItemIndicesByClient.end()) | 130 if (it == displayItemIndicesByClient.end()) |
| 125 return kNotFound; | 131 return kNotFound; |
| 126 | 132 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 // Coefficients are related to the ratio of out-of-order [Subtree]CachedDisplayI
tems | 193 // Coefficients are related to the ratio of out-of-order [Subtree]CachedDisplayI
tems |
| 188 // and the average number of (Drawing|BeginSubtree)DisplayItems per client. | 194 // and the average number of (Drawing|BeginSubtree)DisplayItems per client. |
| 189 void DisplayItemList::commitNewDisplayItems() | 195 void DisplayItemList::commitNewDisplayItems() |
| 190 { | 196 { |
| 191 TRACE_EVENT0("blink,benchmark", "DisplayItemList::commitNewDisplayItems"); | 197 TRACE_EVENT0("blink,benchmark", "DisplayItemList::commitNewDisplayItems"); |
| 192 | 198 |
| 193 // These data structures are used during painting only. | 199 // These data structures are used during painting only. |
| 194 m_clientScopeIdMap.clear(); | 200 m_clientScopeIdMap.clear(); |
| 195 ASSERT(m_scopeStack.isEmpty()); | 201 ASSERT(m_scopeStack.isEmpty()); |
| 196 m_scopeStack.clear(); | 202 m_scopeStack.clear(); |
| 203 ASSERT(!skippingCache()); |
| 197 #if ENABLE(ASSERT) | 204 #if ENABLE(ASSERT) |
| 198 m_newDisplayItemIndicesByClient.clear(); | 205 m_newDisplayItemIndicesByClient.clear(); |
| 199 #endif | 206 #endif |
| 200 | 207 |
| 201 if (m_currentDisplayItems.isEmpty()) { | 208 if (m_currentDisplayItems.isEmpty()) { |
| 202 #if ENABLE(ASSERT) | 209 #if ENABLE(ASSERT) |
| 203 for (auto& item : m_newDisplayItems) | 210 for (auto& item : m_newDisplayItems) |
| 204 ASSERT(!item->isCached() && !item->isSubtreeCached()); | 211 ASSERT(!item->isCached() && !item->isSubtreeCached()); |
| 205 #endif | 212 #endif |
| 206 m_currentDisplayItems.swap(m_newDisplayItems); | 213 m_currentDisplayItems.swap(m_newDisplayItems); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 isSynchronized = (foundIndex == currentDisplayItemsIndex); | 253 isSynchronized = (foundIndex == currentDisplayItemsIndex); |
| 247 updatedList.append(m_currentDisplayItems[foundIndex].release
()); | 254 updatedList.append(m_currentDisplayItems[foundIndex].release
()); |
| 248 } | 255 } |
| 249 // else: do nothing because previously the client generated a em
pty picture which is not stored in the cache. | 256 // else: do nothing because previously the client generated a em
pty picture which is not stored in the cache. |
| 250 } | 257 } |
| 251 } else { | 258 } else { |
| 252 #if ENABLE(ASSERT) | 259 #if ENABLE(ASSERT) |
| 253 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn
abled()) | 260 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn
abled()) |
| 254 checkCachedDisplayItemIsUnchanged(*newDisplayItem, displayItemIn
dicesByClient); | 261 checkCachedDisplayItemIsUnchanged(*newDisplayItem, displayItemIn
dicesByClient); |
| 255 else | 262 else |
| 256 ASSERT(!newDisplayItem->isDrawing() || !clientCacheIsValid(newDi
splayItem->client())); | 263 ASSERT(!newDisplayItem->isDrawing() || newDisplayItem->skippedCa
che() || !clientCacheIsValid(newDisplayItem->client())); |
| 257 #endif // ENABLE(ASSERT) | 264 #endif // ENABLE(ASSERT) |
| 258 updatedList.append(newDisplayItem.release()); | 265 updatedList.append(newDisplayItem.release()); |
| 259 } | 266 } |
| 260 | 267 |
| 261 if (isSynchronized) | 268 if (isSynchronized) |
| 262 ++currentDisplayItemsIndex; | 269 ++currentDisplayItemsIndex; |
| 263 } | 270 } |
| 264 | 271 |
| 265 #if ENABLE(ASSERT) | 272 #if ENABLE(ASSERT) |
| 266 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 273 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 279 return; | 286 return; |
| 280 | 287 |
| 281 m_validlyCachedClients.clear(); | 288 m_validlyCachedClients.clear(); |
| 282 m_validlyCachedClientsDirty = false; | 289 m_validlyCachedClientsDirty = false; |
| 283 | 290 |
| 284 DisplayItemClient lastClient = nullptr; | 291 DisplayItemClient lastClient = nullptr; |
| 285 for (const auto& displayItem : m_currentDisplayItems) { | 292 for (const auto& displayItem : m_currentDisplayItems) { |
| 286 if (displayItem->client() == lastClient) | 293 if (displayItem->client() == lastClient) |
| 287 continue; | 294 continue; |
| 288 lastClient = displayItem->client(); | 295 lastClient = displayItem->client(); |
| 289 m_validlyCachedClients.add(lastClient); | 296 if (!displayItem->skippedCache()) |
| 297 m_validlyCachedClients.add(lastClient); |
| 290 } | 298 } |
| 291 } | 299 } |
| 292 | 300 |
| 293 #if ENABLE(ASSERT) | 301 #if ENABLE(ASSERT) |
| 294 | 302 |
| 295 static void showUnderInvalidationError(const char* reason, const DisplayItem& di
splayItem) | 303 static void showUnderInvalidationError(const char* reason, const DisplayItem& di
splayItem) |
| 296 { | 304 { |
| 297 #ifndef NDEBUG | 305 #ifndef NDEBUG |
| 298 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD
ebugString().utf8().data()); | 306 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD
ebugString().utf8().data()); |
| 299 #else | 307 #else |
| (...skipping 15 matching lines...) Expand all Loading... |
| 315 return result; | 323 return result; |
| 316 } | 324 } |
| 317 | 325 |
| 318 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ
ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) | 326 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ
ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) |
| 319 { | 327 { |
| 320 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); | 328 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); |
| 321 | 329 |
| 322 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) | 330 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) |
| 323 return; | 331 return; |
| 324 | 332 |
| 325 DrawingDisplayItem::UnderInvalidationCheckingMode mode = static_cast<const D
rawingDisplayItem&>(displayItem).underInvalidationCheckingMode(); | 333 const DrawingDisplayItem& drawingDisplayItem = static_cast<const DrawingDisp
layItem&>(displayItem); |
| 334 if (drawingDisplayItem.skippedCache()) |
| 335 return; |
| 336 |
| 337 DrawingDisplayItem::UnderInvalidationCheckingMode mode = drawingDisplayItem.
underInvalidationCheckingMode(); |
| 326 if (mode == DrawingDisplayItem::DontCheck) | 338 if (mode == DrawingDisplayItem::DontCheck) |
| 327 return; | 339 return; |
| 328 | 340 |
| 329 // If checking under-invalidation, we always generate new display item even
if the client is not invalidated. | 341 // If checking under-invalidation, we always generate new display item even
if the client is not invalidated. |
| 330 // Checks if the new picture is the same as the cached old picture. If the n
ew picture is different but | 342 // Checks if the new picture is the same as the cached old picture. If the n
ew picture is different but |
| 331 // the client is not invalidated, issue error about under-invalidation. | 343 // the client is not invalidated, issue error about under-invalidation. |
| 332 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di
splayItemIndicesByClient, m_currentDisplayItems); | 344 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di
splayItemIndicesByClient, m_currentDisplayItems); |
| 333 if (index == kNotFound) { | 345 if (index == kNotFound) { |
| 334 showUnderInvalidationError("ERROR: under-invalidation: no cached display
item", displayItem); | 346 showUnderInvalidationError("ERROR: under-invalidation: no cached display
item", displayItem); |
| 335 ASSERT_NOT_REACHED(); | 347 ASSERT_NOT_REACHED(); |
| 336 return; | 348 return; |
| 337 } | 349 } |
| 338 | 350 |
| 339 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>(
displayItem).picture(); | 351 RefPtr<const SkPicture> newPicture = drawingDisplayItem.picture(); |
| 340 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(
*m_currentDisplayItems[index]).picture(); | 352 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(
*m_currentDisplayItems[index]).picture(); |
| 341 // Remove the display item from cache so that we can check if there are any
remaining cached display items after merging. | 353 // Remove the display item from cache so that we can check if there are any
remaining cached display items after merging. |
| 342 m_currentDisplayItems[index] = nullptr; | 354 m_currentDisplayItems[index] = nullptr; |
| 343 | 355 |
| 344 if (!newPicture && !oldPicture) | 356 if (!newPicture && !oldPicture) |
| 345 return; | 357 return; |
| 346 if (newPicture && oldPicture) { | 358 if (newPicture && oldPicture) { |
| 347 switch (mode) { | 359 switch (mode) { |
| 348 case DrawingDisplayItem::CheckPicture: | 360 case DrawingDisplayItem::CheckPicture: |
| 349 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou
nt()) { | 361 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou
nt()) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 | 447 |
| 436 void DisplayItemList::replay(GraphicsContext& context) const | 448 void DisplayItemList::replay(GraphicsContext& context) const |
| 437 { | 449 { |
| 438 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 450 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
| 439 ASSERT(m_newDisplayItems.isEmpty()); | 451 ASSERT(m_newDisplayItems.isEmpty()); |
| 440 for (auto& displayItem : m_currentDisplayItems) | 452 for (auto& displayItem : m_currentDisplayItems) |
| 441 displayItem->replay(context); | 453 displayItem->replay(context); |
| 442 } | 454 } |
| 443 | 455 |
| 444 } // namespace blink | 456 } // namespace blink |
| OLD | NEW |