| 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 if (value) { |
| 23 m_paintChunksRasterInvalidationTrackingMap = |
| 24 wrapUnique(new RasterInvalidationTrackingMap<const PaintChunk>); |
| 25 } else { |
| 26 m_paintChunksRasterInvalidationTrackingMap = nullptr; |
| 27 } |
| 28 } |
| 29 |
| 21 const PaintArtifact& PaintController::paintArtifact() const { | 30 const PaintArtifact& PaintController::paintArtifact() const { |
| 22 DCHECK(m_newDisplayItemList.isEmpty()); | 31 DCHECK(m_newDisplayItemList.isEmpty()); |
| 23 DCHECK(m_newPaintChunks.isInInitialState()); | 32 DCHECK(m_newPaintChunks.isInInitialState()); |
| 24 return m_currentPaintArtifact; | 33 return m_currentPaintArtifact; |
| 25 } | 34 } |
| 26 | 35 |
| 27 bool PaintController::useCachedDrawingIfPossible( | 36 bool PaintController::useCachedDrawingIfPossible( |
| 28 const DisplayItemClient& client, | 37 const DisplayItemClient& client, |
| 29 DisplayItem::Type type) { | 38 DisplayItem::Type type) { |
| 30 DCHECK(DisplayItem::isDrawingType(type)); | 39 DCHECK(DisplayItem::isDrawingType(type)); |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 m_currentPaintArtifact.getDisplayItemList().appendVisualRect( | 591 m_currentPaintArtifact.getDisplayItemList().appendVisualRect( |
| 583 visualRectForDisplayItem(displayItem, offsetFromLayoutObject)); | 592 visualRectForDisplayItem(displayItem, offsetFromLayoutObject)); |
| 584 } | 593 } |
| 585 | 594 |
| 586 void PaintController::generateChunkRasterInvalidationRects( | 595 void PaintController::generateChunkRasterInvalidationRects( |
| 587 PaintChunk& newChunk) { | 596 PaintChunk& newChunk) { |
| 588 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 597 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 589 if (newChunk.beginIndex >= m_currentCachedSubsequenceBeginIndexInNewList) | 598 if (newChunk.beginIndex >= m_currentCachedSubsequenceBeginIndexInNewList) |
| 590 return; | 599 return; |
| 591 | 600 |
| 601 static FloatRect infiniteFloatRect(LayoutRect::infiniteIntRect()); |
| 592 if (!newChunk.id) { | 602 if (!newChunk.id) { |
| 593 newChunk.rasterInvalidationRects.append( | 603 addRasterInvalidationInfo(nullptr, newChunk, infiniteFloatRect); |
| 594 FloatRect(LayoutRect::infiniteIntRect())); | |
| 595 return; | 604 return; |
| 596 } | 605 } |
| 597 | 606 |
| 598 // Try to match old chunk sequentially first. | 607 // Try to match old chunk sequentially first. |
| 599 const auto& oldChunks = m_currentPaintArtifact.paintChunks(); | 608 const auto& oldChunks = m_currentPaintArtifact.paintChunks(); |
| 600 while (m_nextChunkToMatch < oldChunks.size()) { | 609 while (m_nextChunkToMatch < oldChunks.size()) { |
| 601 const PaintChunk& oldChunk = oldChunks[m_nextChunkToMatch]; | 610 const PaintChunk& oldChunk = oldChunks[m_nextChunkToMatch]; |
| 602 if (newChunk.matches(oldChunk)) { | 611 if (newChunk.matches(oldChunk)) { |
| 603 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk, oldChunk); | 612 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk, oldChunk); |
| 604 ++m_nextChunkToMatch; | 613 ++m_nextChunkToMatch; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 625 for (size_t i : it->value) { | 634 for (size_t i : it->value) { |
| 626 if (newChunk.matches(oldChunks[i])) { | 635 if (newChunk.matches(oldChunks[i])) { |
| 627 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk, | 636 generateChunkRasterInvalidationRectsComparingOldChunk(newChunk, |
| 628 oldChunks[i]); | 637 oldChunks[i]); |
| 629 return; | 638 return; |
| 630 } | 639 } |
| 631 } | 640 } |
| 632 } | 641 } |
| 633 | 642 |
| 634 // We reach here because the chunk is new. | 643 // We reach here because the chunk is new. |
| 635 newChunk.rasterInvalidationRects.append( | 644 addRasterInvalidationInfo(nullptr, newChunk, infiniteFloatRect); |
| 636 FloatRect(LayoutRect::infiniteIntRect())); | 645 } |
| 646 |
| 647 void PaintController::addRasterInvalidationInfo(const DisplayItemClient* client, |
| 648 PaintChunk& chunk, |
| 649 const FloatRect& rect) { |
| 650 chunk.rasterInvalidationRects.append(rect); |
| 651 if (!m_paintChunksRasterInvalidationTrackingMap) |
| 652 return; |
| 653 RasterInvalidationInfo info; |
| 654 info.rect = enclosingIntRect(rect); |
| 655 info.client = client; |
| 656 if (client) { |
| 657 info.clientDebugName = client->debugName(); |
| 658 info.reason = client->getPaintInvalidationReason(); |
| 659 } |
| 660 RasterInvalidationTracking& tracking = |
| 661 m_paintChunksRasterInvalidationTrackingMap->add(&chunk); |
| 662 tracking.trackedRasterInvalidations.append(info); |
| 637 } | 663 } |
| 638 | 664 |
| 639 void PaintController::generateChunkRasterInvalidationRectsComparingOldChunk( | 665 void PaintController::generateChunkRasterInvalidationRectsComparingOldChunk( |
| 640 PaintChunk& newChunk, | 666 PaintChunk& newChunk, |
| 641 const PaintChunk& oldChunk) { | 667 const PaintChunk& oldChunk) { |
| 642 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 668 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 643 | 669 |
| 644 // TODO(wangxianzhu): Handle PaintInvalidationIncremental. | 670 // TODO(wangxianzhu): Handle PaintInvalidationIncremental. |
| 645 // TODO(wangxianzhu): Optimize paint offset change. | 671 // TODO(wangxianzhu): Optimize paint offset change. |
| 646 | 672 |
| 647 HashSet<const DisplayItemClient*> invalidatedClientsInOldChunk; | 673 HashSet<const DisplayItemClient*> invalidatedClientsInOldChunk; |
| 648 size_t highestMovedToIndex = 0; | 674 size_t highestMovedToIndex = 0; |
| 649 for (size_t oldIndex = oldChunk.beginIndex; oldIndex < oldChunk.endIndex; | 675 for (size_t oldIndex = oldChunk.beginIndex; oldIndex < oldChunk.endIndex; |
| 650 ++oldIndex) { | 676 ++oldIndex) { |
| 651 const DisplayItem& oldItem = | 677 const DisplayItem& oldItem = |
| 652 m_currentPaintArtifact.getDisplayItemList()[oldIndex]; | 678 m_currentPaintArtifact.getDisplayItemList()[oldIndex]; |
| 653 const DisplayItemClient* clientToInvalidate = nullptr; | 679 const DisplayItemClient* clientToInvalidate = nullptr; |
| 680 bool isPotentiallyInvalidClient = false; |
| 654 if (!oldItem.hasValidClient()) { | 681 if (!oldItem.hasValidClient()) { |
| 655 size_t movedToIndex = m_itemsMovedIntoNewList[oldIndex]; | 682 size_t movedToIndex = m_itemsMovedIntoNewList[oldIndex]; |
| 656 if (m_newDisplayItemList[movedToIndex].drawsContent()) { | 683 if (m_newDisplayItemList[movedToIndex].drawsContent()) { |
| 657 if (movedToIndex < newChunk.beginIndex || | 684 if (movedToIndex < newChunk.beginIndex || |
| 658 movedToIndex >= newChunk.endIndex) { | 685 movedToIndex >= newChunk.endIndex) { |
| 659 // The item has been moved into another chunk, so need to invalidate i
t in the old chunk. | 686 // The item has been moved into another chunk, so need to invalidate i
t in the old chunk. |
| 660 clientToInvalidate = &m_newDisplayItemList[movedToIndex].client(); | 687 clientToInvalidate = &m_newDisplayItemList[movedToIndex].client(); |
| 661 // And invalidate in the new chunk into which the item was moved. | 688 // And invalidate in the new chunk into which the item was moved. |
| 662 PaintChunk& movedToChunk = | 689 PaintChunk& movedToChunk = |
| 663 m_newPaintChunks.findChunkByDisplayItemIndex(movedToIndex); | 690 m_newPaintChunks.findChunkByDisplayItemIndex(movedToIndex); |
| 664 movedToChunk.rasterInvalidationRects.append( | 691 addRasterInvalidationInfo( |
| 665 clientToInvalidate->visualRect()); | 692 clientToInvalidate, movedToChunk, |
| 693 FloatRect(clientToInvalidate->visualRect())); |
| 666 } else if (movedToIndex < highestMovedToIndex) { | 694 } else if (movedToIndex < highestMovedToIndex) { |
| 667 // The item has been moved behind other cached items, so need to inval
idate the area | 695 // The item has been moved behind other cached items, so need to inval
idate the area |
| 668 // that is probably exposed by the item moved earlier. | 696 // that is probably exposed by the item moved earlier. |
| 669 clientToInvalidate = &m_newDisplayItemList[movedToIndex].client(); | 697 clientToInvalidate = &m_newDisplayItemList[movedToIndex].client(); |
| 670 } else { | 698 } else { |
| 671 highestMovedToIndex = movedToIndex; | 699 highestMovedToIndex = movedToIndex; |
| 672 } | 700 } |
| 673 } | 701 } |
| 674 } else if (oldItem.drawsContent()) { | 702 } else if (oldItem.drawsContent()) { |
| 703 isPotentiallyInvalidClient = true; |
| 675 clientToInvalidate = &oldItem.client(); | 704 clientToInvalidate = &oldItem.client(); |
| 676 } | 705 } |
| 677 if (clientToInvalidate && | 706 if (clientToInvalidate && |
| 678 invalidatedClientsInOldChunk.add(clientToInvalidate).isNewEntry) { | 707 invalidatedClientsInOldChunk.add(clientToInvalidate).isNewEntry) { |
| 679 newChunk.rasterInvalidationRects.append( | 708 addRasterInvalidationInfo( |
| 680 m_currentPaintArtifact.getDisplayItemList().visualRect(oldIndex)); | 709 isPotentiallyInvalidClient ? nullptr : clientToInvalidate, newChunk, |
| 710 FloatRect(m_currentPaintArtifact.getDisplayItemList().visualRect( |
| 711 oldIndex))); |
| 681 } | 712 } |
| 682 } | 713 } |
| 683 | 714 |
| 684 HashSet<const DisplayItemClient*> invalidatedClientsInNewChunk; | 715 HashSet<const DisplayItemClient*> invalidatedClientsInNewChunk; |
| 685 for (size_t newIndex = newChunk.beginIndex; newIndex < newChunk.endIndex; | 716 for (size_t newIndex = newChunk.beginIndex; newIndex < newChunk.endIndex; |
| 686 ++newIndex) { | 717 ++newIndex) { |
| 687 const DisplayItem& newItem = m_newDisplayItemList[newIndex]; | 718 const DisplayItem& newItem = m_newDisplayItemList[newIndex]; |
| 688 if (newItem.drawsContent() && !clientCacheIsValid(newItem.client()) && | 719 if (newItem.drawsContent() && !clientCacheIsValid(newItem.client()) && |
| 689 invalidatedClientsInNewChunk.add(&newItem.client()).isNewEntry) | 720 invalidatedClientsInNewChunk.add(&newItem.client()).isNewEntry) { |
| 690 newChunk.rasterInvalidationRects.append(newItem.client().visualRect()); | 721 addRasterInvalidationInfo(&newItem.client(), newChunk, |
| 722 FloatRect(newItem.client().visualRect())); |
| 723 } |
| 691 } | 724 } |
| 692 } | 725 } |
| 693 | 726 |
| 694 void PaintController::showUnderInvalidationError( | 727 void PaintController::showUnderInvalidationError( |
| 695 const char* reason, | 728 const char* reason, |
| 696 const DisplayItem& newItem, | 729 const DisplayItem& newItem, |
| 697 const DisplayItem* oldItem) const { | 730 const DisplayItem* oldItem) const { |
| 698 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; | 731 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; |
| 699 #ifndef NDEBUG | 732 #ifndef NDEBUG |
| 700 LOG(ERROR) << "New display item: " << newItem.asDebugString(); | 733 LOG(ERROR) << "New display item: " << newItem.asDebugString(); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 m_currentPaintArtifact.getDisplayItemList(), showPictures) | 869 m_currentPaintArtifact.getDisplayItemList(), showPictures) |
| 837 .utf8() | 870 .utf8() |
| 838 .data()); | 871 .data()); |
| 839 WTFLogAlways("new display item list: [%s]\n", | 872 WTFLogAlways("new display item list: [%s]\n", |
| 840 displayItemListAsDebugString(m_newDisplayItemList, showPictures) | 873 displayItemListAsDebugString(m_newDisplayItemList, showPictures) |
| 841 .utf8() | 874 .utf8() |
| 842 .data()); | 875 .data()); |
| 843 } | 876 } |
| 844 | 877 |
| 845 } // namespace blink | 878 } // namespace blink |
| OLD | NEW |