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 |