| 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 | 84 |
| 85 #if DCHECK_IS_ON() | 85 #if DCHECK_IS_ON() |
| 86 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
&& isCheckingUnderInvalidation()) { | 86 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
&& isCheckingUnderInvalidation()) { |
| 87 // 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. |
| 88 // 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 |
| 89 // client continue to actually paint the descendant subsequences without
"copying". | 89 // client continue to actually paint the descendant subsequences without
"copying". |
| 90 return false; | 90 return false; |
| 91 } | 91 } |
| 92 #endif | 92 #endif |
| 93 | 93 |
| 94 size_t cachedItem = findCachedItem(DisplayItem::Id(client, DisplayItem::Subs
equence)); | 94 size_t cachedItem = findCachedItem(DisplayItem::Id(client, DisplayItem::kSub
sequence)); |
| 95 if (cachedItem == kNotFound) { | 95 if (cachedItem == kNotFound) { |
| 96 NOTREACHED(); | 96 NOTREACHED(); |
| 97 return false; | 97 return false; |
| 98 } | 98 } |
| 99 | 99 |
| 100 // |cachedItem| will point to the first item after the subsequence or end of
the current list. | 100 // |cachedItem| will point to the first item after the subsequence or end of
the current list. |
| 101 ensureNewDisplayItemListInitialCapacity(); | 101 ensureNewDisplayItemListInitialCapacity(); |
| 102 copyCachedSubsequence(cachedItem); | 102 copyCachedSubsequence(cachedItem); |
| 103 | 103 |
| 104 m_nextItemToMatch = cachedItem; | 104 m_nextItemToMatch = cachedItem; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 // The status will end after the new display items are committed. | 173 // The status will end after the new display items are committed. |
| 174 displayItem.client().beginShouldKeepAlive(this); | 174 displayItem.client().beginShouldKeepAlive(this); |
| 175 | 175 |
| 176 if (!m_currentSubsequenceClients.isEmpty()) { | 176 if (!m_currentSubsequenceClients.isEmpty()) { |
| 177 // Mark the client shouldKeepAlive under the current subsequence
. | 177 // Mark the client shouldKeepAlive under the current subsequence
. |
| 178 // The status will end when the subsequence owner is invalidated
or deleted. | 178 // The status will end when the subsequence owner is invalidated
or deleted. |
| 179 displayItem.client().beginShouldKeepAlive(m_currentSubsequenceCl
ients.last()); | 179 displayItem.client().beginShouldKeepAlive(m_currentSubsequenceCl
ients.last()); |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 if (displayItem.getType() == DisplayItem::Subsequence) { | 183 if (displayItem.getType() == DisplayItem::kSubsequence) { |
| 184 m_currentSubsequenceClients.append(&displayItem.client()); | 184 m_currentSubsequenceClients.append(&displayItem.client()); |
| 185 } else if (displayItem.getType() == DisplayItem::EndSubsequence) { | 185 } else if (displayItem.getType() == DisplayItem::kEndSubsequence) { |
| 186 CHECK(m_currentSubsequenceClients.last() == &displayItem.client()); | 186 CHECK(m_currentSubsequenceClients.last() == &displayItem.client()); |
| 187 m_currentSubsequenceClients.removeLast(); | 187 m_currentSubsequenceClients.removeLast(); |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 #endif | 190 #endif |
| 191 | 191 |
| 192 if (isSkippingCache()) { | 192 if (isSkippingCache()) { |
| 193 DCHECK(newItemSource == NewPainting); | 193 DCHECK(newItemSource == NewPainting); |
| 194 displayItem.setSkippedCache(); | 194 displayItem.setSkippedCache(); |
| 195 } | 195 } |
| 196 | 196 |
| 197 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 197 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 198 if (newItemSource != FromCachedSubsequence) | 198 if (newItemSource != FromCachedSubsequence) |
| 199 m_currentChunkIsFromCachedSubsequence = false; | 199 m_currentChunkIsFromCachedSubsequence = false; |
| 200 | 200 |
| 201 size_t lastChunkIndex = m_newPaintChunks.lastChunkIndex(); | 201 size_t lastChunkIndex = m_newPaintChunks.lastChunkIndex(); |
| 202 if (m_newPaintChunks.incrementDisplayItemIndex(displayItem)) { | 202 if (m_newPaintChunks.incrementDisplayItemIndex(displayItem)) { |
| 203 DCHECK(lastChunkIndex != m_newPaintChunks.lastChunkIndex()); | 203 DCHECK(lastChunkIndex != m_newPaintChunks.lastChunkIndex()); |
| 204 if (lastChunkIndex != kNotFound) | 204 if (lastChunkIndex != kNotFound) |
| 205 generateChunkRasterInvalidationRects(m_newPaintChunks.paintChunk
At(lastChunkIndex)); | 205 generateChunkRasterInvalidationRects(m_newPaintChunks.paintChunk
At(lastChunkIndex)); |
| 206 m_currentChunkIsFromCachedSubsequence = true; | 206 m_currentChunkIsFromCachedSubsequence = true; |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 | 209 |
| 210 #if DCHECK_IS_ON() | 210 #if DCHECK_IS_ON() |
| 211 // Verify noop begin/end pairs have been removed. | 211 // Verify noop begin/end pairs have been removed. |
| 212 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { | 212 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { |
| 213 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList
.size() - 2]; | 213 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList
.size() - 2]; |
| 214 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI
tem::Subsequence && !beginDisplayItem.drawsContent()) | 214 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI
tem::kSubsequence && !beginDisplayItem.drawsContent()) |
| 215 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); | 215 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); |
| 216 } | 216 } |
| 217 | 217 |
| 218 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt
emIndicesByClient, m_newDisplayItemList); | 218 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt
emIndicesByClient, m_newDisplayItemList); |
| 219 if (index != kNotFound) { | 219 if (index != kNotFound) { |
| 220 #ifndef NDEBUG | 220 #ifndef NDEBUG |
| 221 showDebugData(); | 221 showDebugData(); |
| 222 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", | 222 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", |
| 223 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde
x].asDebugString().utf8().data(), static_cast<int>(index)); | 223 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde
x].asDebugString().utf8().data(), static_cast<int>(index)); |
| 224 #endif | 224 #endif |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 } | 352 } |
| 353 | 353 |
| 354 // Copies a cached subsequence from current list to the new list. On return, | 354 // Copies a cached subsequence from current list to the new list. On return, |
| 355 // |cachedItemIndex| points to the item after the EndSubsequence item of the sub
sequence. | 355 // |cachedItemIndex| points to the item after the EndSubsequence item of the sub
sequence. |
| 356 // When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subs
equence, | 356 // When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subs
equence, |
| 357 // but mark the begin and end of the subsequence for under-invalidation checking
. | 357 // but mark the begin and end of the subsequence for under-invalidation checking
. |
| 358 void PaintController::copyCachedSubsequence(size_t& cachedItemIndex) | 358 void PaintController::copyCachedSubsequence(size_t& cachedItemIndex) |
| 359 { | 359 { |
| 360 DisplayItem* cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cache
dItemIndex]; | 360 DisplayItem* cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cache
dItemIndex]; |
| 361 #if DCHECK_IS_ON() | 361 #if DCHECK_IS_ON() |
| 362 DCHECK(cachedItem->getType() == DisplayItem::Subsequence); | 362 DCHECK(cachedItem->getType() == DisplayItem::kSubsequence); |
| 363 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ | 363 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ |
| 364 DCHECK(!isCheckingUnderInvalidation()); | 364 DCHECK(!isCheckingUnderInvalidation()); |
| 365 m_underInvalidationCheckingBegin = cachedItemIndex; | 365 m_underInvalidationCheckingBegin = cachedItemIndex; |
| 366 m_underInvalidationMessagePrefix = "(In cached subsequence of " + cached
Item->client().debugName() + ")"; | 366 m_underInvalidationMessagePrefix = "(In cached subsequence of " + cached
Item->client().debugName() + ")"; |
| 367 } | 367 } |
| 368 #endif | 368 #endif |
| 369 | 369 |
| 370 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::EndSubse
quence); | 370 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::kEndSubs
equence); |
| 371 Vector<PaintChunk>::const_iterator cachedChunk; | 371 Vector<PaintChunk>::const_iterator cachedChunk; |
| 372 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 372 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 373 cachedChunk = m_currentPaintArtifact.findChunkByDisplayItemIndex(cachedI
temIndex); | 373 cachedChunk = m_currentPaintArtifact.findChunkByDisplayItemIndex(cachedI
temIndex); |
| 374 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChunk->id :
nullptr, cachedChunk->properties); | 374 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChunk->id :
nullptr, cachedChunk->properties); |
| 375 } else { | 375 } else { |
| 376 // This is to avoid compilation error about uninitialized variable on Wi
ndows. | 376 // This is to avoid compilation error about uninitialized variable on Wi
ndows. |
| 377 cachedChunk = m_currentPaintArtifact.paintChunks().begin(); | 377 cachedChunk = m_currentPaintArtifact.paintChunks().begin(); |
| 378 } | 378 } |
| 379 | 379 |
| 380 while (true) { | 380 while (true) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 // Memory outside this class due to m_newDisplayItemList. | 521 // Memory outside this class due to m_newDisplayItemList. |
| 522 DCHECK(m_newDisplayItemList.isEmpty()); | 522 DCHECK(m_newDisplayItemList.isEmpty()); |
| 523 memoryUsage += m_newDisplayItemList.memoryUsageInBytes(); | 523 memoryUsage += m_newDisplayItemList.memoryUsageInBytes(); |
| 524 | 524 |
| 525 return memoryUsage; | 525 return memoryUsage; |
| 526 } | 526 } |
| 527 | 527 |
| 528 void PaintController::appendDebugDrawingAfterCommit(const DisplayItemClient& dis
playItemClient, PassRefPtr<SkPicture> picture, const LayoutSize& offsetFromLayou
tObject) | 528 void PaintController::appendDebugDrawingAfterCommit(const DisplayItemClient& dis
playItemClient, PassRefPtr<SkPicture> picture, const LayoutSize& offsetFromLayou
tObject) |
| 529 { | 529 { |
| 530 DCHECK(m_newDisplayItemList.isEmpty()); | 530 DCHECK(m_newDisplayItemList.isEmpty()); |
| 531 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList(
).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::Debug
Drawing, picture); | 531 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList(
).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::kDebu
gDrawing, picture); |
| 532 displayItem.setSkippedCache(); | 532 displayItem.setSkippedCache(); |
| 533 // TODO(wkorman): Only compute and append visual rect for drawings. | 533 // TODO(wkorman): Only compute and append visual rect for drawings. |
| 534 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi
splayItem(displayItem, offsetFromLayoutObject)); | 534 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi
splayItem(displayItem, offsetFromLayoutObject)); |
| 535 } | 535 } |
| 536 | 536 |
| 537 void PaintController::generateChunkRasterInvalidationRects(PaintChunk& newChunk) | 537 void PaintController::generateChunkRasterInvalidationRects(PaintChunk& newChunk) |
| 538 { | 538 { |
| 539 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 539 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 540 if (m_currentChunkIsFromCachedSubsequence) | 540 if (m_currentChunkIsFromCachedSubsequence) |
| 541 return; | 541 return; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 | 650 |
| 651 bool oldAndNewEqual = oldItem && newItem.equals(*oldItem); | 651 bool oldAndNewEqual = oldItem && newItem.equals(*oldItem); |
| 652 if (!oldAndNewEqual) { | 652 if (!oldAndNewEqual) { |
| 653 if (newItem.isBegin()) { | 653 if (newItem.isBegin()) { |
| 654 // Temporarily skip mismatching begin display item which may be remo
ved when we remove a no-op pair. | 654 // Temporarily skip mismatching begin display item which may be remo
ved when we remove a no-op pair. |
| 655 ++m_skippedProbableUnderInvalidationCount; | 655 ++m_skippedProbableUnderInvalidationCount; |
| 656 return; | 656 return; |
| 657 } | 657 } |
| 658 if (newItem.isDrawing() && m_skippedProbableUnderInvalidationCount == 1)
{ | 658 if (newItem.isDrawing() && m_skippedProbableUnderInvalidationCount == 1)
{ |
| 659 DCHECK_GE(m_newDisplayItemList.size(), 2u); | 659 DCHECK_GE(m_newDisplayItemList.size(), 2u); |
| 660 if (m_newDisplayItemList[m_newDisplayItemList.size() - 2].getType()
== DisplayItem::BeginCompositing) { | 660 if (m_newDisplayItemList[m_newDisplayItemList.size() - 2].getType()
== DisplayItem::kBeginCompositing) { |
| 661 // This might be a drawing item between a pair of begin/end comp
ositing display items that will be folded | 661 // This might be a drawing item between a pair of begin/end comp
ositing display items that will be folded |
| 662 // into a single drawing display item. | 662 // into a single drawing display item. |
| 663 ++m_skippedProbableUnderInvalidationCount; | 663 ++m_skippedProbableUnderInvalidationCount; |
| 664 return; | 664 return; |
| 665 } | 665 } |
| 666 } | 666 } |
| 667 } | 667 } |
| 668 | 668 |
| 669 if (m_skippedProbableUnderInvalidationCount || !oldAndNewEqual) { | 669 if (m_skippedProbableUnderInvalidationCount || !oldAndNewEqual) { |
| 670 // If we ever skipped reporting any under-invalidations, report the earl
iest one. | 670 // If we ever skipped reporting any under-invalidations, report the earl
iest one. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 return stringBuilder.toString(); | 722 return stringBuilder.toString(); |
| 723 } | 723 } |
| 724 | 724 |
| 725 void PaintController::showDebugData() const | 725 void PaintController::showDebugData() const |
| 726 { | 726 { |
| 727 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); | 727 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); |
| 728 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); | 728 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); |
| 729 } | 729 } |
| 730 | 730 |
| 731 } // namespace blink | 731 } // namespace blink |
| OLD | NEW |