Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp

Issue 1978313003: Reland of Client side display item cache flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ScrollbarTheme
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 11
12 #ifndef NDEBUG 12 #ifndef NDEBUG
13 #include "platform/graphics/LoggingCanvas.h" 13 #include "platform/graphics/LoggingCanvas.h"
14 #include "wtf/text/StringBuilder.h" 14 #include "wtf/text/StringBuilder.h"
15 #include <stdio.h> 15 #include <stdio.h>
16 #endif 16 #endif
17 17
18 namespace blink { 18 namespace blink {
19 19
20 static PaintChunker::ItemBehavior behaviorOfItemType(DisplayItem::Type type) 20 static PaintChunker::ItemBehavior behaviorOfItemType(DisplayItem::Type type)
21 { 21 {
22 if (DisplayItem::isForeignLayerType(type)) 22 if (DisplayItem::isForeignLayerType(type))
23 return PaintChunker::RequiresSeparateChunk; 23 return PaintChunker::RequiresSeparateChunk;
24 return PaintChunker::DefaultBehavior; 24 return PaintChunker::DefaultBehavior;
25 } 25 }
26 26
27 const PaintArtifact& PaintController::paintArtifact() const 27 const PaintArtifact& PaintController::paintArtifact() const
28 { 28 {
29 ASSERT(m_newDisplayItemList.isEmpty()); 29 DCHECK(m_newDisplayItemList.isEmpty());
30 ASSERT(m_newPaintChunks.isInInitialState()); 30 DCHECK(m_newPaintChunks.isInInitialState());
31 return m_currentPaintArtifact; 31 return m_currentPaintArtifact;
32 } 32 }
33 33
34 bool PaintController::lastDisplayItemIsNoopBegin() const 34 bool PaintController::lastDisplayItemIsNoopBegin() const
35 { 35 {
36 if (m_newDisplayItemList.isEmpty()) 36 if (m_newDisplayItemList.isEmpty())
37 return false; 37 return false;
38 38
39 const auto& lastDisplayItem = m_newDisplayItemList.last(); 39 const auto& lastDisplayItem = m_newDisplayItemList.last();
40 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); 40 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent();
41 } 41 }
42 42
43 void PaintController::removeLastDisplayItem() 43 void PaintController::removeLastDisplayItem()
44 { 44 {
45 if (m_newDisplayItemList.isEmpty()) 45 if (m_newDisplayItemList.isEmpty())
46 return; 46 return;
47 47
48 #if ENABLE(ASSERT) 48 #if DCHECK_IS_ON()
49 // Also remove the index pointing to the removed display item. 49 // Also remove the index pointing to the removed display item.
50 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient .find(&m_newDisplayItemList.last().client()); 50 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient .find(&m_newDisplayItemList.last().client());
51 if (it != m_newDisplayItemIndicesByClient.end()) { 51 if (it != m_newDisplayItemIndicesByClient.end()) {
52 Vector<size_t>& indices = it->value; 52 Vector<size_t>& indices = it->value;
53 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1)) 53 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1))
54 indices.removeLast(); 54 indices.removeLast();
55 } 55 }
56 #endif 56 #endif
57 m_newDisplayItemList.removeLast(); 57 m_newDisplayItemList.removeLast();
58 58
59 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 59 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
60 m_newPaintChunks.decrementDisplayItemIndex(); 60 m_newPaintChunks.decrementDisplayItemIndex();
61 } 61 }
62 62
63 void PaintController::processNewItem(DisplayItem& displayItem) 63 void PaintController::processNewItem(DisplayItem& displayItem)
64 { 64 {
65 ASSERT(!m_constructionDisabled); 65 DCHECK(!m_constructionDisabled);
66 ASSERT(!skippingCache() || !displayItem.isCached()); 66 DCHECK(!skippingCache() || !displayItem.isCached());
67 67
68 if (displayItem.isCached()) 68 if (displayItem.isCached())
69 ++m_numCachedNewItems; 69 ++m_numCachedNewItems;
70 70
71 #if ENABLE(ASSERT) 71 #if DCHECK_IS_ON()
72 // Verify noop begin/end pairs have been removed. 72 // Verify noop begin/end pairs have been removed.
73 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { 73 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) {
74 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2]; 74 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2];
75 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::Subsequence && !beginDisplayItem.drawsContent()) 75 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::Subsequence && !beginDisplayItem.drawsContent())
76 ASSERT(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); 76 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType()));
77 } 77 }
78 #endif 78 #endif
79 79
80 if (!m_scopeStack.isEmpty()) 80 if (!m_scopeStack.isEmpty())
81 displayItem.setScope(m_scopeStack.last()); 81 displayItem.setScope(m_scopeStack.last());
82 82
83 #if ENABLE(ASSERT) 83 #if DCHECK_IS_ON()
84 size_t index = findMatchingItemFromIndex(displayItem.nonCachedId(), m_newDis playItemIndicesByClient, m_newDisplayItemList); 84 size_t index = findMatchingItemFromIndex(displayItem.nonCachedId(), m_newDis playItemIndicesByClient, m_newDisplayItemList);
85 if (index != kNotFound) { 85 if (index != kNotFound) {
86 #ifndef NDEBUG 86 #ifndef NDEBUG
87 showDebugData(); 87 showDebugData();
88 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n", 88 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n",
89 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index)); 89 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index));
90 #endif 90 #endif
91 ASSERT_NOT_REACHED(); 91 NOTREACHED();
92 } 92 }
93 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient); 93 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient);
94 #endif // ENABLE(ASSERT) 94 #endif // DCHECK_IS_ON()
95 95
96 if (skippingCache()) 96 if (skippingCache())
97 displayItem.setSkippedCache(); 97 displayItem.setSkippedCache();
98 98
99 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 99 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
100 m_newPaintChunks.incrementDisplayItemIndex(behaviorOfItemType(displayIte m.getType())); 100 m_newPaintChunks.incrementDisplayItemIndex(behaviorOfItemType(displayIte m.getType()));
101 } 101 }
102 102
103 void PaintController::updateCurrentPaintChunkProperties(const PaintChunkProperti es& newProperties) 103 void PaintController::updateCurrentPaintChunkProperties(const PaintChunkProperti es& newProperties)
104 { 104 {
105 m_newPaintChunks.updateCurrentPaintChunkProperties(newProperties); 105 m_newPaintChunks.updateCurrentPaintChunkProperties(newProperties);
106 } 106 }
107 107
108 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const 108 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const
109 { 109 {
110 return m_newPaintChunks.currentPaintChunkProperties(); 110 return m_newPaintChunks.currentPaintChunkProperties();
111 } 111 }
112 112
113 void PaintController::beginScope() 113 void PaintController::beginScope()
114 { 114 {
115 ASSERT_WITH_SECURITY_IMPLICATION(m_nextScope < UINT_MAX); 115 SECURITY_DCHECK(m_nextScope < UINT_MAX);
116 m_scopeStack.append(m_nextScope++); 116 m_scopeStack.append(m_nextScope++);
117 beginSkippingCache(); 117 beginSkippingCache();
118 } 118 }
119 119
120 void PaintController::endScope() 120 void PaintController::endScope()
121 { 121 {
122 m_scopeStack.removeLast(); 122 m_scopeStack.removeLast();
123 endSkippingCache(); 123 endSkippingCache();
124 } 124 }
125 125
126 void PaintController::invalidate(const DisplayItemClient& client) 126 void PaintController::invalidate(const DisplayItemClient& client)
127 { 127 {
128 #if ENABLE(ASSERT) 128 #if DCHECK_IS_ON()
129 // Slimming paint v1 CompositedLayerMapping may invalidate client on extra l ayers. 129 // Slimming paint v1 CompositedLayerMapping may invalidate client on extra l ayers.
130 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() || clientCacheIsValid(c lient)) 130 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() || clientCacheIsValid(c lient))
131 m_invalidations.append(client.debugName()); 131 m_invalidations.append(client.debugName());
132 #endif 132 #endif
133 133
134 invalidateUntracked(client); 134 invalidateUntracked(client);
135 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects) 135 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects)
136 m_trackedPaintInvalidationObjects->append(client.debugName()); 136 m_trackedPaintInvalidationObjects->append(client.debugName());
137 } 137 }
138 138
139 void PaintController::invalidateUntracked(const DisplayItemClient& client) 139 void PaintController::invalidateUntracked(const DisplayItemClient& client)
140 { 140 {
141 // This can be called during painting, but we can't invalidate already paint ed clients. 141 // This can be called during painting, but we can't invalidate already paint ed clients.
142 ASSERT(!m_newDisplayItemIndicesByClient.contains(&client)); 142 client.setDisplayItemsUncached();
143 updateValidlyCachedClientsIfNeeded(); 143 #if DCHECK_IS_ON()
144 m_validlyCachedClients.remove(&client); 144 DCHECK(!m_newDisplayItemIndicesByClient.contains(&client));
145 #endif
145 } 146 }
146 147
147 void PaintController::invalidateAll() 148 void PaintController::invalidateAll()
148 { 149 {
149 // Can only be called during layout/paintInvalidation, not during painting. 150 // Can only be called during layout/paintInvalidation, not during painting.
150 ASSERT(m_newDisplayItemList.isEmpty()); 151 DCHECK(m_newDisplayItemList.isEmpty());
151 m_currentPaintArtifact.reset(); 152 m_currentPaintArtifact.reset();
152 m_validlyCachedClients.clear(); 153 m_currentCacheGeneration.invalidate();
153 m_validlyCachedClientsDirty = false;
154 154
155 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects) 155 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects)
156 m_trackedPaintInvalidationObjects->append("##ALL##"); 156 m_trackedPaintInvalidationObjects->append("##ALL##");
157 } 157 }
158 158
159 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const 159 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const
160 { 160 {
161 #if DCHECK_IS_ON()
162 DCHECK(DisplayItemClient::isAlive(client));
163 #endif
161 if (skippingCache()) 164 if (skippingCache())
162 return false; 165 return false;
163 updateValidlyCachedClientsIfNeeded(); 166 return client.displayItemsAreCached(m_currentCacheGeneration);
164 return m_validlyCachedClients.contains(&client);
165 } 167 }
166 168
167 void PaintController::invalidatePaintOffset(const DisplayItemClient& client) 169 void PaintController::invalidatePaintOffset(const DisplayItemClient& client)
168 { 170 {
169 ASSERT(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); 171 DCHECK(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled());
170 invalidate(client); 172 invalidate(client);
171 173
172 #if ENABLE(ASSERT) 174 #if DCHECK_IS_ON()
173 ASSERT(!paintOffsetWasInvalidated(client)); 175 DCHECK(!paintOffsetWasInvalidated(client));
174 m_clientsWithPaintOffsetInvalidations.add(&client); 176 m_clientsWithPaintOffsetInvalidations.add(&client);
175 #endif 177 #endif
176 } 178 }
177 179
178 #if ENABLE(ASSERT) 180 #if DCHECK_IS_ON()
179 bool PaintController::paintOffsetWasInvalidated(const DisplayItemClient& client) const 181 bool PaintController::paintOffsetWasInvalidated(const DisplayItemClient& client) const
180 { 182 {
181 ASSERT(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); 183 DCHECK(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled());
182 return m_clientsWithPaintOffsetInvalidations.contains(&client); 184 return m_clientsWithPaintOffsetInvalidations.contains(&client);
183 } 185 }
184 #endif 186 #endif
185 187
186 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItemL ist& list) 188 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItemL ist& list)
187 { 189 {
188 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(&id.client); 190 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(&id.client);
189 if (it == displayItemIndicesByClient.end()) 191 if (it == displayItemIndicesByClient.end())
190 return kNotFound; 192 return kNotFound;
191 193
192 const Vector<size_t>& indices = it->value; 194 const Vector<size_t>& indices = it->value;
193 for (size_t index : indices) { 195 for (size_t index : indices) {
194 const DisplayItem& existingItem = list[index]; 196 const DisplayItem& existingItem = list[index];
195 ASSERT(!existingItem.hasValidClient() || existingItem.client() == id.cli ent); 197 DCHECK(!existingItem.hasValidClient() || existingItem.client() == id.cli ent);
196 if (id.matches(existingItem)) 198 if (id.matches(existingItem))
197 return index; 199 return index;
198 } 200 }
199 201
200 return kNotFound; 202 return kNotFound;
201 } 203 }
202 204
203 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient) 205 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient)
204 { 206 {
205 if (!displayItem.isCacheable()) 207 if (!displayItem.isCacheable())
206 return; 208 return;
207 209
208 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find (&displayItem.client()); 210 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find (&displayItem.client());
209 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? 211 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ?
210 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value; 212 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value;
211 indices.append(index); 213 indices.append(index);
212 } 214 }
213 215
214 struct PaintController::OutOfOrderIndexContext { 216 struct PaintController::OutOfOrderIndexContext {
215 STACK_ALLOCATED(); 217 STACK_ALLOCATED();
216 OutOfOrderIndexContext(DisplayItemList::iterator begin) : nextItemToIndex(be gin) { } 218 OutOfOrderIndexContext(DisplayItemList::iterator begin) : nextItemToIndex(be gin) { }
217 219
218 DisplayItemList::iterator nextItemToIndex; 220 DisplayItemList::iterator nextItemToIndex;
219 DisplayItemIndicesByClientMap displayItemIndicesByClient; 221 DisplayItemIndicesByClientMap displayItemIndicesByClient;
220 }; 222 };
221 223
222 DisplayItemList::iterator PaintController::findOutOfOrderCachedItem(const Displa yItem::Id& id, OutOfOrderIndexContext& context) 224 DisplayItemList::iterator PaintController::findOutOfOrderCachedItem(const Displa yItem::Id& id, OutOfOrderIndexContext& context)
223 { 225 {
224 ASSERT(clientCacheIsValid(id.client)); 226 DCHECK(clientCacheIsValid(id.client));
225 227
226 size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndices ByClient, m_currentPaintArtifact.getDisplayItemList()); 228 size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndices ByClient, m_currentPaintArtifact.getDisplayItemList());
227 if (foundIndex != kNotFound) 229 if (foundIndex != kNotFound)
228 return m_currentPaintArtifact.getDisplayItemList().begin() + foundIndex; 230 return m_currentPaintArtifact.getDisplayItemList().begin() + foundIndex;
229 231
230 return findOutOfOrderCachedItemForward(id, context); 232 return findOutOfOrderCachedItemForward(id, context);
231 } 233 }
232 234
233 // Find forward for the item and index all skipped indexable items. 235 // Find forward for the item and index all skipped indexable items.
234 DisplayItemList::iterator PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& id, OutOfOrderIndexContext& context) 236 DisplayItemList::iterator PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& id, OutOfOrderIndexContext& context)
235 { 237 {
236 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItem List().end(); 238 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItem List().end();
237 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { 239 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) {
238 const DisplayItem& item = *context.nextItemToIndex; 240 const DisplayItem& item = *context.nextItemToIndex;
239 ASSERT(item.hasValidClient()); 241 DCHECK(item.hasValidClient());
240 if (item.isCacheable() && clientCacheIsValid(item.client())) { 242 if (id.matches(item))
241 if (id.matches(item)) 243 return context.nextItemToIndex++;
242 return context.nextItemToIndex++; 244 if (item.isCacheable())
243
244 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPain tArtifact.getDisplayItemList().begin(), context.displayItemIndicesByClient); 245 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPain tArtifact.getDisplayItemList().begin(), context.displayItemIndicesByClient);
245 }
246 } 246 }
247 return currentEnd; 247 return currentEnd;
248 } 248 }
249 249
250 void PaintController::copyCachedSubsequence(const DisplayItemList& currentList, DisplayItemList::iterator& currentIt, DisplayItemList& updatedList, SkPictureGpu Analyzer& gpuAnalyzer) 250 void PaintController::copyCachedSubsequence(const DisplayItemList& currentList, DisplayItemList::iterator& currentIt, DisplayItemList& updatedList, SkPictureGpu Analyzer& gpuAnalyzer)
251 { 251 {
252 ASSERT(currentIt->getType() == DisplayItem::Subsequence); 252 DCHECK(currentIt->getType() == DisplayItem::Subsequence);
253 ASSERT(!currentIt->scope()); 253 DCHECK(!currentIt->scope());
254 DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::EndSubseq uence, 0); 254 DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::EndSubseq uence, 0);
255 do { 255 do {
256 // We should always find the EndSubsequence display item. 256 // We should always find the EndSubsequence display item.
257 ASSERT(currentIt != m_currentPaintArtifact.getDisplayItemList().end()); 257 DCHECK(currentIt != m_currentPaintArtifact.getDisplayItemList().end());
258 ASSERT(currentIt->hasValidClient()); 258 DCHECK(currentIt->hasValidClient());
259 updatedList.appendByMoving(*currentIt, currentList.visualRect(currentIt - m_currentPaintArtifact.getDisplayItemList().begin()), gpuAnalyzer); 259 updatedList.appendByMoving(*currentIt, currentList.visualRect(currentIt - m_currentPaintArtifact.getDisplayItemList().begin()), gpuAnalyzer);
260 ++currentIt; 260 ++currentIt;
261 } while (!endSubsequenceId.matches(updatedList.last())); 261 } while (!endSubsequenceId.matches(updatedList.last()));
262 } 262 }
263 263
264 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject) 264 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject)
265 { 265 {
266 #if ENABLE(ASSERT) 266 #if DCHECK_IS_ON()
267 m_newDisplayItemList.assertDisplayItemClientsAreAlive(); 267 m_newDisplayItemList.assertDisplayItemClientsAreAlive();
268 #endif 268 #endif
269 commitNewDisplayItemsInternal(offsetFromLayoutObject); 269 commitNewDisplayItemsInternal(offsetFromLayoutObject);
270 #if ENABLE(ASSERT) 270 #if DCHECK_IS_ON()
271 m_currentPaintArtifact.getDisplayItemList().assertDisplayItemClientsAreAlive (); 271 m_currentPaintArtifact.getDisplayItemList().assertDisplayItemClientsAreAlive ();
272 #endif 272 #endif
273 } 273 }
274 274
275 static IntRect visualRectForDisplayItem(const DisplayItem& displayItem, const La youtSize& offsetFromLayoutObject) 275 static IntRect visualRectForDisplayItem(const DisplayItem& displayItem, const La youtSize& offsetFromLayoutObject)
276 { 276 {
277 LayoutRect visualRect = displayItem.client().visualRect(); 277 LayoutRect visualRect = displayItem.client().visualRect();
278 visualRect.move(-offsetFromLayoutObject); 278 visualRect.move(-offsetFromLayoutObject);
279 return enclosingIntRect(visualRect); 279 return enclosingIntRect(visualRect);
280 } 280 }
281 281
282 // Update the existing display items by removing invalidated entries, updating 282 // Update the existing display items by removing invalidated entries, updating
283 // repainted ones, and appending new items. 283 // repainted ones, and appending new items.
284 // - For cached drawing display item, copy the corresponding cached DrawingDispl ayItem; 284 // - For cached drawing display item, copy the corresponding cached DrawingDispl ayItem;
285 // - For cached subsequence display item, copy the cached display items between the 285 // - For cached subsequence display item, copy the cached display items between the
286 // corresponding SubsequenceDisplayItem and EndSubsequenceDisplayItem (incl.); 286 // corresponding SubsequenceDisplayItem and EndSubsequenceDisplayItem (incl.);
287 // - Otherwise, copy the new display item. 287 // - Otherwise, copy the new display item.
288 // 288 //
289 // The algorithm is O(|m_currentDisplayItemList| + |m_newDisplayItemList|). 289 // The algorithm is O(|m_currentDisplayItemList| + |m_newDisplayItemList|).
290 // Coefficients are related to the ratio of out-of-order CachedDisplayItems 290 // Coefficients are related to the ratio of out-of-order CachedDisplayItems
291 // and the average number of (Drawing|Subsequence)DisplayItems per client. 291 // and the average number of (Drawing|Subsequence)DisplayItems per client.
292 // 292 //
293 void PaintController::commitNewDisplayItemsInternal(const LayoutSize& offsetFrom LayoutObject) 293 void PaintController::commitNewDisplayItemsInternal(const LayoutSize& offsetFrom LayoutObject)
294 { 294 {
295 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", 295 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems",
296 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(), 296 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(),
297 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems); 297 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems);
298 m_numCachedNewItems = 0; 298 m_numCachedNewItems = 0;
299 299
300 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
301 m_clientsCheckedPaintInvalidation.clear();
302
303 // These data structures are used during painting only. 300 // These data structures are used during painting only.
304 ASSERT(m_scopeStack.isEmpty()); 301 DCHECK(m_scopeStack.isEmpty());
305 m_scopeStack.clear(); 302 m_scopeStack.clear();
306 m_nextScope = 1; 303 m_nextScope = 1;
307 ASSERT(!skippingCache()); 304 DCHECK(!skippingCache());
308 #if ENABLE(ASSERT) 305 #if DCHECK_IS_ON()
309 m_newDisplayItemIndicesByClient.clear(); 306 m_newDisplayItemIndicesByClient.clear();
310 m_clientsWithPaintOffsetInvalidations.clear(); 307 m_clientsWithPaintOffsetInvalidations.clear();
311 m_invalidations.clear(); 308 m_invalidations.clear();
312 #endif 309 #endif
313 310
314 SkPictureGpuAnalyzer gpuAnalyzer; 311 SkPictureGpuAnalyzer gpuAnalyzer;
315 312
316 if (m_currentPaintArtifact.isEmpty()) { 313 if (m_currentPaintArtifact.isEmpty()) {
317 #if ENABLE(ASSERT) 314 #if DCHECK_IS_ON()
318 for (const auto& item : m_newDisplayItemList) 315 for (const auto& item : m_newDisplayItemList)
319 ASSERT(!item.isCached()); 316 DCHECK(!item.isCached());
320 #endif 317 #endif
321 318
322 for (const auto& item : m_newDisplayItemList) { 319 for (const auto& item : m_newDisplayItemList) {
323 m_newDisplayItemList.appendVisualRect(visualRectForDisplayItem(item, offsetFromLayoutObject)); 320 m_newDisplayItemList.appendVisualRect(visualRectForDisplayItem(item, offsetFromLayoutObject));
324 if (item.isDrawing()) 321 if (item.isDrawing())
325 gpuAnalyzer.analyze(static_cast<const DrawingDisplayItem&>(item) .picture()); 322 gpuAnalyzer.analyze(static_cast<const DrawingDisplayItem&>(item) .picture());
326 } 323 }
327 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_newPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization() ); 324 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_newPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization() );
328 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBy tes); 325 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBy tes);
329 m_validlyCachedClientsDirty = true; 326 updateCacheGeneration();
330 return; 327 return;
331 } 328 }
332 329
333 updateValidlyCachedClientsIfNeeded();
334
335 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched 330 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched
336 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched 331 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched
337 // by later out-of-order CachedDisplayItems in m_newDisplayItemList. This en sures that when 332 // by later out-of-order CachedDisplayItems in m_newDisplayItemList. This en sures that when
338 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems 333 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems
339 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. 334 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time.
340 OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.getDisp layItemList().begin()); 335 OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.getDisp layItemList().begin());
341 336
342 // TODO(jbroman): Consider revisiting this heuristic. 337 // TODO(jbroman): Consider revisiting this heuristic.
343 DisplayItemList updatedList(std::max(m_currentPaintArtifact.getDisplayItemLi st().usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes())); 338 DisplayItemList updatedList(std::max(m_currentPaintArtifact.getDisplayItemLi st().usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes()));
344 Vector<PaintChunk> updatedPaintChunks; 339 Vector<PaintChunk> updatedPaintChunks;
345 DisplayItemList::iterator currentIt = m_currentPaintArtifact.getDisplayItemL ist().begin(); 340 DisplayItemList::iterator currentIt = m_currentPaintArtifact.getDisplayItemL ist().begin();
346 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItem List().end(); 341 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItem List().end();
347 for (DisplayItemList::iterator newIt = m_newDisplayItemList.begin(); newIt ! = m_newDisplayItemList.end(); ++newIt) { 342 for (DisplayItemList::iterator newIt = m_newDisplayItemList.begin(); newIt ! = m_newDisplayItemList.end(); ++newIt) {
348 const DisplayItem& newDisplayItem = *newIt; 343 const DisplayItem& newDisplayItem = *newIt;
349 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); 344 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId();
350 bool newDisplayItemHasCachedType = newDisplayItem.getType() != newDispla yItemId.type; 345 bool newDisplayItemHasCachedType = newDisplayItem.getType() != newDispla yItemId.type;
351 346
352 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt); 347 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt);
353 348
354 if (newDisplayItemHasCachedType) { 349 if (newDisplayItemHasCachedType) {
355 ASSERT(newDisplayItem.isCached()); 350 #if DCHECK_IS_ON()
356 ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable dFeatures::slimmingPaintInvalidationEnabled() && !paintOffsetWasInvalidated(newD isplayItem.client()))); 351 DCHECK(newDisplayItem.isCached());
352 DCHECK(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable dFeatures::slimmingPaintInvalidationEnabled() && !paintOffsetWasInvalidated(newD isplayItem.client())));
353 #endif
357 if (!isSynchronized) { 354 if (!isSynchronized) {
358 currentIt = findOutOfOrderCachedItem(newDisplayItemId, outOfOrde rIndexContext); 355 currentIt = findOutOfOrderCachedItem(newDisplayItemId, outOfOrde rIndexContext);
359 356
360 if (currentIt == currentEnd) { 357 if (currentIt == currentEnd) {
361 #ifndef NDEBUG 358 #ifndef NDEBUG
362 showDebugData(); 359 showDebugData();
363 WTFLogAlways("%s not found in m_currentDisplayItemList\n", n ewDisplayItem.asDebugString().utf8().data()); 360 WTFLogAlways("%s not found in m_currentDisplayItemList\n", n ewDisplayItem.asDebugString().utf8().data());
364 #endif 361 #endif
365 ASSERT_NOT_REACHED(); 362 NOTREACHED();
366 // We did not find the cached display item. This should be i mpossible, but may occur if there is a bug 363 // We did not find the cached display item. This should be i mpossible, but may occur if there is a bug
367 // in the system, such as under-invalidation, incorrect cach e checking or duplicate display ids. 364 // in the system, such as under-invalidation, incorrect cach e checking or duplicate display ids.
368 // In this case, attempt to recover rather than crashing or bailing on display of the rest of the display list. 365 // In this case, attempt to recover rather than crashing or bailing on display of the rest of the display list.
369 continue; 366 continue;
370 } 367 }
371 } 368 }
372 #if ENABLE(ASSERT) 369 #if DCHECK_IS_ON()
373 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled()) { 370 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled()) {
374 DisplayItemList::iterator temp = currentIt; 371 DisplayItemList::iterator temp = currentIt;
375 checkUnderInvalidation(newIt, temp); 372 checkUnderInvalidation(newIt, temp);
376 } 373 }
377 #endif 374 #endif
378 if (newDisplayItem.isCachedDrawing()) { 375 if (newDisplayItem.isCachedDrawing()) {
379 updatedList.appendByMoving(*currentIt, m_currentPaintArtifact.ge tDisplayItemList().visualRect(currentIt - m_currentPaintArtifact.getDisplayItemL ist().begin()), 376 updatedList.appendByMoving(*currentIt, m_currentPaintArtifact.ge tDisplayItemList().visualRect(currentIt - m_currentPaintArtifact.getDisplayItemL ist().begin()),
380 gpuAnalyzer); 377 gpuAnalyzer);
381 ++currentIt; 378 ++currentIt;
382 } else { 379 } else {
383 ASSERT(newDisplayItem.getType() == DisplayItem::CachedSubsequenc e); 380 DCHECK(newDisplayItem.getType() == DisplayItem::CachedSubsequenc e);
384 copyCachedSubsequence(m_currentPaintArtifact.getDisplayItemList( ), currentIt, updatedList, gpuAnalyzer); 381 copyCachedSubsequence(m_currentPaintArtifact.getDisplayItemList( ), currentIt, updatedList, gpuAnalyzer);
385 ASSERT(updatedList.last().getType() == DisplayItem::EndSubsequen ce); 382 DCHECK(updatedList.last().getType() == DisplayItem::EndSubsequen ce);
386 } 383 }
387 } else { 384 } else {
388 ASSERT(!newDisplayItem.isDrawing() 385 #if DCHECK_IS_ON()
386 DCHECK(!newDisplayItem.isDrawing()
389 || newDisplayItem.skippedCache() 387 || newDisplayItem.skippedCache()
390 || !clientCacheIsValid(newDisplayItem.client()) 388 || !clientCacheIsValid(newDisplayItem.client())
391 || (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() & & paintOffsetWasInvalidated(newDisplayItem.client()))); 389 || (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() & & paintOffsetWasInvalidated(newDisplayItem.client())));
390 #endif
392 391
393 updatedList.appendByMoving(*newIt, visualRectForDisplayItem(*newIt, offsetFromLayoutObject), gpuAnalyzer); 392 updatedList.appendByMoving(*newIt, visualRectForDisplayItem(*newIt, offsetFromLayoutObject), gpuAnalyzer);
394 393
395 if (isSynchronized) 394 if (isSynchronized)
396 ++currentIt; 395 ++currentIt;
397 } 396 }
398 // Items before currentIt should have been copied so we don't need to in dex them. 397 // Items before currentIt should have been copied so we don't need to in dex them.
399 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) 398 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0)
400 outOfOrderIndexContext.nextItemToIndex = currentIt; 399 outOfOrderIndexContext.nextItemToIndex = currentIt;
401 } 400 }
402 401
403 #if ENABLE(ASSERT) 402 #if DCHECK_IS_ON()
404 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) 403 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
405 checkNoRemainingCachedDisplayItems(); 404 checkNoRemainingCachedDisplayItems();
406 #endif // ENABLE(ASSERT) 405 #endif
407 406
408 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to 407 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to
409 // merge the paint chunks as well. 408 // merge the paint chunks as well.
410 m_currentPaintArtifact = PaintArtifact(std::move(updatedList), m_newPaintChu nks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization()); 409 m_currentPaintArtifact = PaintArtifact(std::move(updatedList), m_newPaintChu nks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization());
411 410
412 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBytes) ; 411 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBytes) ;
413 m_validlyCachedClientsDirty = true; 412 updateCacheGeneration();
414 } 413 }
415 414
416 size_t PaintController::approximateUnsharedMemoryUsage() const 415 size_t PaintController::approximateUnsharedMemoryUsage() const
417 { 416 {
418 size_t memoryUsage = sizeof(*this); 417 size_t memoryUsage = sizeof(*this);
419 418
420 // Memory outside this class due to m_currentPaintArtifact. 419 // Memory outside this class due to m_currentPaintArtifact.
421 memoryUsage += m_currentPaintArtifact.approximateUnsharedMemoryUsage() - siz eof(m_currentPaintArtifact); 420 memoryUsage += m_currentPaintArtifact.approximateUnsharedMemoryUsage() - siz eof(m_currentPaintArtifact);
422 421
423 // TODO(jbroman): If display items begin to have significant external memory 422 // TODO(jbroman): If display items begin to have significant external memory
424 // usage that's not shared with the embedder, we should account for it here. 423 // usage that's not shared with the embedder, we should account for it here.
425 // 424 //
426 // External objects, shared with the embedder, such as SkPicture, should be 425 // External objects, shared with the embedder, such as SkPicture, should be
427 // excluded to avoid double counting. It is the embedder's responsibility to 426 // excluded to avoid double counting. It is the embedder's responsibility to
428 // count such objects. 427 // count such objects.
429 // 428 //
430 // At time of writing, the only known case of unshared external memory was 429 // At time of writing, the only known case of unshared external memory was
431 // the rounded clips vector in ClipDisplayItem, which is not expected to 430 // the rounded clips vector in ClipDisplayItem, which is not expected to
432 // contribute significantly to memory usage. 431 // contribute significantly to memory usage.
433 432
434 // Memory outside this class due to m_newDisplayItemList. 433 // Memory outside this class due to m_newDisplayItemList.
435 ASSERT(m_newDisplayItemList.isEmpty()); 434 DCHECK(m_newDisplayItemList.isEmpty());
436 memoryUsage += m_newDisplayItemList.memoryUsageInBytes(); 435 memoryUsage += m_newDisplayItemList.memoryUsageInBytes();
437 436
438 return memoryUsage; 437 return memoryUsage;
439 } 438 }
440 439
441 void PaintController::updateValidlyCachedClientsIfNeeded() const 440 void PaintController::updateCacheGeneration()
442 { 441 {
443 if (!m_validlyCachedClientsDirty) 442 m_currentCacheGeneration = DisplayItemCacheGeneration::next();
444 return;
445
446 m_validlyCachedClients.clear();
447 m_validlyCachedClientsDirty = false;
448
449 const DisplayItemClient* lastAddedClient = nullptr;
450 for (const DisplayItem& displayItem : m_currentPaintArtifact.getDisplayItemL ist()) { 443 for (const DisplayItem& displayItem : m_currentPaintArtifact.getDisplayItemL ist()) {
451 if (&displayItem.client() == lastAddedClient) 444 if (displayItem.isCacheable())
452 continue; 445 displayItem.client().setDisplayItemsCached(m_currentCacheGeneration) ;
453 if (displayItem.isCacheable()) {
454 lastAddedClient = &displayItem.client();
455 m_validlyCachedClients.add(lastAddedClient);
456 }
457 } 446 }
458 } 447 }
459 448
460 #if ENABLE(ASSERT) 449 #if DCHECK_IS_ON()
461 450
462 void PaintController::checkUnderInvalidation(DisplayItemList::iterator& newIt, D isplayItemList::iterator& currentIt) 451 void PaintController::checkUnderInvalidation(DisplayItemList::iterator& newIt, D isplayItemList::iterator& currentIt)
463 { 452 {
464 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 453 DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
465 ASSERT(newIt->isCached()); 454 DCHECK(newIt->isCached());
466 455
467 // When under-invalidation-checking is enabled, the forced painting is follo wing the cached display item. 456 // When under-invalidation-checking is enabled, the forced painting is follo wing the cached display item.
468 DisplayItem::Type nextItemType = DisplayItem::nonCachedType(newIt->getType() ); 457 DisplayItem::Type nextItemType = DisplayItem::nonCachedType(newIt->getType() );
469 ++newIt; 458 ++newIt;
470 ASSERT(newIt->getType() == nextItemType); 459 DCHECK(newIt->getType() == nextItemType);
471 460
472 if (newIt->isDrawing()) { 461 if (newIt->isDrawing()) {
473 checkCachedDisplayItemIsUnchanged("", *newIt, *currentIt); 462 checkCachedDisplayItemIsUnchanged("", *newIt, *currentIt);
474 return; 463 return;
475 } 464 }
476 465
477 ASSERT(newIt->getType() == DisplayItem::Subsequence); 466 DCHECK(newIt->getType() == DisplayItem::Subsequence);
478 467
479 #ifndef NDEBUG 468 #ifndef NDEBUG
480 CString messagePrefix = String::format("(In CachedSubsequence of %s)", newIt ->clientDebugString().utf8().data()).utf8(); 469 CString messagePrefix = String::format("(In CachedSubsequence of %s)", newIt ->clientDebugString().utf8().data()).utf8();
481 #else 470 #else
482 CString messagePrefix = "(In CachedSubsequence)"; 471 CString messagePrefix = "(In CachedSubsequence)";
483 #endif 472 #endif
484 473
485 DisplayItem::Id endSubsequenceId(newIt->client(), DisplayItem::EndSubsequenc e, 0); 474 DisplayItem::Id endSubsequenceId(newIt->client(), DisplayItem::EndSubsequenc e, 0);
486 while (true) { 475 while (true) {
487 ASSERT(newIt != m_newDisplayItemList.end()); 476 DCHECK(newIt != m_newDisplayItemList.end());
488 if (newIt->isCached()) 477 if (newIt->isCached())
489 checkUnderInvalidation(newIt, currentIt); 478 checkUnderInvalidation(newIt, currentIt);
490 else 479 else
491 checkCachedDisplayItemIsUnchanged(messagePrefix.data(), *newIt, *cur rentIt); 480 checkCachedDisplayItemIsUnchanged(messagePrefix.data(), *newIt, *cur rentIt);
492 481
493 if (endSubsequenceId.matches(*newIt)) 482 if (endSubsequenceId.matches(*newIt))
494 break; 483 break;
495 484
496 ++newIt; 485 ++newIt;
497 ++currentIt; 486 ++currentIt;
498 } 487 }
499 } 488 }
500 489
501 static void showUnderInvalidationError(const char* messagePrefix, const char* re ason, const DisplayItem* newItem, const DisplayItem* oldItem) 490 static void showUnderInvalidationError(const char* messagePrefix, const char* re ason, const DisplayItem* newItem, const DisplayItem* oldItem)
502 { 491 {
503 #ifndef NDEBUG 492 #ifndef NDEBUG
504 WTFLogAlways("%s %s:\nNew display item: %s\nOld display item: %s\nSee http:/ /crbug.com/450725.", messagePrefix, reason, 493 WTFLogAlways("%s %s:\nNew display item: %s\nOld display item: %s\nSee http:/ /crbug.com/450725.", messagePrefix, reason,
505 newItem ? newItem->asDebugString().utf8().data() : "None", 494 newItem ? newItem->asDebugString().utf8().data() : "None",
506 oldItem ? oldItem->asDebugString().utf8().data() : "None"); 495 oldItem ? oldItem->asDebugString().utf8().data() : "None");
507 #else 496 #else
508 WTFLogAlways("%s %s. Run debug build to get more details\nSee http://crbug.c om/450725.", messagePrefix, reason); 497 WTFLogAlways("%s %s. Run debug build to get more details\nSee http://crbug.c om/450725.", messagePrefix, reason);
509 #endif // NDEBUG 498 #endif // NDEBUG
510 } 499 }
511 500
512 void PaintController::checkCachedDisplayItemIsUnchanged(const char* messagePrefi x, const DisplayItem& newItem, const DisplayItem& oldItem) 501 void PaintController::checkCachedDisplayItemIsUnchanged(const char* messagePrefi x, const DisplayItem& newItem, const DisplayItem& oldItem)
513 { 502 {
514 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 503 DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
515 ASSERT(!newItem.isCached()); 504 DCHECK(!newItem.isCached());
516 ASSERT(!oldItem.isCached()); 505 DCHECK(!oldItem.isCached());
517 506
518 if (newItem.skippedCache()) { 507 if (newItem.skippedCache()) {
519 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: sk ipped-cache in cached subsequence", &newItem, &oldItem); 508 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: sk ipped-cache in cached subsequence", &newItem, &oldItem);
520 ASSERT_NOT_REACHED(); 509 NOTREACHED();
521 } 510 }
522 511
523 if (newItem.isCacheable() && !m_validlyCachedClients.contains(&newItem.clien t())) { 512 if (newItem.isCacheable() && !clientCacheIsValid(newItem.client())) {
524 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: in validated in cached subsequence", &newItem, &oldItem); 513 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: in validated in cached subsequence", &newItem, &oldItem);
525 ASSERT_NOT_REACHED(); 514 NOTREACHED();
526 } 515 }
527 516
528 if (newItem.equals(oldItem)) 517 if (newItem.equals(oldItem))
529 return; 518 return;
530 519
531 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: displa y item changed", &newItem, &oldItem); 520 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: displa y item changed", &newItem, &oldItem);
532 521
533 #ifndef NDEBUG 522 #ifndef NDEBUG
534 if (newItem.isDrawing()) { 523 if (newItem.isDrawing()) {
535 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayIte m&>(newItem).picture(); 524 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayIte m&>(newItem).picture();
536 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayIte m&>(oldItem).picture(); 525 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayIte m&>(oldItem).picture();
537 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPict ure.get()) : "None"; 526 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPict ure.get()) : "None";
538 String newPictureDebugString = newPicture ? pictureAsDebugString(newPict ure.get()) : "None"; 527 String newPictureDebugString = newPicture ? pictureAsDebugString(newPict ure.get()) : "None";
539 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data()); 528 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data());
540 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); 529 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data());
541 } 530 }
542 #endif // NDEBUG 531 #endif // NDEBUG
543 532
544 ASSERT_NOT_REACHED(); 533 NOTREACHED();
545 } 534 }
546 535
547 void PaintController::checkNoRemainingCachedDisplayItems() 536 void PaintController::checkNoRemainingCachedDisplayItems()
548 { 537 {
549 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 538 DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
550 539
551 for (const auto& displayItem : m_currentPaintArtifact.getDisplayItemList()) { 540 for (const auto& displayItem : m_currentPaintArtifact.getDisplayItemList()) {
552 if (!displayItem.hasValidClient() || !displayItem.isCacheable() || !clie ntCacheIsValid(displayItem.client())) 541 if (!displayItem.hasValidClient() || !displayItem.isCacheable() || !clie ntCacheIsValid(displayItem.client()))
553 continue; 542 continue;
554 showUnderInvalidationError("", "May be under-invalidation: no new displa y item", nullptr, &displayItem); 543 showUnderInvalidationError("", "May be under-invalidation: no new displa y item", nullptr, &displayItem);
555 } 544 }
556 } 545 }
557 546
558 #endif // ENABLE(ASSERT) 547 #endif // DCHECK_IS_ON()
559 548
560 #ifndef NDEBUG 549 #ifndef NDEBUG
561 550
562 WTF::String PaintController::displayItemListAsDebugString(const DisplayItemList& list) const 551 WTF::String PaintController::displayItemListAsDebugString(const DisplayItemList& list) const
563 { 552 {
564 StringBuilder stringBuilder; 553 StringBuilder stringBuilder;
565 size_t i = 0; 554 size_t i = 0;
566 for (auto it = list.begin(); it != list.end(); ++it, ++i) { 555 for (auto it = list.begin(); it != list.end(); ++it, ++i) {
567 const DisplayItem& displayItem = *it; 556 const DisplayItem& displayItem = *it;
568 if (i) 557 if (i)
(...skipping 11 matching lines...) Expand all
580 569
581 void PaintController::showDebugData() const 570 void PaintController::showDebugData() const
582 { 571 {
583 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); 572 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data());
584 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data()); 573 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data());
585 } 574 }
586 575
587 #endif // ifndef NDEBUG 576 #endif // ifndef NDEBUG
588 577
589 } // namespace blink 578 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698