| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 // is the same as the cached. | 69 // is the same as the cached. |
| 70 return false; | 70 return false; |
| 71 } | 71 } |
| 72 #endif | 72 #endif |
| 73 | 73 |
| 74 return true; | 74 return true; |
| 75 } | 75 } |
| 76 | 76 |
| 77 bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl
ient) | 77 bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl
ient) |
| 78 { | 78 { |
| 79 // TODO(crbug.com/596983): Implement subsequence caching for spv2. | |
| 80 // The problem is in copyCachedSubsequence() which fails to handle PaintChun
kProperties | |
| 81 // of chunks containing cached display items. We need to find the previous | |
| 82 // PaintChunkProperties and ensure they are valid in the current paint prope
rty tree. | |
| 83 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | |
| 84 return false; | |
| 85 | |
| 86 if (displayItemConstructionIsDisabled() || subsequenceCachingIsDisabled()) | 79 if (displayItemConstructionIsDisabled() || subsequenceCachingIsDisabled()) |
| 87 return false; | 80 return false; |
| 88 | 81 |
| 89 if (!clientCacheIsValid(client)) | 82 if (!clientCacheIsValid(client)) |
| 90 return false; | 83 return false; |
| 91 | 84 |
| 92 #if DCHECK_IS_ON() | 85 #if DCHECK_IS_ON() |
| 93 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
&& isCheckingUnderInvalidation()) { | 86 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
&& isCheckingUnderInvalidation()) { |
| 94 // We are checking under-invalidation of an ancestor subsequence enclosi
ng this one. | 87 // We are checking under-invalidation of an ancestor subsequence enclosi
ng this one. |
| 95 // The ancestor subsequence is supposed to have already "copied", so we
should let the | 88 // The ancestor subsequence is supposed to have already "copied", so we
should let the |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 | 166 |
| 174 if (displayItem.getType() == DisplayItem::Subsequence) { | 167 if (displayItem.getType() == DisplayItem::Subsequence) { |
| 175 m_currentSubsequenceClients.append(&displayItem.client()); | 168 m_currentSubsequenceClients.append(&displayItem.client()); |
| 176 } else if (displayItem.getType() == DisplayItem::EndSubsequence) { | 169 } else if (displayItem.getType() == DisplayItem::EndSubsequence) { |
| 177 CHECK(m_currentSubsequenceClients.last() == &displayItem.client()); | 170 CHECK(m_currentSubsequenceClients.last() == &displayItem.client()); |
| 178 m_currentSubsequenceClients.removeLast(); | 171 m_currentSubsequenceClients.removeLast(); |
| 179 } | 172 } |
| 180 } | 173 } |
| 181 #endif | 174 #endif |
| 182 | 175 |
| 176 if (isSkippingCache()) |
| 177 displayItem.setSkippedCache(); |
| 178 |
| 183 #if DCHECK_IS_ON() | 179 #if DCHECK_IS_ON() |
| 184 // Verify noop begin/end pairs have been removed. | 180 // Verify noop begin/end pairs have been removed. |
| 185 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { | 181 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { |
| 186 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList
.size() - 2]; | 182 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList
.size() - 2]; |
| 187 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI
tem::Subsequence && !beginDisplayItem.drawsContent()) | 183 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI
tem::Subsequence && !beginDisplayItem.drawsContent()) |
| 188 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); | 184 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); |
| 189 } | 185 } |
| 190 #endif | |
| 191 | 186 |
| 192 if (isSkippingCache()) | |
| 193 displayItem.setSkippedCache(); | |
| 194 | |
| 195 #if DCHECK_IS_ON() | |
| 196 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt
emIndicesByClient, m_newDisplayItemList); | 187 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt
emIndicesByClient, m_newDisplayItemList); |
| 197 if (index != kNotFound) { | 188 if (index != kNotFound) { |
| 198 #ifndef NDEBUG | 189 #ifndef NDEBUG |
| 199 showDebugData(); | 190 showDebugData(); |
| 200 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", | 191 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", |
| 201 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde
x].asDebugString().utf8().data(), static_cast<int>(index)); | 192 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde
x].asDebugString().utf8().data(), static_cast<int>(index)); |
| 202 #endif | 193 #endif |
| 203 NOTREACHED(); | 194 NOTREACHED(); |
| 204 } | 195 } |
| 205 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi
splayItemIndicesByClient); | 196 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi
splayItemIndicesByClient); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 m_underInvalidationCheckingBegin = cachedItemIndex; | 337 m_underInvalidationCheckingBegin = cachedItemIndex; |
| 347 #ifndef NDEBUG | 338 #ifndef NDEBUG |
| 348 m_underInvalidationMessagePrefix = "(In CachedSubsequence of " + cachedI
tem->clientDebugString() + ")"; | 339 m_underInvalidationMessagePrefix = "(In CachedSubsequence of " + cachedI
tem->clientDebugString() + ")"; |
| 349 #else | 340 #else |
| 350 m_underInvalidationMessagePrefix = "(In CachedSubsequence)"; | 341 m_underInvalidationMessagePrefix = "(In CachedSubsequence)"; |
| 351 #endif | 342 #endif |
| 352 } | 343 } |
| 353 #endif | 344 #endif |
| 354 | 345 |
| 355 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::EndSubse
quence); | 346 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::EndSubse
quence); |
| 347 Vector<PaintChunk>::const_iterator cachedChunk; |
| 348 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 349 cachedChunk = m_currentPaintArtifact.findChunkByDisplayItemIndex(cachedI
temIndex); |
| 350 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChunk->id :
nullptr, cachedChunk->properties); |
| 351 } else { |
| 352 // This is to avoid compilation error about uninitialized variable on Wi
ndows. |
| 353 cachedChunk = m_currentPaintArtifact.paintChunks().begin(); |
| 354 } |
| 355 |
| 356 while (true) { | 356 while (true) { |
| 357 DCHECK(cachedItem->hasValidClient()); | 357 DCHECK(cachedItem->hasValidClient()); |
| 358 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 358 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
| 359 CHECK(cachedItem->client().isAlive()); | 359 CHECK(cachedItem->client().isAlive()); |
| 360 #endif | 360 #endif |
| 361 ++m_numCachedNewItems; | 361 ++m_numCachedNewItems; |
| 362 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId; | 362 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId; |
| 363 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali
dationCheckingEnabled()) | 363 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali
dationCheckingEnabled()) { |
| 364 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn
dex == cachedChunk->endIndex) { |
| 365 ++cachedChunk; |
| 366 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun
k->id : nullptr, cachedChunk->properties); |
| 367 } |
| 364 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem)); | 368 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem)); |
| 369 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 370 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) ||
m_newPaintChunks.lastChunk().matches(*cachedChunk)); |
| 371 } |
| 365 | 372 |
| 366 ++cachedItemIndex; | 373 ++cachedItemIndex; |
| 367 if (metEndSubsequence) | 374 if (metEndSubsequence) |
| 368 break; | 375 break; |
| 369 | 376 |
| 370 // We should always be able to find the EndSubsequence display item. | 377 // We should always be able to find the EndSubsequence display item. |
| 371 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz
e()); | 378 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz
e()); |
| 372 cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cachedItemInde
x]; | 379 cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cachedItemInde
x]; |
| 373 } | 380 } |
| 374 | 381 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 if (item.isCacheable()) | 430 if (item.isCacheable()) |
| 424 item.client().setDisplayItemsCached(m_currentCacheGeneration); | 431 item.client().setDisplayItemsCached(m_currentCacheGeneration); |
| 425 } | 432 } |
| 426 | 433 |
| 427 // The new list will not be appended to again so we can release unused memor
y. | 434 // The new list will not be appended to again so we can release unused memor
y. |
| 428 m_newDisplayItemList.shrinkToFit(); | 435 m_newDisplayItemList.shrinkToFit(); |
| 429 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_ne
wPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization()); | 436 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_ne
wPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization()); |
| 430 resetCurrentListIndices(); | 437 resetCurrentListIndices(); |
| 431 m_outOfOrderItemIndices.clear(); | 438 m_outOfOrderItemIndices.clear(); |
| 432 | 439 |
| 440 for (const auto& chunk : m_currentPaintArtifact.paintChunks()) { |
| 441 if (chunk.id) |
| 442 chunk.id->client.setDisplayItemsCached(m_currentCacheGeneration); |
| 443 } |
| 444 |
| 433 // We'll allocate the initial buffer when we start the next paint. | 445 // We'll allocate the initial buffer when we start the next paint. |
| 434 m_newDisplayItemList = DisplayItemList(0); | 446 m_newDisplayItemList = DisplayItemList(0); |
| 435 | 447 |
| 436 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 448 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
| 437 CHECK(m_currentSubsequenceClients.isEmpty()); | 449 CHECK(m_currentSubsequenceClients.isEmpty()); |
| 438 DisplayItemClient::endShouldKeepAliveAllClients(this); | 450 DisplayItemClient::endShouldKeepAliveAllClients(this); |
| 439 #endif | 451 #endif |
| 440 | 452 |
| 441 #if DCHECK_IS_ON() | 453 #if DCHECK_IS_ON() |
| 442 m_numSequentialMatches = 0; | 454 m_numSequentialMatches = 0; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 | 564 |
| 553 void PaintController::showDebugData() const | 565 void PaintController::showDebugData() const |
| 554 { | 566 { |
| 555 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); | 567 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); |
| 556 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); | 568 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); |
| 557 } | 569 } |
| 558 | 570 |
| 559 #endif // ifndef NDEBUG | 571 #endif // ifndef NDEBUG |
| 560 | 572 |
| 561 } // namespace blink | 573 } // namespace blink |
| OLD | NEW |