| 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 DisplayItems& DisplayItemList::displayItems() const |
| 22 { | 22 { |
| 23 ASSERT(m_newDisplayItems.isEmpty()); | 23 ASSERT(m_newDisplayItems.isEmpty()); |
| 24 return m_currentDisplayItems; | 24 return m_currentDisplayItems; |
| 25 } | 25 } |
| 26 | 26 |
| 27 const Vector<PaintChunk>& DisplayItemList::paintChunks() const |
| 28 { |
| 29 ASSERT(m_newPaintChunks.isInInitialState()); |
| 30 return m_currentPaintChunks; |
| 31 } |
| 32 |
| 27 bool DisplayItemList::lastDisplayItemIsNoopBegin() const | 33 bool DisplayItemList::lastDisplayItemIsNoopBegin() const |
| 28 { | 34 { |
| 29 if (m_newDisplayItems.isEmpty()) | 35 if (m_newDisplayItems.isEmpty()) |
| 30 return false; | 36 return false; |
| 31 | 37 |
| 32 const auto& lastDisplayItem = m_newDisplayItems.last(); | 38 const auto& lastDisplayItem = m_newDisplayItems.last(); |
| 33 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); | 39 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); |
| 34 } | 40 } |
| 35 | 41 |
| 36 void DisplayItemList::removeLastDisplayItem() | 42 void DisplayItemList::removeLastDisplayItem() |
| 37 { | 43 { |
| 38 if (m_newDisplayItems.isEmpty()) | 44 if (m_newDisplayItems.isEmpty()) |
| 39 return; | 45 return; |
| 40 | 46 |
| 41 #if ENABLE(ASSERT) | 47 #if ENABLE(ASSERT) |
| 42 // Also remove the index pointing to the removed display item. | 48 // Also remove the index pointing to the removed display item. |
| 43 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient
.find(m_newDisplayItems.last().client()); | 49 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient
.find(m_newDisplayItems.last().client()); |
| 44 if (it != m_newDisplayItemIndicesByClient.end()) { | 50 if (it != m_newDisplayItemIndicesByClient.end()) { |
| 45 Vector<size_t>& indices = it->value; | 51 Vector<size_t>& indices = it->value; |
| 46 if (!indices.isEmpty() && indices.last() == (m_newDisplayItems.size() -
1)) | 52 if (!indices.isEmpty() && indices.last() == (m_newDisplayItems.size() -
1)) |
| 47 indices.removeLast(); | 53 indices.removeLast(); |
| 48 } | 54 } |
| 49 #endif | 55 #endif |
| 50 m_newDisplayItems.removeLast(); | 56 m_newDisplayItems.removeLast(); |
| 57 |
| 58 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 59 m_newPaintChunks.decrementDisplayItemIndex(); |
| 51 } | 60 } |
| 52 | 61 |
| 53 void DisplayItemList::processNewItem(DisplayItem& displayItem) | 62 void DisplayItemList::processNewItem(DisplayItem& displayItem) |
| 54 { | 63 { |
| 55 ASSERT(!m_constructionDisabled); | 64 ASSERT(!m_constructionDisabled); |
| 56 ASSERT(!skippingCache() || !displayItem.isCached()); | 65 ASSERT(!skippingCache() || !displayItem.isCached()); |
| 57 | 66 |
| 58 if (displayItem.isCached()) | 67 if (displayItem.isCached()) |
| 59 ++m_numCachedItems; | 68 ++m_numCachedItems; |
| 60 | 69 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 78 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", | 87 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", |
| 79 displayItem.asDebugString().utf8().data(), m_newDisplayItems[index].
asDebugString().utf8().data(), static_cast<int>(index)); | 88 displayItem.asDebugString().utf8().data(), m_newDisplayItems[index].
asDebugString().utf8().data(), static_cast<int>(index)); |
| 80 #endif | 89 #endif |
| 81 ASSERT_NOT_REACHED(); | 90 ASSERT_NOT_REACHED(); |
| 82 } | 91 } |
| 83 addItemToIndexIfNeeded(displayItem, m_newDisplayItems.size() - 1, m_newDispl
ayItemIndicesByClient); | 92 addItemToIndexIfNeeded(displayItem, m_newDisplayItems.size() - 1, m_newDispl
ayItemIndicesByClient); |
| 84 #endif // ENABLE(ASSERT) | 93 #endif // ENABLE(ASSERT) |
| 85 | 94 |
| 86 if (skippingCache()) | 95 if (skippingCache()) |
| 87 displayItem.setSkippedCache(); | 96 displayItem.setSkippedCache(); |
| 97 |
| 98 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 99 m_newPaintChunks.incrementDisplayItemIndex(); |
| 100 } |
| 101 |
| 102 void DisplayItemList::updateCurrentPaintProperties(const PaintProperties& newPai
ntProperties) |
| 103 { |
| 104 m_newPaintChunks.updateCurrentPaintProperties(newPaintProperties); |
| 88 } | 105 } |
| 89 | 106 |
| 90 void DisplayItemList::beginScope() | 107 void DisplayItemList::beginScope() |
| 91 { | 108 { |
| 92 ASSERT_WITH_SECURITY_IMPLICATION(m_nextScope < UINT_MAX); | 109 ASSERT_WITH_SECURITY_IMPLICATION(m_nextScope < UINT_MAX); |
| 93 m_scopeStack.append(m_nextScope++); | 110 m_scopeStack.append(m_nextScope++); |
| 94 beginSkippingCache(); | 111 beginSkippingCache(); |
| 95 } | 112 } |
| 96 | 113 |
| 97 void DisplayItemList::endScope() | 114 void DisplayItemList::endScope() |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 #if ENABLE(ASSERT) | 297 #if ENABLE(ASSERT) |
| 281 m_newDisplayItemIndicesByClient.clear(); | 298 m_newDisplayItemIndicesByClient.clear(); |
| 282 #endif | 299 #endif |
| 283 | 300 |
| 284 if (m_currentDisplayItems.isEmpty()) { | 301 if (m_currentDisplayItems.isEmpty()) { |
| 285 #if ENABLE(ASSERT) | 302 #if ENABLE(ASSERT) |
| 286 for (const auto& item : m_newDisplayItems) | 303 for (const auto& item : m_newDisplayItems) |
| 287 ASSERT(!item.isCached()); | 304 ASSERT(!item.isCached()); |
| 288 #endif | 305 #endif |
| 289 m_currentDisplayItems.swap(m_newDisplayItems); | 306 m_currentDisplayItems.swap(m_newDisplayItems); |
| 307 m_currentPaintChunks = m_newPaintChunks.releasePaintChunks(); |
| 290 m_validlyCachedClientsDirty = true; | 308 m_validlyCachedClientsDirty = true; |
| 291 m_numCachedItems = 0; | 309 m_numCachedItems = 0; |
| 292 return; | 310 return; |
| 293 } | 311 } |
| 294 | 312 |
| 295 updateValidlyCachedClientsIfNeeded(); | 313 updateValidlyCachedClientsIfNeeded(); |
| 296 | 314 |
| 297 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched | 315 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched |
| 298 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched | 316 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched |
| 299 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when | 317 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when |
| 300 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems | 318 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems |
| 301 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. | 319 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. |
| 302 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin())
; | 320 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin())
; |
| 303 | 321 |
| 304 // TODO(jbroman): Consider revisiting this heuristic. | 322 // TODO(jbroman): Consider revisiting this heuristic. |
| 305 DisplayItems updatedList(std::max(m_currentDisplayItems.usedCapacityInBytes(
), m_newDisplayItems.usedCapacityInBytes())); | 323 DisplayItems updatedList(std::max(m_currentDisplayItems.usedCapacityInBytes(
), m_newDisplayItems.usedCapacityInBytes())); |
| 324 Vector<PaintChunk> updatedPaintChunks; |
| 306 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); | 325 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); |
| 307 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 326 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); |
| 308 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { | 327 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { |
| 309 const DisplayItem& newDisplayItem = *newIt; | 328 const DisplayItem& newDisplayItem = *newIt; |
| 310 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 329 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
| 311 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; | 330 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; |
| 312 | 331 |
| 313 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); | 332 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); |
| 314 | 333 |
| 315 if (newDisplayItemHasCachedType) { | 334 if (newDisplayItemHasCachedType) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 // Items before currentIt should have been copied so we don't need to in
dex them. | 377 // Items before currentIt should have been copied so we don't need to in
dex them. |
| 359 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) | 378 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) |
| 360 outOfOrderIndexContext.nextItemToIndex = currentIt; | 379 outOfOrderIndexContext.nextItemToIndex = currentIt; |
| 361 } | 380 } |
| 362 | 381 |
| 363 #if ENABLE(ASSERT) | 382 #if ENABLE(ASSERT) |
| 364 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 383 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
| 365 checkNoRemainingCachedDisplayItems(); | 384 checkNoRemainingCachedDisplayItems(); |
| 366 #endif // ENABLE(ASSERT) | 385 #endif // ENABLE(ASSERT) |
| 367 | 386 |
| 387 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to |
| 388 // merge the paint chunks as well. |
| 389 m_currentPaintChunks = m_newPaintChunks.releasePaintChunks(); |
| 390 |
| 368 m_newDisplayItems.clear(); | 391 m_newDisplayItems.clear(); |
| 369 m_validlyCachedClientsDirty = true; | 392 m_validlyCachedClientsDirty = true; |
| 370 m_currentDisplayItems.swap(updatedList); | 393 m_currentDisplayItems.swap(updatedList); |
| 371 m_numCachedItems = 0; | 394 m_numCachedItems = 0; |
| 372 | 395 |
| 373 #if ENABLE(ASSERT) | 396 #if ENABLE(ASSERT) |
| 374 m_clientsWithPaintOffsetInvalidations.clear(); | 397 m_clientsWithPaintOffsetInvalidations.clear(); |
| 375 #endif | 398 #endif |
| 376 } | 399 } |
| 377 | 400 |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 | 585 |
| 563 void DisplayItemList::replay(GraphicsContext& context) | 586 void DisplayItemList::replay(GraphicsContext& context) |
| 564 { | 587 { |
| 565 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 588 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
| 566 ASSERT(m_newDisplayItems.isEmpty()); | 589 ASSERT(m_newDisplayItems.isEmpty()); |
| 567 for (DisplayItem& displayItem : m_currentDisplayItems) | 590 for (DisplayItem& displayItem : m_currentDisplayItems) |
| 568 displayItem.replay(context); | 591 displayItem.replay(context); |
| 569 } | 592 } |
| 570 | 593 |
| 571 } // namespace blink | 594 } // namespace blink |
| OLD | NEW |