Index: third_party/WebKit/Source/platform/graphics/paint/PaintController.h |
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h |
index fd1d11f42b68261d93e692d247cbd0d5bf5a7a6d..de0e2f05f23668dd55a529f758bb28d9cfdbcd1f 100644 |
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h |
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h |
@@ -75,6 +75,8 @@ public: |
if (displayItemConstructionIsDisabled()) |
return; |
+ |
+ ensureNewDisplayItemListInitialCapacity(); |
DisplayItemClass& displayItem = m_newDisplayItemList.allocateAndConstruct<DisplayItemClass>(std::forward<Args>(args)...); |
processNewItem(displayItem); |
} |
@@ -95,6 +97,14 @@ public: |
createAndAppend<DisplayItemClass>(std::forward<Args>(args)...); |
} |
+ // Try to find the cached drawing display item corresponding to the given parameters. If found, |
+ // append the cached display item to the new display list and return true. Otherwise return false. |
+ bool useCachedDrawingIfPossible(const DisplayItemClient&, DisplayItem::Type); |
+ |
+ // Try to find the cached subsequence corresponding to the given parameters. If found, copy the |
+ // cache subsequence to the new display list and return true. Otherwise return false. |
+ bool useCachedSubsequenceIfPossible(const DisplayItemClient&); |
+ |
// True if the last display item is a begin that doesn't draw content. |
bool lastDisplayItemIsNoopBegin() const; |
void removeLastDisplayItem(); |
@@ -148,16 +158,34 @@ public: |
protected: |
PaintController() |
- : m_newDisplayItemList(kInitialDisplayItemListCapacityBytes) |
+ : m_newDisplayItemList(0) |
, m_constructionDisabled(false) |
, m_subsequenceCachingDisabled(false) |
, m_textPainted(false) |
, m_imagePainted(false) |
, m_skippingCacheCount(0) |
, m_numCachedNewItems(0) |
- { } |
+#if DCHECK_IS_ON() |
+ , m_numSequentialMatches(0) |
+ , m_numOutOfOrderMatches(0) |
+ , m_numIndexedItems(0) |
+#endif |
+ { |
+ resetCurrentListIterators(); |
+ } |
private: |
+ friend class PaintControllerTest; |
+ friend class PaintControllerPaintTestBase; |
+ |
+ void ensureNewDisplayItemListInitialCapacity() |
+ { |
+ if (m_newDisplayItemList.isEmpty()) { |
+ // TODO(wangxianzhu): Consider revisiting this heuristic. |
+ m_newDisplayItemList = DisplayItemList(m_currentPaintArtifact.getDisplayItemList().isEmpty() ? kInitialDisplayItemListCapacityBytes : m_currentPaintArtifact.getDisplayItemList().usedCapacityInBytes()); |
+ } |
+ } |
+ |
// Set new item state (cache skipping, etc) for a new item. |
void processNewItem(DisplayItem&); |
@@ -172,10 +200,11 @@ private: |
static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const DisplayItemIndicesByClientMap&, const DisplayItemList&); |
static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, DisplayItemIndicesByClientMap&); |
- struct OutOfOrderIndexContext; |
- DisplayItemList::iterator findOutOfOrderCachedItem(const DisplayItem::Id&, OutOfOrderIndexContext&); |
- DisplayItemList::iterator findOutOfOrderCachedItemForward(const DisplayItem::Id&, OutOfOrderIndexContext&); |
- void copyCachedSubsequence(const DisplayItemList& currentList, DisplayItemList::iterator& currentIt, DisplayItemList& updatedList, SkPictureGpuAnalyzer&); |
+ DisplayItemList::iterator findCachedItem(const DisplayItem::Id&); |
+ DisplayItemList::iterator findOutOfOrderCachedItemForward(const DisplayItem::Id&); |
+ void copyCachedSubsequence(DisplayItemList::iterator&); |
+ |
+ void resetCurrentListIterators(); |
jbroman
2016/07/06 19:09:38
Comment? It's not obvious to me what the "current
Xianzhu
2016/07/06 19:29:34
Done.
|
#if DCHECK_IS_ON() |
// The following two methods are for checking under-invalidations |
@@ -184,8 +213,6 @@ private: |
void checkCachedDisplayItemIsUnchanged(const char* messagePrefix, const DisplayItem& newItem, const DisplayItem& oldItem); |
#endif |
- void updateCacheGeneration(); |
- |
// The last complete paint artifact. |
// In SPv2, this includes paint chunks as well as display items. |
PaintArtifact m_currentPaintArtifact; |
@@ -209,15 +236,31 @@ private: |
int m_numCachedNewItems; |
+ // Stores indices to valid DrawingDisplayItems in current display list that have not been |
+ // matched by CachedDisplayItems during sequential matching. The indexed items will be |
+ // matched by later out-of-order requests of cached display items. This ensures that when |
+ // out-of-order cached display items are requested, we only traverse at most once over |
+ // the current display list looking for potential matches. Thus we can ensure that the |
+ // algorithm runs in linear time. |
+ DisplayItemIndicesByClientMap m_outOfOrderItemIndices; |
+ |
+ // The next item in the current list for sequential match. |
+ DisplayItemList::iterator m_nextItemToMatch; |
+ |
+ // The next item in the current list to be indexed for out-of-order cache requests. |
+ DisplayItemList::iterator m_nextItemToIndex; |
+ |
+ DisplayItemClient::CacheGenerationOrInvalidationReason m_currentCacheGeneration; |
+ |
#if DCHECK_IS_ON() |
- // This is used to check duplicated ids during add(). We could also check |
- // during commitNewDisplayItems(), but checking during add() helps developer |
- // easily find where the duplicated ids are from. |
+ int m_numSequentialMatches; |
+ int m_numOutOfOrderMatches; |
+ int m_numIndexedItems; |
+ |
+ // This is used to check duplicated ids during createAndAppend(). |
DisplayItemIndicesByClientMap m_newDisplayItemIndicesByClient; |
#endif |
- DisplayItemClient::CacheGenerationOrInvalidationReason m_currentCacheGeneration; |
- |
#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
// A stack recording subsequence clients that are currently painting. |
Vector<const DisplayItemClient*> m_currentSubsequenceClients; |