| 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 #ifndef PaintController_h | 5 #ifndef PaintController_h |
| 6 #define PaintController_h | 6 #define PaintController_h |
| 7 | 7 |
| 8 #include "platform/PlatformExport.h" | 8 #include "platform/PlatformExport.h" |
| 9 #include "platform/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
| 10 #include "platform/geometry/IntRect.h" | 10 #include "platform/geometry/IntRect.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 template <typename DisplayItemClass, typename... Args> | 68 template <typename DisplayItemClass, typename... Args> |
| 69 void createAndAppend(Args&&... args) | 69 void createAndAppend(Args&&... args) |
| 70 { | 70 { |
| 71 static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, | 71 static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, |
| 72 "Can only createAndAppend subclasses of DisplayItem."); | 72 "Can only createAndAppend subclasses of DisplayItem."); |
| 73 static_assert(sizeof(DisplayItemClass) <= kMaximumDisplayItemSize, | 73 static_assert(sizeof(DisplayItemClass) <= kMaximumDisplayItemSize, |
| 74 "DisplayItem subclass is larger than kMaximumDisplayItemSize."); | 74 "DisplayItem subclass is larger than kMaximumDisplayItemSize."); |
| 75 | 75 |
| 76 if (displayItemConstructionIsDisabled()) | 76 if (displayItemConstructionIsDisabled()) |
| 77 return; | 77 return; |
| 78 |
| 79 ensureNewDisplayItemListInitialCapacity(); |
| 78 DisplayItemClass& displayItem = m_newDisplayItemList.allocateAndConstruc
t<DisplayItemClass>(std::forward<Args>(args)...); | 80 DisplayItemClass& displayItem = m_newDisplayItemList.allocateAndConstruc
t<DisplayItemClass>(std::forward<Args>(args)...); |
| 79 processNewItem(displayItem); | 81 processNewItem(displayItem); |
| 80 } | 82 } |
| 81 | 83 |
| 82 // Creates and appends an ending display item to pair with a preceding | 84 // Creates and appends an ending display item to pair with a preceding |
| 83 // beginning item iff the display item actually draws content. For no-op | 85 // beginning item iff the display item actually draws content. For no-op |
| 84 // items, rather than creating an ending item, the begin item will | 86 // items, rather than creating an ending item, the begin item will |
| 85 // instead be removed, thereby maintaining brevity of the list. If display | 87 // instead be removed, thereby maintaining brevity of the list. If display |
| 86 // item construction is disabled, no list mutations will be performed. | 88 // item construction is disabled, no list mutations will be performed. |
| 87 template <typename DisplayItemClass, typename... Args> | 89 template <typename DisplayItemClass, typename... Args> |
| 88 void endItem(Args&&... args) | 90 void endItem(Args&&... args) |
| 89 { | 91 { |
| 90 if (displayItemConstructionIsDisabled()) | 92 if (displayItemConstructionIsDisabled()) |
| 91 return; | 93 return; |
| 92 if (lastDisplayItemIsNoopBegin()) | 94 if (lastDisplayItemIsNoopBegin()) |
| 93 removeLastDisplayItem(); | 95 removeLastDisplayItem(); |
| 94 else | 96 else |
| 95 createAndAppend<DisplayItemClass>(std::forward<Args>(args)...); | 97 createAndAppend<DisplayItemClass>(std::forward<Args>(args)...); |
| 96 } | 98 } |
| 97 | 99 |
| 100 // Tries to find the cached drawing display item corresponding to the given
parameters. If found, |
| 101 // appends the cached display item to the new display list and returns true.
Otherwise returns false. |
| 102 bool useCachedDrawingIfPossible(const DisplayItemClient&, DisplayItem::Type)
; |
| 103 |
| 104 // Tries to find the cached subsequence corresponding to the given parameter
s. If found, copies the |
| 105 // cache subsequence to the new display list and returns true. Otherwise ret
urns false. |
| 106 bool useCachedSubsequenceIfPossible(const DisplayItemClient&); |
| 107 |
| 98 // True if the last display item is a begin that doesn't draw content. | 108 // True if the last display item is a begin that doesn't draw content. |
| 99 bool lastDisplayItemIsNoopBegin() const; | 109 bool lastDisplayItemIsNoopBegin() const; |
| 100 void removeLastDisplayItem(); | 110 void removeLastDisplayItem(); |
| 101 | 111 |
| 102 void beginSkippingCache() { ++m_skippingCacheCount; } | 112 void beginSkippingCache() { ++m_skippingCacheCount; } |
| 103 void endSkippingCache() { DCHECK(m_skippingCacheCount > 0); --m_skippingCach
eCount; } | 113 void endSkippingCache() { DCHECK(m_skippingCacheCount > 0); --m_skippingCach
eCount; } |
| 104 bool skippingCache() const { return m_skippingCacheCount; } | 114 bool skippingCache() const { return m_skippingCacheCount; } |
| 105 | 115 |
| 106 // Must be called when a painting is finished. | 116 // Must be called when a painting is finished. |
| 107 // offsetFromLayoutObject is the offset between the space of the GraphicsLay
er which owns this | 117 // offsetFromLayoutObject is the offset between the space of the GraphicsLay
er which owns this |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 #ifndef NDEBUG | 151 #ifndef NDEBUG |
| 142 void showDebugData() const; | 152 void showDebugData() const; |
| 143 #endif | 153 #endif |
| 144 | 154 |
| 145 #if DCHECK_IS_ON() | 155 #if DCHECK_IS_ON() |
| 146 void assertDisplayItemClientsAreLive(); | 156 void assertDisplayItemClientsAreLive(); |
| 147 #endif | 157 #endif |
| 148 | 158 |
| 149 protected: | 159 protected: |
| 150 PaintController() | 160 PaintController() |
| 151 : m_newDisplayItemList(kInitialDisplayItemListCapacityBytes) | 161 : m_newDisplayItemList(0) |
| 152 , m_constructionDisabled(false) | 162 , m_constructionDisabled(false) |
| 153 , m_subsequenceCachingDisabled(false) | 163 , m_subsequenceCachingDisabled(false) |
| 154 , m_textPainted(false) | 164 , m_textPainted(false) |
| 155 , m_imagePainted(false) | 165 , m_imagePainted(false) |
| 156 , m_skippingCacheCount(0) | 166 , m_skippingCacheCount(0) |
| 157 , m_numCachedNewItems(0) | 167 , m_numCachedNewItems(0) |
| 158 { } | 168 #if DCHECK_IS_ON() |
| 169 , m_numSequentialMatches(0) |
| 170 , m_numOutOfOrderMatches(0) |
| 171 , m_numIndexedItems(0) |
| 172 #endif |
| 173 { |
| 174 resetCurrentListIterators(); |
| 175 } |
| 159 | 176 |
| 160 private: | 177 private: |
| 178 friend class PaintControllerTest; |
| 179 friend class PaintControllerPaintTestBase; |
| 180 |
| 181 void ensureNewDisplayItemListInitialCapacity() |
| 182 { |
| 183 if (m_newDisplayItemList.isEmpty()) { |
| 184 // TODO(wangxianzhu): Consider revisiting this heuristic. |
| 185 m_newDisplayItemList = DisplayItemList(m_currentPaintArtifact.getDis
playItemList().isEmpty() ? kInitialDisplayItemListCapacityBytes : m_currentPaint
Artifact.getDisplayItemList().usedCapacityInBytes()); |
| 186 } |
| 187 } |
| 188 |
| 161 // Set new item state (cache skipping, etc) for a new item. | 189 // Set new item state (cache skipping, etc) for a new item. |
| 162 void processNewItem(DisplayItem&); | 190 void processNewItem(DisplayItem&); |
| 163 | 191 |
| 164 #ifndef NDEBUG | 192 #ifndef NDEBUG |
| 165 WTF::String displayItemListAsDebugString(const DisplayItemList&) const; | 193 WTF::String displayItemListAsDebugString(const DisplayItemList&) const; |
| 166 #endif | 194 #endif |
| 167 | 195 |
| 168 // Indices into PaintList of all DrawingDisplayItems and BeginSubsequenceDis
playItems of each client. | 196 // Indices into PaintList of all DrawingDisplayItems and BeginSubsequenceDis
playItems of each client. |
| 169 // Temporarily used during merge to find out-of-order display items. | 197 // Temporarily used during merge to find out-of-order display items. |
| 170 using DisplayItemIndicesByClientMap = HashMap<const DisplayItemClient*, Vect
or<size_t>>; | 198 using DisplayItemIndicesByClientMap = HashMap<const DisplayItemClient*, Vect
or<size_t>>; |
| 171 | 199 |
| 172 static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const Displa
yItemIndicesByClientMap&, const DisplayItemList&); | 200 static size_t findMatchingItemFromIndex(const DisplayItem::Id&, const Displa
yItemIndicesByClientMap&, const DisplayItemList&); |
| 173 static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, Display
ItemIndicesByClientMap&); | 201 static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, Display
ItemIndicesByClientMap&); |
| 174 | 202 |
| 175 struct OutOfOrderIndexContext; | 203 DisplayItemList::iterator findCachedItem(const DisplayItem::Id&); |
| 176 DisplayItemList::iterator findOutOfOrderCachedItem(const DisplayItem::Id&, O
utOfOrderIndexContext&); | 204 DisplayItemList::iterator findOutOfOrderCachedItemForward(const DisplayItem:
:Id&); |
| 177 DisplayItemList::iterator findOutOfOrderCachedItemForward(const DisplayItem:
:Id&, OutOfOrderIndexContext&); | 205 void copyCachedSubsequence(DisplayItemList::iterator&); |
| 178 void copyCachedSubsequence(const DisplayItemList& currentList, DisplayItemLi
st::iterator& currentIt, DisplayItemList& updatedList, SkPictureGpuAnalyzer&); | 206 |
| 207 // Resets the iterators (e.g. m_nextItemToMatch) of m_currentPaintArtifact.g
etDisplayItemList() |
| 208 // to their initial values. This should be called when the DisplayItemList i
n m_currentPaintArtifact |
| 209 // is newly created, or is changed causing the previous iterators to be inva
lid. |
| 210 void resetCurrentListIterators(); |
| 179 | 211 |
| 180 #if DCHECK_IS_ON() | 212 #if DCHECK_IS_ON() |
| 181 // The following two methods are for checking under-invalidations | 213 // The following two methods are for checking under-invalidations |
| 182 // (when RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabl
ed). | 214 // (when RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabl
ed). |
| 183 void checkUnderInvalidation(DisplayItemList::iterator& newIt, DisplayItemLis
t::iterator& currentIt); | 215 void checkUnderInvalidation(DisplayItemList::iterator& newIt, DisplayItemLis
t::iterator& currentIt); |
| 184 void checkCachedDisplayItemIsUnchanged(const char* messagePrefix, const Disp
layItem& newItem, const DisplayItem& oldItem); | 216 void checkCachedDisplayItemIsUnchanged(const char* messagePrefix, const Disp
layItem& newItem, const DisplayItem& oldItem); |
| 185 #endif | 217 #endif |
| 186 | 218 |
| 187 void updateCacheGeneration(); | |
| 188 | |
| 189 // The last complete paint artifact. | 219 // The last complete paint artifact. |
| 190 // In SPv2, this includes paint chunks as well as display items. | 220 // In SPv2, this includes paint chunks as well as display items. |
| 191 PaintArtifact m_currentPaintArtifact; | 221 PaintArtifact m_currentPaintArtifact; |
| 192 | 222 |
| 193 // Data being used to build the next paint artifact. | 223 // Data being used to build the next paint artifact. |
| 194 DisplayItemList m_newDisplayItemList; | 224 DisplayItemList m_newDisplayItemList; |
| 195 PaintChunker m_newPaintChunks; | 225 PaintChunker m_newPaintChunks; |
| 196 | 226 |
| 197 // Allow display item construction to be disabled to isolate the costs of co
nstruction | 227 // Allow display item construction to be disabled to isolate the costs of co
nstruction |
| 198 // in performance metrics. | 228 // in performance metrics. |
| 199 bool m_constructionDisabled; | 229 bool m_constructionDisabled; |
| 200 | 230 |
| 201 // Allow subsequence caching to be disabled to test the cost of display item
caching. | 231 // Allow subsequence caching to be disabled to test the cost of display item
caching. |
| 202 bool m_subsequenceCachingDisabled; | 232 bool m_subsequenceCachingDisabled; |
| 203 | 233 |
| 204 // Indicates this PaintController has ever had text. It is never reset to fa
lse. | 234 // Indicates this PaintController has ever had text. It is never reset to fa
lse. |
| 205 bool m_textPainted; | 235 bool m_textPainted; |
| 206 bool m_imagePainted; | 236 bool m_imagePainted; |
| 207 | 237 |
| 208 int m_skippingCacheCount; | 238 int m_skippingCacheCount; |
| 209 | 239 |
| 210 int m_numCachedNewItems; | 240 int m_numCachedNewItems; |
| 211 | 241 |
| 242 // Stores indices to valid DrawingDisplayItems in current display list that
have not been |
| 243 // matched by CachedDisplayItems during sequential matching. The indexed ite
ms will be |
| 244 // matched by later out-of-order requests of cached display items. This ensu
res that when |
| 245 // out-of-order cached display items are requested, we only traverse at most
once over |
| 246 // the current display list looking for potential matches. Thus we can ensur
e that the |
| 247 // algorithm runs in linear time. |
| 248 DisplayItemIndicesByClientMap m_outOfOrderItemIndices; |
| 249 |
| 250 // The next item in the current list for sequential match. |
| 251 DisplayItemList::iterator m_nextItemToMatch; |
| 252 |
| 253 // The next item in the current list to be indexed for out-of-order cache re
quests. |
| 254 DisplayItemList::iterator m_nextItemToIndex; |
| 255 |
| 256 DisplayItemClient::CacheGenerationOrInvalidationReason m_currentCacheGenerat
ion; |
| 257 |
| 212 #if DCHECK_IS_ON() | 258 #if DCHECK_IS_ON() |
| 213 // This is used to check duplicated ids during add(). We could also check | 259 int m_numSequentialMatches; |
| 214 // during commitNewDisplayItems(), but checking during add() helps developer | 260 int m_numOutOfOrderMatches; |
| 215 // easily find where the duplicated ids are from. | 261 int m_numIndexedItems; |
| 262 |
| 263 // This is used to check duplicated ids during createAndAppend(). |
| 216 DisplayItemIndicesByClientMap m_newDisplayItemIndicesByClient; | 264 DisplayItemIndicesByClientMap m_newDisplayItemIndicesByClient; |
| 217 #endif | 265 #endif |
| 218 | 266 |
| 219 DisplayItemClient::CacheGenerationOrInvalidationReason m_currentCacheGenerat
ion; | |
| 220 | |
| 221 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 267 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
| 222 // A stack recording subsequence clients that are currently painting. | 268 // A stack recording subsequence clients that are currently painting. |
| 223 Vector<const DisplayItemClient*> m_currentSubsequenceClients; | 269 Vector<const DisplayItemClient*> m_currentSubsequenceClients; |
| 224 #endif | 270 #endif |
| 225 }; | 271 }; |
| 226 | 272 |
| 227 } // namespace blink | 273 } // namespace blink |
| 228 | 274 |
| 229 #endif // PaintController_h | 275 #endif // PaintController_h |
| OLD | NEW |