Chromium Code Reviews| 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/TraceEvent.h" | 9 #include "platform/TraceEvent.h" |
| 10 #include "platform/graphics/GraphicsLayer.h" | 10 #include "platform/graphics/GraphicsLayer.h" |
| 11 #include "platform/graphics/paint/DrawingDisplayItem.h" | 11 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 12 | 12 |
| 13 #ifndef NDEBUG | 13 #ifndef NDEBUG |
| 14 #include "platform/graphics/LoggingCanvas.h" | 14 #include "platform/graphics/LoggingCanvas.h" |
| 15 #include "wtf/text/StringBuilder.h" | 15 #include "wtf/text/StringBuilder.h" |
| 16 #include <stdio.h> | 16 #include <stdio.h> |
| 17 #endif | 17 #endif |
| 18 | 18 |
| 19 namespace blink { | 19 namespace blink { |
| 20 | 20 |
| 21 const DisplayItems& DisplayItemList::displayItems() const | 21 const PaintArtifact& DisplayItemList::paintArtifact() const |
| 22 { | 22 { |
| 23 ASSERT(m_newDisplayItems.isEmpty()); | 23 ASSERT(m_newDisplayItems.isEmpty()); |
| 24 return m_currentDisplayItems; | |
| 25 } | |
| 26 | |
| 27 const Vector<PaintChunk>& DisplayItemList::paintChunks() const | |
| 28 { | |
| 29 ASSERT(m_newPaintChunks.isInInitialState()); | 24 ASSERT(m_newPaintChunks.isInInitialState()); |
| 30 return m_currentPaintChunks; | 25 return m_currentPaintArtifact; |
| 31 } | 26 } |
| 32 | 27 |
| 33 bool DisplayItemList::lastDisplayItemIsNoopBegin() const | 28 bool DisplayItemList::lastDisplayItemIsNoopBegin() const |
| 34 { | 29 { |
| 35 if (m_newDisplayItems.isEmpty()) | 30 if (m_newDisplayItems.isEmpty()) |
| 36 return false; | 31 return false; |
| 37 | 32 |
| 38 const auto& lastDisplayItem = m_newDisplayItems.last(); | 33 const auto& lastDisplayItem = m_newDisplayItems.last(); |
| 39 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); | 34 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); |
| 40 } | 35 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 // This can be called during painting, but we can't invalidate already paint ed clients. | 139 // This can be called during painting, but we can't invalidate already paint ed clients. |
| 145 ASSERT(!m_newDisplayItemIndicesByClient.contains(client)); | 140 ASSERT(!m_newDisplayItemIndicesByClient.contains(client)); |
| 146 updateValidlyCachedClientsIfNeeded(); | 141 updateValidlyCachedClientsIfNeeded(); |
| 147 m_validlyCachedClients.remove(client); | 142 m_validlyCachedClients.remove(client); |
| 148 } | 143 } |
| 149 | 144 |
| 150 void DisplayItemList::invalidateAll() | 145 void DisplayItemList::invalidateAll() |
| 151 { | 146 { |
| 152 // Can only be called during layout/paintInvalidation, not during painting. | 147 // Can only be called during layout/paintInvalidation, not during painting. |
| 153 ASSERT(m_newDisplayItems.isEmpty()); | 148 ASSERT(m_newDisplayItems.isEmpty()); |
| 154 m_currentDisplayItems.clear(); | 149 m_currentPaintArtifact.reset(); |
| 155 m_validlyCachedClients.clear(); | 150 m_validlyCachedClients.clear(); |
| 156 m_validlyCachedClientsDirty = false; | 151 m_validlyCachedClientsDirty = false; |
| 157 | 152 |
| 158 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects) | 153 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects) |
| 159 m_trackedPaintInvalidationObjects->append("##ALL##"); | 154 m_trackedPaintInvalidationObjects->append("##ALL##"); |
| 160 } | 155 } |
| 161 | 156 |
| 162 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const | 157 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const |
| 163 { | 158 { |
| 164 if (skippingCache()) | 159 if (skippingCache()) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 OutOfOrderIndexContext(DisplayItems::iterator begin) : nextItemToIndex(begin ) { } | 213 OutOfOrderIndexContext(DisplayItems::iterator begin) : nextItemToIndex(begin ) { } |
| 219 | 214 |
| 220 DisplayItems::iterator nextItemToIndex; | 215 DisplayItems::iterator nextItemToIndex; |
| 221 DisplayItemIndicesByClientMap displayItemIndicesByClient; | 216 DisplayItemIndicesByClientMap displayItemIndicesByClient; |
| 222 }; | 217 }; |
| 223 | 218 |
| 224 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(const DisplayIt em::Id& id, OutOfOrderIndexContext& context) | 219 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(const DisplayIt em::Id& id, OutOfOrderIndexContext& context) |
| 225 { | 220 { |
| 226 ASSERT(clientCacheIsValid(id.client)); | 221 ASSERT(clientCacheIsValid(id.client)); |
| 227 | 222 |
| 228 size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndices ByClient, m_currentDisplayItems); | 223 size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndices ByClient, m_currentPaintArtifact.displayItems()); |
| 229 if (foundIndex != kNotFound) | 224 if (foundIndex != kNotFound) |
| 230 return m_currentDisplayItems.begin() + foundIndex; | 225 return m_currentPaintArtifact.displayItems().begin() + foundIndex; |
| 231 | 226 |
| 232 return findOutOfOrderCachedItemForward(id, context); | 227 return findOutOfOrderCachedItemForward(id, context); |
| 233 } | 228 } |
| 234 | 229 |
| 235 // Find forward for the item and index all skipped indexable items. | 230 // Find forward for the item and index all skipped indexable items. |
| 236 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(const Di splayItem::Id& id, OutOfOrderIndexContext& context) | 231 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(const Di splayItem::Id& id, OutOfOrderIndexContext& context) |
| 237 { | 232 { |
| 238 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 233 DisplayItems::iterator currentEnd = m_currentPaintArtifact.displayItems().en d(); |
| 239 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { | 234 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { |
| 240 const DisplayItem& item = *context.nextItemToIndex; | 235 const DisplayItem& item = *context.nextItemToIndex; |
| 241 ASSERT(item.isValid()); | 236 ASSERT(item.isValid()); |
| 242 if (item.isCacheable() && clientCacheIsValid(item.client())) { | 237 if (item.isCacheable() && clientCacheIsValid(item.client())) { |
| 243 if (id.matches(item)) | 238 if (id.matches(item)) |
| 244 return context.nextItemToIndex++; | 239 return context.nextItemToIndex++; |
| 245 | 240 |
| 246 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentDisp layItems.begin(), context.displayItemIndicesByClient); | 241 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPain tArtifact.displayItems().begin(), context.displayItemIndicesByClient); |
| 247 } | 242 } |
| 248 } | 243 } |
| 249 return currentEnd; | 244 return currentEnd; |
| 250 } | 245 } |
| 251 | 246 |
| 252 void DisplayItemList::copyCachedSubsequence(DisplayItems::iterator& currentIt, D isplayItems& updatedList) | 247 void DisplayItemList::copyCachedSubsequence(DisplayItems::iterator& currentIt, D isplayItems& updatedList) |
| 253 { | 248 { |
| 254 ASSERT(currentIt->isSubsequence()); | 249 ASSERT(currentIt->isSubsequence()); |
| 255 ASSERT(!currentIt->scope()); | 250 ASSERT(!currentIt->scope()); |
| 256 DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::subsequen ceTypeToEndSubsequenceType(currentIt->type()), 0); | 251 DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::subsequen ceTypeToEndSubsequenceType(currentIt->type()), 0); |
| 257 do { | 252 do { |
| 258 // We should always find the EndSubsequence display item. | 253 // We should always find the EndSubsequence display item. |
| 259 ASSERT(currentIt != m_currentDisplayItems.end()); | 254 ASSERT(currentIt != m_currentPaintArtifact.displayItems().end()); |
| 260 ASSERT(currentIt->isValid()); | 255 ASSERT(currentIt->isValid()); |
| 261 updatedList.appendByMoving(*currentIt); | 256 updatedList.appendByMoving(*currentIt); |
| 262 ++currentIt; | 257 ++currentIt; |
| 263 } while (!endSubsequenceId.matches(updatedList.last())); | 258 } while (!endSubsequenceId.matches(updatedList.last())); |
| 264 } | 259 } |
| 265 | 260 |
| 266 // Update the existing display items by removing invalidated entries, updating | 261 // Update the existing display items by removing invalidated entries, updating |
| 267 // repainted ones, and appending new items. | 262 // repainted ones, and appending new items. |
| 268 // - For cached drawing display item, copy the corresponding cached DrawingDispl ayItem; | 263 // - For cached drawing display item, copy the corresponding cached DrawingDispl ayItem; |
| 269 // - For cached subsequence display item, copy the cached display items between the | 264 // - For cached subsequence display item, copy the cached display items between the |
| 270 // corresponding SubsequenceDisplayItem and EndSubsequenceDisplayItem (incl.); | 265 // corresponding SubsequenceDisplayItem and EndSubsequenceDisplayItem (incl.); |
| 271 // - Otherwise, copy the new display item. | 266 // - Otherwise, copy the new display item. |
| 272 // | 267 // |
| 273 // The algorithm is O(|m_currentDisplayItems| + |m_newDisplayItems|). | 268 // The algorithm is O(|m_currentDisplayItems| + |m_newDisplayItems|). |
| 274 // Coefficients are related to the ratio of out-of-order CachedDisplayItems | 269 // Coefficients are related to the ratio of out-of-order CachedDisplayItems |
| 275 // and the average number of (Drawing|Subsequence)DisplayItems per client. | 270 // and the average number of (Drawing|Subsequence)DisplayItems per client. |
| 276 // | 271 // |
| 277 void DisplayItemList::commitNewDisplayItems(GraphicsLayer* graphicsLayer) | 272 void DisplayItemList::commitNewDisplayItems(GraphicsLayer* graphicsLayer) |
| 278 { | 273 { |
| 279 TRACE_EVENT2("blink,benchmark", "DisplayItemList::commitNewDisplayItems", "c urrent_display_list_size", (int)m_currentDisplayItems.size(), | 274 TRACE_EVENT2("blink,benchmark", "DisplayItemList::commitNewDisplayItems", |
| 275 "current_display_list_size", (int)m_currentPaintArtifact.displayItems(). size(), | |
| 280 "num_non_cached_new_items", (int)m_newDisplayItems.size() - m_numCachedI tems); | 276 "num_non_cached_new_items", (int)m_newDisplayItems.size() - m_numCachedI tems); |
| 281 | 277 |
| 282 if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) { | 278 if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) { |
| 283 for (const auto& invalidation : m_invalidations) | 279 for (const auto& invalidation : m_invalidations) |
| 284 graphicsLayer->setNeedsDisplayInRect(invalidation.rect, invalidation .invalidationReason); | 280 graphicsLayer->setNeedsDisplayInRect(invalidation.rect, invalidation .invalidationReason); |
| 285 m_invalidations.clear(); | 281 m_invalidations.clear(); |
| 286 m_clientsCheckedPaintInvalidation.clear(); | 282 m_clientsCheckedPaintInvalidation.clear(); |
| 287 } | 283 } |
| 288 | 284 |
| 289 // These data structures are used during painting only. | 285 // These data structures are used during painting only. |
| 290 ASSERT(m_scopeStack.isEmpty()); | 286 ASSERT(m_scopeStack.isEmpty()); |
| 291 m_scopeStack.clear(); | 287 m_scopeStack.clear(); |
| 292 m_nextScope = 1; | 288 m_nextScope = 1; |
| 293 ASSERT(!skippingCache()); | 289 ASSERT(!skippingCache()); |
| 294 #if ENABLE(ASSERT) | 290 #if ENABLE(ASSERT) |
| 295 m_newDisplayItemIndicesByClient.clear(); | 291 m_newDisplayItemIndicesByClient.clear(); |
| 296 m_clientsWithPaintOffsetInvalidations.clear(); | 292 m_clientsWithPaintOffsetInvalidations.clear(); |
| 297 #endif | 293 #endif |
| 298 | 294 |
| 299 if (m_currentDisplayItems.isEmpty()) { | 295 if (m_currentPaintArtifact.isEmpty()) { |
| 300 #if ENABLE(ASSERT) | 296 #if ENABLE(ASSERT) |
| 301 for (const auto& item : m_newDisplayItems) | 297 for (const auto& item : m_newDisplayItems) |
| 302 ASSERT(!item.isCached()); | 298 ASSERT(!item.isCached()); |
| 303 #endif | 299 #endif |
| 304 m_currentDisplayItems.swap(m_newDisplayItems); | 300 m_currentPaintArtifact.update(m_newDisplayItems, m_newPaintChunks.releas ePaintChunks()); |
| 305 m_currentPaintChunks = m_newPaintChunks.releasePaintChunks(); | |
| 306 m_validlyCachedClientsDirty = true; | 301 m_validlyCachedClientsDirty = true; |
| 307 m_numCachedItems = 0; | 302 m_numCachedItems = 0; |
| 308 return; | 303 return; |
| 309 } | 304 } |
| 310 | 305 |
| 311 updateValidlyCachedClientsIfNeeded(); | 306 updateValidlyCachedClientsIfNeeded(); |
| 312 | 307 |
| 313 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched | 308 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched |
| 314 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched | 309 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched |
| 315 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when | 310 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when |
| 316 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems | 311 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems |
| 317 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. | 312 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. |
| 318 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin()) ; | 313 OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.display Items().begin()); |
| 319 | 314 |
| 320 // TODO(jbroman): Consider revisiting this heuristic. | 315 // TODO(jbroman): Consider revisiting this heuristic. |
| 321 DisplayItems updatedList(std::max(m_currentDisplayItems.usedCapacityInBytes( ), m_newDisplayItems.usedCapacityInBytes())); | 316 DisplayItems updatedList(std::max(m_currentPaintArtifact.displayItems().used CapacityInBytes(), m_newDisplayItems.usedCapacityInBytes())); |
| 322 Vector<PaintChunk> updatedPaintChunks; | 317 Vector<PaintChunk> updatedPaintChunks; |
| 323 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); | 318 DisplayItems::iterator currentIt = m_currentPaintArtifact.displayItems().beg in(); |
| 324 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 319 DisplayItems::iterator currentEnd = m_currentPaintArtifact.displayItems().en d(); |
| 325 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne wDisplayItems.end(); ++newIt) { | 320 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne wDisplayItems.end(); ++newIt) { |
| 326 const DisplayItem& newDisplayItem = *newIt; | 321 const DisplayItem& newDisplayItem = *newIt; |
| 327 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 322 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
| 328 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt emId.type; | 323 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt emId.type; |
| 329 | 324 |
| 330 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt); | 325 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt); |
| 331 | 326 |
| 332 if (newDisplayItemHasCachedType) { | 327 if (newDisplayItemHasCachedType) { |
| 333 ASSERT(newDisplayItem.isCached()); | 328 ASSERT(newDisplayItem.isCached()); |
| 334 ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable dFeatures::slimmingPaintOffsetCachingEnabled() && !paintOffsetWasInvalidated(new DisplayItem.client()))); | 329 ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable dFeatures::slimmingPaintOffsetCachingEnabled() && !paintOffsetWasInvalidated(new DisplayItem.client()))); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 // Items before currentIt should have been copied so we don't need to in dex them. | 370 // Items before currentIt should have been copied so we don't need to in dex them. |
| 376 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) | 371 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) |
| 377 outOfOrderIndexContext.nextItemToIndex = currentIt; | 372 outOfOrderIndexContext.nextItemToIndex = currentIt; |
| 378 } | 373 } |
| 379 | 374 |
| 380 #if ENABLE(ASSERT) | 375 #if ENABLE(ASSERT) |
| 381 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 376 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
| 382 checkNoRemainingCachedDisplayItems(); | 377 checkNoRemainingCachedDisplayItems(); |
| 383 #endif // ENABLE(ASSERT) | 378 #endif // ENABLE(ASSERT) |
| 384 | 379 |
| 380 | |
|
pdr.
2015/10/09 03:57:50
Nit
| |
| 385 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to | 381 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to |
| 386 // merge the paint chunks as well. | 382 // merge the paint chunks as well. |
| 387 m_currentPaintChunks = m_newPaintChunks.releasePaintChunks(); | 383 m_currentPaintArtifact.update(updatedList, m_newPaintChunks.releasePaintChun ks()); |
| 388 | 384 |
| 389 m_newDisplayItems.clear(); | 385 m_newDisplayItems.clear(); |
| 390 m_validlyCachedClientsDirty = true; | 386 m_validlyCachedClientsDirty = true; |
| 391 m_currentDisplayItems.swap(updatedList); | |
| 392 m_numCachedItems = 0; | 387 m_numCachedItems = 0; |
| 393 } | 388 } |
| 394 | 389 |
| 395 size_t DisplayItemList::approximateUnsharedMemoryUsage() const | 390 size_t DisplayItemList::approximateUnsharedMemoryUsage() const |
| 396 { | 391 { |
| 397 size_t memoryUsage = sizeof(*this); | 392 size_t memoryUsage = sizeof(*this); |
| 398 | 393 |
| 399 // Memory outside this class due to m_currentDisplayItems. | 394 // Memory outside this class due to m_currentPaintArtifact. |
| 400 memoryUsage += m_currentDisplayItems.memoryUsageInBytes(); | 395 memoryUsage += m_currentPaintArtifact.approximateUnsharedMemoryUsage() - siz eof(m_currentPaintArtifact); |
| 401 | 396 |
| 402 // TODO(jbroman): If display items begin to have significant external memory | 397 // TODO(jbroman): If display items begin to have significant external memory |
| 403 // usage that's not shared with the embedder, we should account for it here. | 398 // usage that's not shared with the embedder, we should account for it here. |
| 404 // | 399 // |
| 405 // External objects, shared with the embedder, such as SkPicture, should be | 400 // External objects, shared with the embedder, such as SkPicture, should be |
| 406 // excluded to avoid double counting. It is the embedder's responsibility to | 401 // excluded to avoid double counting. It is the embedder's responsibility to |
| 407 // count such objects. | 402 // count such objects. |
| 408 // | 403 // |
| 409 // At time of writing, the only known case of unshared external memory was | 404 // At time of writing, the only known case of unshared external memory was |
| 410 // the rounded clips vector in ClipDisplayItem, which is not expected to | 405 // the rounded clips vector in ClipDisplayItem, which is not expected to |
| 411 // contribute significantly to memory usage. | 406 // contribute significantly to memory usage. |
| 412 | 407 |
| 413 // Memory outside this class due to m_newDisplayItems. | 408 // Memory outside this class due to m_newDisplayItems. |
| 414 ASSERT(m_newDisplayItems.isEmpty()); | 409 ASSERT(m_newDisplayItems.isEmpty()); |
| 415 memoryUsage += m_newDisplayItems.memoryUsageInBytes(); | 410 memoryUsage += m_newDisplayItems.memoryUsageInBytes(); |
| 416 | 411 |
| 417 return memoryUsage; | 412 return memoryUsage; |
| 418 } | 413 } |
| 419 | 414 |
| 420 void DisplayItemList::updateValidlyCachedClientsIfNeeded() const | 415 void DisplayItemList::updateValidlyCachedClientsIfNeeded() const |
| 421 { | 416 { |
| 422 if (!m_validlyCachedClientsDirty) | 417 if (!m_validlyCachedClientsDirty) |
| 423 return; | 418 return; |
| 424 | 419 |
| 425 m_validlyCachedClients.clear(); | 420 m_validlyCachedClients.clear(); |
| 426 m_validlyCachedClientsDirty = false; | 421 m_validlyCachedClientsDirty = false; |
| 427 | 422 |
| 428 DisplayItemClient lastAddedClient = nullptr; | 423 DisplayItemClient lastAddedClient = nullptr; |
| 429 for (const DisplayItem& displayItem : m_currentDisplayItems) { | 424 for (const DisplayItem& displayItem : m_currentPaintArtifact.displayItems()) { |
| 430 if (displayItem.client() == lastAddedClient) | 425 if (displayItem.client() == lastAddedClient) |
| 431 continue; | 426 continue; |
| 432 if (displayItem.isCacheable()) { | 427 if (displayItem.isCacheable()) { |
| 433 lastAddedClient = displayItem.client(); | 428 lastAddedClient = displayItem.client(); |
| 434 m_validlyCachedClients.add(lastAddedClient); | 429 m_validlyCachedClients.add(lastAddedClient); |
| 435 } | 430 } |
| 436 } | 431 } |
| 437 } | 432 } |
| 438 | 433 |
| 439 void DisplayItemList::appendToWebDisplayItemList(WebDisplayItemList* list) | |
| 440 { | |
| 441 for (const DisplayItem& item : m_currentDisplayItems) | |
| 442 item.appendToWebDisplayItemList(list); | |
| 443 } | |
| 444 | |
| 445 void DisplayItemList::commitNewDisplayItemsAndAppendToWebDisplayItemList(WebDisp layItemList* list) | |
| 446 { | |
| 447 commitNewDisplayItems(); | |
| 448 appendToWebDisplayItemList(list); | |
| 449 } | |
| 450 | |
| 451 #if ENABLE(ASSERT) | 434 #if ENABLE(ASSERT) |
| 452 | 435 |
| 453 void DisplayItemList::checkUnderInvalidation(DisplayItems::iterator& newIt, Disp layItems::iterator& currentIt) | 436 void DisplayItemList::checkUnderInvalidation(DisplayItems::iterator& newIt, Disp layItems::iterator& currentIt) |
| 454 { | 437 { |
| 455 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); | 438 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); |
| 456 ASSERT(newIt->isCached()); | 439 ASSERT(newIt->isCached()); |
| 457 | 440 |
| 458 // When under-invalidation-checking is enabled, the forced painting is follo wing the cached display item. | 441 // When under-invalidation-checking is enabled, the forced painting is follo wing the cached display item. |
| 459 DisplayItem::Type nextItemType = DisplayItem::nonCachedType(newIt->type()); | 442 DisplayItem::Type nextItemType = DisplayItem::nonCachedType(newIt->type()); |
| 460 ++newIt; | 443 ++newIt; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 } | 515 } |
| 533 #endif // NDEBUG | 516 #endif // NDEBUG |
| 534 | 517 |
| 535 ASSERT_NOT_REACHED(); | 518 ASSERT_NOT_REACHED(); |
| 536 } | 519 } |
| 537 | 520 |
| 538 void DisplayItemList::checkNoRemainingCachedDisplayItems() | 521 void DisplayItemList::checkNoRemainingCachedDisplayItems() |
| 539 { | 522 { |
| 540 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); | 523 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); |
| 541 | 524 |
| 542 for (const auto& displayItem : m_currentDisplayItems) { | 525 for (const auto& displayItem : m_currentPaintArtifact.displayItems()) { |
| 543 if (!displayItem.isValid() || !displayItem.isCacheable() || !clientCache IsValid(displayItem.client())) | 526 if (!displayItem.isValid() || !displayItem.isCacheable() || !clientCache IsValid(displayItem.client())) |
| 544 continue; | 527 continue; |
| 545 showUnderInvalidationError("", "May be under-invalidation: no new displa y item", nullptr, &displayItem); | 528 showUnderInvalidationError("", "May be under-invalidation: no new displa y item", nullptr, &displayItem); |
| 546 } | 529 } |
| 547 } | 530 } |
| 548 | 531 |
| 549 #endif // ENABLE(ASSERT) | 532 #endif // ENABLE(ASSERT) |
| 550 | 533 |
| 551 #ifndef NDEBUG | 534 #ifndef NDEBUG |
| 552 | 535 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 564 stringBuilder.append(", cacheIsValid: "); | 547 stringBuilder.append(", cacheIsValid: "); |
| 565 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "tru e" : "false"); | 548 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "tru e" : "false"); |
| 566 } | 549 } |
| 567 stringBuilder.append('}'); | 550 stringBuilder.append('}'); |
| 568 } | 551 } |
| 569 return stringBuilder.toString(); | 552 return stringBuilder.toString(); |
| 570 } | 553 } |
| 571 | 554 |
| 572 void DisplayItemList::showDebugData() const | 555 void DisplayItemList::showDebugData() const |
| 573 { | 556 { |
| 574 WTFLogAlways("current display items: [%s]\n", displayItemsAsDebugString(m_cu rrentDisplayItems).utf8().data()); | 557 WTFLogAlways("current display items: [%s]\n", displayItemsAsDebugString(m_cu rrentPaintArtifact.displayItems()).utf8().data()); |
| 575 WTFLogAlways("new display items: [%s]\n", displayItemsAsDebugString(m_newDis playItems).utf8().data()); | 558 WTFLogAlways("new display items: [%s]\n", displayItemsAsDebugString(m_newDis playItems).utf8().data()); |
| 576 } | 559 } |
| 577 | 560 |
| 578 #endif // ifndef NDEBUG | 561 #endif // ifndef NDEBUG |
| 579 | 562 |
| 580 void DisplayItemList::replay(GraphicsContext& context) const | |
| 581 { | |
| 582 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | |
| 583 ASSERT(m_newDisplayItems.isEmpty()); | |
| 584 for (const DisplayItem& displayItem : m_currentDisplayItems) | |
| 585 displayItem.replay(context); | |
| 586 } | |
| 587 | |
| 588 } // namespace blink | 563 } // namespace blink |
| OLD | NEW |