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 |