| 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" |
| 11 #include "wtf/AutoReset.h" | 11 #include "wtf/AutoReset.h" |
| 12 #include "wtf/text/StringBuilder.h" | 12 #include "wtf/text/StringBuilder.h" |
| 13 | 13 |
| 14 #ifndef NDEBUG | 14 #ifndef NDEBUG |
| 15 #include "platform/graphics/LoggingCanvas.h" | 15 #include "platform/graphics/LoggingCanvas.h" |
| 16 #include <stdio.h> | 16 #include <stdio.h> |
| 17 #endif | 17 #endif |
| 18 | 18 |
| 19 namespace blink { | 19 namespace blink { |
| 20 | 20 |
| 21 void PaintController::setTracksRasterInvalidations(bool value) |
| 22 { |
| 23 if (value) |
| 24 m_paintChunksRasterInvalidationTrackingMap = wrapUnique(new RasterInvali
dationTrackingMap<const PaintChunk>); |
| 25 else |
| 26 m_paintChunksRasterInvalidationTrackingMap = nullptr; |
| 27 } |
| 28 |
| 29 |
| 21 const PaintArtifact& PaintController::paintArtifact() const | 30 const PaintArtifact& PaintController::paintArtifact() const |
| 22 { | 31 { |
| 23 DCHECK(m_newDisplayItemList.isEmpty()); | 32 DCHECK(m_newDisplayItemList.isEmpty()); |
| 24 DCHECK(m_newPaintChunks.isInInitialState()); | 33 DCHECK(m_newPaintChunks.isInInitialState()); |
| 25 return m_currentPaintArtifact; | 34 return m_currentPaintArtifact; |
| 26 } | 35 } |
| 27 | 36 |
| 28 bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client
, DisplayItem::Type type) | 37 bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client
, DisplayItem::Type type) |
| 29 { | 38 { |
| 30 DCHECK(DisplayItem::isDrawingType(type)); | 39 DCHECK(DisplayItem::isDrawingType(type)); |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 // TODO(wkorman): Only compute and append visual rect for drawings. | 540 // TODO(wkorman): Only compute and append visual rect for drawings. |
| 532 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi
splayItem(displayItem, offsetFromLayoutObject)); | 541 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi
splayItem(displayItem, offsetFromLayoutObject)); |
| 533 } | 542 } |
| 534 | 543 |
| 535 void PaintController::generateChunkRasterInvalidationRects(PaintChunk& newChunk) | 544 void PaintController::generateChunkRasterInvalidationRects(PaintChunk& newChunk) |
| 536 { | 545 { |
| 537 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 546 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 538 if (newChunk.beginIndex >= m_currentCachedSubsequenceBeginIndexInNewList) | 547 if (newChunk.beginIndex >= m_currentCachedSubsequenceBeginIndexInNewList) |
| 539 return; | 548 return; |
| 540 | 549 |
| 550 static FloatRect infiniteFloatRect(LayoutRect::infiniteIntRect()); |
| 541 if (!newChunk.id) { | 551 if (!newChunk.id) { |
| 542 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIn
tRect())); | 552 addRasterInvalidationInfo(nullptr, newChunk, infiniteFloatRect); |
| 543 return; | 553 return; |
| 544 } | 554 } |
| 545 | 555 |
| 546 // Try to match old chunk sequentially first. | 556 // Try to match old chunk sequentially first. |
| 547 const auto& oldChunks = m_currentPaintArtifact.paintChunks(); | 557 const auto& oldChunks = m_currentPaintArtifact.paintChunks(); |
| 548 while (m_nextChunkToMatch < oldChunks.size()) { | 558 while (m_nextChunkToMatch < oldChunks.size()) { |
| 549 const PaintChunk& oldChunk = oldChunks[m_nextChunkToMatch]; | 559 const PaintChunk& oldChunk = oldChunks[m_nextChunkToMatch]; |
| 550 if (newChunk.matches(oldChunk)) { | 560 if (newChunk.matches(oldChunk)) { |
| 551 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk, oldC
hunk); | 561 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk, oldC
hunk); |
| 552 ++m_nextChunkToMatch; | 562 ++m_nextChunkToMatch; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 568 if (it != m_outOfOrderChunkIndices.end()) { | 578 if (it != m_outOfOrderChunkIndices.end()) { |
| 569 for (size_t i : it->value) { | 579 for (size_t i : it->value) { |
| 570 if (newChunk.matches(oldChunks[i])) { | 580 if (newChunk.matches(oldChunks[i])) { |
| 571 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk,
oldChunks[i]); | 581 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk,
oldChunks[i]); |
| 572 return; | 582 return; |
| 573 } | 583 } |
| 574 } | 584 } |
| 575 } | 585 } |
| 576 | 586 |
| 577 // We reach here because the chunk is new. | 587 // We reach here because the chunk is new. |
| 578 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIntRec
t())); | 588 addRasterInvalidationInfo(nullptr, newChunk, infiniteFloatRect); |
| 589 } |
| 590 |
| 591 void PaintController::addRasterInvalidationInfo(const DisplayItemClient* client,
PaintChunk& chunk, const FloatRect& rect) |
| 592 { |
| 593 chunk.rasterInvalidationRects.append(rect); |
| 594 if (!m_paintChunksRasterInvalidationTrackingMap) |
| 595 return; |
| 596 |
| 597 RasterInvalidationInfo info; |
| 598 info.rect = enclosingIntRect(rect); |
| 599 info.client = client; |
| 600 if (client) { |
| 601 info.clientDebugName = client->debugName(); |
| 602 info.reason = client->getPaintInvalidationReason(); |
| 603 } |
| 604 |
| 605 RasterInvalidationTracking& tracking = m_paintChunksRasterInvalidationTracki
ngMap->add(&chunk); |
| 606 tracking.trackedRasterInvalidations.append(info); |
| 579 } | 607 } |
| 580 | 608 |
| 581 void PaintController::generateChunkRasterInvalidationRectsComparingOldChunk(Pain
tChunk& newChunk, const PaintChunk& oldChunk) | 609 void PaintController::generateChunkRasterInvalidationRectsComparingOldChunk(Pain
tChunk& newChunk, const PaintChunk& oldChunk) |
| 582 { | 610 { |
| 583 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 611 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 584 | 612 |
| 585 // TODO(wangxianzhu): Handle PaintInvalidationIncremental. | 613 // TODO(wangxianzhu): Handle PaintInvalidationIncremental. |
| 586 // TODO(wangxianzhu): Optimize paint offset change. | 614 // TODO(wangxianzhu): Optimize paint offset change. |
| 587 | 615 |
| 588 HashSet<const DisplayItemClient*> invalidatedClientsInOldChunk; | 616 HashSet<const DisplayItemClient*> invalidatedClientsInOldChunk; |
| 589 size_t highestMovedToIndex = 0; | 617 size_t highestMovedToIndex = 0; |
| 590 for (size_t oldIndex = oldChunk.beginIndex; oldIndex < oldChunk.endIndex; ++
oldIndex) { | 618 for (size_t oldIndex = oldChunk.beginIndex; oldIndex < oldChunk.endIndex; ++
oldIndex) { |
| 591 const DisplayItem& oldItem = m_currentPaintArtifact.getDisplayItemList()
[oldIndex]; | 619 const DisplayItem& oldItem = m_currentPaintArtifact.getDisplayItemList()
[oldIndex]; |
| 592 const DisplayItemClient* clientToInvalidate = nullptr; | 620 const DisplayItemClient* clientToInvalidate = nullptr; |
| 593 if (!oldItem.hasValidClient()) { | 621 if (!oldItem.hasValidClient()) { |
| 594 size_t movedToIndex = m_itemsMovedIntoNewList[oldIndex]; | 622 size_t movedToIndex = m_itemsMovedIntoNewList[oldIndex]; |
| 595 if (m_newDisplayItemList[movedToIndex].drawsContent()) { | 623 if (m_newDisplayItemList[movedToIndex].drawsContent()) { |
| 596 if (movedToIndex < newChunk.beginIndex || movedToIndex >= newChu
nk.endIndex) { | 624 if (movedToIndex < newChunk.beginIndex || movedToIndex >= newChu
nk.endIndex) { |
| 597 // The item has been moved into another chunk, so need to in
validate it in the old chunk. | 625 // The item has been moved into another chunk, so need to in
validate it in the old chunk. |
| 598 clientToInvalidate = &m_newDisplayItemList[movedToIndex].cli
ent(); | 626 clientToInvalidate = &m_newDisplayItemList[movedToIndex].cli
ent(); |
| 599 // And invalidate in the new chunk into which the item was m
oved. | 627 // And invalidate in the new chunk into which the item was m
oved. |
| 600 PaintChunk& movedToChunk = m_newPaintChunks.findChunkByDispl
ayItemIndex(movedToIndex); | 628 PaintChunk& movedToChunk = m_newPaintChunks.findChunkByDispl
ayItemIndex(movedToIndex); |
| 601 movedToChunk.rasterInvalidationRects.append(clientToInvalida
te->visualRect()); | 629 |
| 630 addRasterInvalidationInfo(clientToInvalidate, movedToChunk,
FloatRect(clientToInvalidate->visualRect())); |
| 602 } else if (movedToIndex < highestMovedToIndex) { | 631 } else if (movedToIndex < highestMovedToIndex) { |
| 603 // The item has been moved behind other cached items, so nee
d to invalidate the area | 632 // The item has been moved behind other cached items, so nee
d to invalidate the area |
| 604 // that is probably exposed by the item moved earlier. | 633 // that is probably exposed by the item moved earlier. |
| 605 clientToInvalidate = &m_newDisplayItemList[movedToIndex].cli
ent(); | 634 clientToInvalidate = &m_newDisplayItemList[movedToIndex].cli
ent(); |
| 606 } else { | 635 } else { |
| 607 highestMovedToIndex = movedToIndex; | 636 highestMovedToIndex = movedToIndex; |
| 608 } | 637 } |
| 609 } | 638 } |
| 610 } else if (oldItem.drawsContent()) { | 639 } else if (oldItem.drawsContent()) { |
| 611 clientToInvalidate = &oldItem.client(); | 640 clientToInvalidate = &oldItem.client(); |
| 612 } | 641 } |
| 613 if (clientToInvalidate && invalidatedClientsInOldChunk.add(clientToInval
idate).isNewEntry) { | 642 if (clientToInvalidate && invalidatedClientsInOldChunk.add(clientToInval
idate).isNewEntry) { |
| 614 newChunk.rasterInvalidationRects.append(m_currentPaintArtifact.getDi
splayItemList().visualRect(oldIndex)); | 643 addRasterInvalidationInfo(clientToInvalidate, newChunk, FloatRect(m_
currentPaintArtifact.getDisplayItemList().visualRect(oldIndex))); |
| 644 |
| 615 } | 645 } |
| 616 } | 646 } |
| 617 | 647 |
| 618 HashSet<const DisplayItemClient*> invalidatedClientsInNewChunk; | 648 HashSet<const DisplayItemClient*> invalidatedClientsInNewChunk; |
| 619 for (size_t newIndex = newChunk.beginIndex; newIndex < newChunk.endIndex; ++
newIndex) { | 649 for (size_t newIndex = newChunk.beginIndex; newIndex < newChunk.endIndex; ++
newIndex) { |
| 620 const DisplayItem& newItem = m_newDisplayItemList[newIndex]; | 650 const DisplayItem& newItem = m_newDisplayItemList[newIndex]; |
| 621 if (newItem.drawsContent() && !clientCacheIsValid(newItem.client()) && i
nvalidatedClientsInNewChunk.add(&newItem.client()).isNewEntry) | 651 if (newItem.drawsContent() && !clientCacheIsValid(newItem.client()) && i
nvalidatedClientsInNewChunk.add(&newItem.client()).isNewEntry) { |
| 622 newChunk.rasterInvalidationRects.append(newItem.client().visualRect(
)); | 652 addRasterInvalidationInfo(&newItem.client(), newChunk, FloatRect(new
Item.client().visualRect())); |
| 653 } |
| 623 } | 654 } |
| 624 } | 655 } |
| 625 | 656 |
| 626 void PaintController::showUnderInvalidationError(const char* reason, const Displ
ayItem& newItem, const DisplayItem* oldItem) const | 657 void PaintController::showUnderInvalidationError(const char* reason, const Displ
ayItem& newItem, const DisplayItem* oldItem) const |
| 627 { | 658 { |
| 628 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; | 659 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; |
| 629 #ifndef NDEBUG | 660 #ifndef NDEBUG |
| 630 LOG(ERROR) << "New display item: " << newItem.asDebugString(); | 661 LOG(ERROR) << "New display item: " << newItem.asDebugString(); |
| 631 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() :
"None"); | 662 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() :
"None"); |
| 632 #else | 663 #else |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 return stringBuilder.toString(); | 770 return stringBuilder.toString(); |
| 740 } | 771 } |
| 741 | 772 |
| 742 void PaintController::showDebugDataInternal(bool showPictures) const | 773 void PaintController::showDebugDataInternal(bool showPictures) const |
| 743 { | 774 { |
| 744 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList(), showPictures).utf8().data()); | 775 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.getDisplayItemList(), showPictures).utf8().data()); |
| 745 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList, showPictures).utf8().data()); | 776 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList, showPictures).utf8().data()); |
| 746 } | 777 } |
| 747 | 778 |
| 748 } // namespace blink | 779 } // namespace blink |
| OLD | NEW |