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

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

Issue 2299223002: Compile under-invalidation checking in all builds (Closed)
Patch Set: Resolve conflict Created 4 years, 3 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"
(...skipping 16 matching lines...) Expand all
27 bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client , DisplayItem::Type type) 27 bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client , DisplayItem::Type type)
28 { 28 {
29 DCHECK(DisplayItem::isDrawingType(type)); 29 DCHECK(DisplayItem::isDrawingType(type));
30 30
31 if (displayItemConstructionIsDisabled()) 31 if (displayItemConstructionIsDisabled())
32 return false; 32 return false;
33 33
34 if (!clientCacheIsValid(client)) 34 if (!clientCacheIsValid(client))
35 return false; 35 return false;
36 36
37 #if DCHECK_IS_ON() 37 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled() && isChe ckingUnderInvalidation()) {
38 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) {
39 // We are checking under-invalidation of a subsequence enclosing this di splay item. 38 // We are checking under-invalidation of a subsequence enclosing this di splay item.
40 // Let the client continue to actually paint the display item. 39 // Let the client continue to actually paint the display item.
41 return false; 40 return false;
42 } 41 }
43 #endif
44 42
45 size_t cachedItem = findCachedItem(DisplayItem::Id(client, type)); 43 size_t cachedItem = findCachedItem(DisplayItem::Id(client, type));
46 if (cachedItem == kNotFound) { 44 if (cachedItem == kNotFound) {
47 NOTREACHED(); 45 NOTREACHED();
48 return false; 46 return false;
49 } 47 }
50 48
51 ++m_numCachedNewItems; 49 ++m_numCachedNewItems;
52 ensureNewDisplayItemListInitialCapacity(); 50 ensureNewDisplayItemListInitialCapacity();
53 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidati onCheckingEnabled()) 51 if (!RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled())
54 processNewItem(m_newDisplayItemList.appendByMoving(m_currentPaintArtifac t.getDisplayItemList()[cachedItem]), FromCachedItem); 52 processNewItem(m_newDisplayItemList.appendByMoving(m_currentPaintArtifac t.getDisplayItemList()[cachedItem]), FromCachedItem);
55 53
56 m_nextItemToMatch = cachedItem + 1; 54 m_nextItemToMatch = cachedItem + 1;
57 // Items before m_nextItemToMatch have been copied so we don't need to index them. 55 // Items before m_nextItemToMatch have been copied so we don't need to index them.
58 if (m_nextItemToMatch > m_nextItemToIndex) 56 if (m_nextItemToMatch > m_nextItemToIndex)
59 m_nextItemToIndex = m_nextItemToMatch; 57 m_nextItemToIndex = m_nextItemToMatch;
60 58
61 #if DCHECK_IS_ON() 59 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
62 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
63 if (!isCheckingUnderInvalidation()) { 60 if (!isCheckingUnderInvalidation()) {
64 m_underInvalidationCheckingBegin = cachedItem; 61 m_underInvalidationCheckingBegin = cachedItem;
65 m_underInvalidationCheckingEnd = cachedItem + 1; 62 m_underInvalidationCheckingEnd = cachedItem + 1;
66 m_underInvalidationMessagePrefix = ""; 63 m_underInvalidationMessagePrefix = "";
67 } 64 }
68 // Return false to let the painter actually paint, and we will check if the new painting 65 // Return false to let the painter actually paint, and we will check if the new painting
69 // is the same as the cached. 66 // is the same as the cached.
70 return false; 67 return false;
71 } 68 }
72 #endif
73 69
74 return true; 70 return true;
75 } 71 }
76 72
77 bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl ient) 73 bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl ient)
78 { 74 {
79 if (displayItemConstructionIsDisabled() || subsequenceCachingIsDisabled()) 75 if (displayItemConstructionIsDisabled() || subsequenceCachingIsDisabled())
80 return false; 76 return false;
81 77
82 if (!clientCacheIsValid(client)) 78 if (!clientCacheIsValid(client))
83 return false; 79 return false;
84 80
85 #if DCHECK_IS_ON() 81 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled() && isChe ckingUnderInvalidation()) {
86 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) {
87 // We are checking under-invalidation of an ancestor subsequence enclosi ng this one. 82 // We are checking under-invalidation of an ancestor subsequence enclosi ng this one.
88 // The ancestor subsequence is supposed to have already "copied", so we should let the 83 // The ancestor subsequence is supposed to have already "copied", so we should let the
89 // client continue to actually paint the descendant subsequences without "copying". 84 // client continue to actually paint the descendant subsequences without "copying".
90 return false; 85 return false;
91 } 86 }
92 #endif
93 87
94 size_t cachedItem = findCachedItem(DisplayItem::Id(client, DisplayItem::kSub sequence)); 88 size_t cachedItem = findCachedItem(DisplayItem::Id(client, DisplayItem::kSub sequence));
95 if (cachedItem == kNotFound) { 89 if (cachedItem == kNotFound) {
96 NOTREACHED(); 90 NOTREACHED();
97 return false; 91 return false;
98 } 92 }
99 93
100 // |cachedItem| will point to the first item after the subsequence or end of the current list. 94 // |cachedItem| will point to the first item after the subsequence or end of the current list.
101 ensureNewDisplayItemListInitialCapacity(); 95 ensureNewDisplayItemListInitialCapacity();
102 copyCachedSubsequence(cachedItem); 96 copyCachedSubsequence(cachedItem);
103 97
104 m_nextItemToMatch = cachedItem; 98 m_nextItemToMatch = cachedItem;
105 // Items before |cachedItem| have been copied so we don't need to index them . 99 // Items before |cachedItem| have been copied so we don't need to index them .
106 if (cachedItem > m_nextItemToIndex) 100 if (cachedItem > m_nextItemToIndex)
107 m_nextItemToIndex = cachedItem; 101 m_nextItemToIndex = cachedItem;
108 102
109 #if DCHECK_IS_ON() 103 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
110 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
111 // Return false to let the painter actually paint, and we will check if the new painting 104 // Return false to let the painter actually paint, and we will check if the new painting
112 // is the same as the cached. 105 // is the same as the cached.
113 return false; 106 return false;
114 } 107 }
115 #endif
116 108
117 return true; 109 return true;
118 } 110 }
119 111
120 bool PaintController::lastDisplayItemIsNoopBegin() const 112 bool PaintController::lastDisplayItemIsNoopBegin() const
121 { 113 {
122 if (m_newDisplayItemList.isEmpty()) 114 if (m_newDisplayItemList.isEmpty())
123 return false; 115 return false;
124 116
125 const auto& lastDisplayItem = m_newDisplayItemList.last(); 117 const auto& lastDisplayItem = m_newDisplayItemList.last();
126 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); 118 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent();
127 } 119 }
128 120
129 void PaintController::removeLastDisplayItem() 121 void PaintController::removeLastDisplayItem()
130 { 122 {
131 if (m_newDisplayItemList.isEmpty()) 123 if (m_newDisplayItemList.isEmpty())
132 return; 124 return;
133 125
134 #if DCHECK_IS_ON() 126 #if DCHECK_IS_ON()
135 // Also remove the index pointing to the removed display item. 127 // Also remove the index pointing to the removed display item.
136 IndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient.find(&m_ne wDisplayItemList.last().client()); 128 IndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient.find(&m_ne wDisplayItemList.last().client());
137 if (it != m_newDisplayItemIndicesByClient.end()) { 129 if (it != m_newDisplayItemIndicesByClient.end()) {
138 Vector<size_t>& indices = it->value; 130 Vector<size_t>& indices = it->value;
139 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1)) 131 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1))
140 indices.removeLast(); 132 indices.removeLast();
141 } 133 }
134 #endif
142 135
143 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) { 136 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled() && isChe ckingUnderInvalidation()) {
144 if (m_skippedProbableUnderInvalidationCount) { 137 if (m_skippedProbableUnderInvalidationCount) {
145 --m_skippedProbableUnderInvalidationCount; 138 --m_skippedProbableUnderInvalidationCount;
146 } else { 139 } else {
147 DCHECK(m_underInvalidationCheckingBegin); 140 DCHECK(m_underInvalidationCheckingBegin);
148 --m_underInvalidationCheckingBegin; 141 --m_underInvalidationCheckingBegin;
149 } 142 }
150 } 143 }
151 #endif
152 m_newDisplayItemList.removeLast(); 144 m_newDisplayItemList.removeLast();
153 145
154 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 146 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
155 m_newPaintChunks.decrementDisplayItemIndex(); 147 m_newPaintChunks.decrementDisplayItemIndex();
156 } 148 }
157 149
158 const DisplayItem* PaintController::lastDisplayItem(unsigned offset) 150 const DisplayItem* PaintController::lastDisplayItem(unsigned offset)
159 { 151 {
160 if (offset < m_newDisplayItemList.size()) 152 if (offset < m_newDisplayItemList.size())
161 return &m_newDisplayItemList[m_newDisplayItemList.size() - offset - 1]; 153 return &m_newDisplayItemList[m_newDisplayItemList.size() - offset - 1];
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList); 210 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList);
219 if (index != kNotFound) { 211 if (index != kNotFound) {
220 #ifndef NDEBUG 212 #ifndef NDEBUG
221 showDebugData(); 213 showDebugData();
222 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n", 214 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n",
223 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index)); 215 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index));
224 #endif 216 #endif
225 NOTREACHED(); 217 NOTREACHED();
226 } 218 }
227 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient); 219 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient);
220 #endif // DCHECK_IS_ON()
228 221
229 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) 222 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled())
230 checkUnderInvalidation(); 223 checkUnderInvalidation();
231 #endif // DCHECK_IS_ON()
232 } 224 }
233 225
234 void PaintController::updateCurrentPaintChunkProperties(const PaintChunk::Id* id , const PaintChunkProperties& newProperties) 226 void PaintController::updateCurrentPaintChunkProperties(const PaintChunk::Id* id , const PaintChunkProperties& newProperties)
235 { 227 {
236 m_newPaintChunks.updateCurrentPaintChunkProperties(id, newProperties); 228 m_newPaintChunks.updateCurrentPaintChunkProperties(id, newProperties);
237 } 229 }
238 230
239 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const 231 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const
240 { 232 {
241 return m_newPaintChunks.currentPaintChunkProperties(); 233 return m_newPaintChunks.currentPaintChunkProperties();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 DCHECK(clientCacheIsValid(id.client)); 284 DCHECK(clientCacheIsValid(id.client));
293 285
294 // Try to find the item sequentially first. This is fast if the current list and the new list are in 286 // Try to find the item sequentially first. This is fast if the current list and the new list are in
295 // the same order around the new item. If found, we don't need to update and lookup the index. 287 // the same order around the new item. If found, we don't need to update and lookup the index.
296 for (size_t i = m_nextItemToMatch; i < m_currentPaintArtifact.getDisplayItem List().size(); ++i) { 288 for (size_t i = m_nextItemToMatch; i < m_currentPaintArtifact.getDisplayItem List().size(); ++i) {
297 // We encounter an item that has already been copied which indicates we can't do sequential matching. 289 // We encounter an item that has already been copied which indicates we can't do sequential matching.
298 const DisplayItem& item = m_currentPaintArtifact.getDisplayItemList()[i] ; 290 const DisplayItem& item = m_currentPaintArtifact.getDisplayItemList()[i] ;
299 if (!item.hasValidClient()) 291 if (!item.hasValidClient())
300 break; 292 break;
301 if (id == item.getId()) { 293 if (id == item.getId()) {
302 #if DCHECK_IS_ON() 294 #ifndef NDEBUG
303 ++m_numSequentialMatches; 295 ++m_numSequentialMatches;
304 #endif 296 #endif
305 return i; 297 return i;
306 } 298 }
307 // We encounter a different cacheable item which also indicates we can't do sequential matching. 299 // We encounter a different cacheable item which also indicates we can't do sequential matching.
308 if (item.isCacheable()) 300 if (item.isCacheable())
309 break; 301 break;
310 } 302 }
311 303
312 size_t foundIndex = findMatchingItemFromIndex(id, m_outOfOrderItemIndices, m _currentPaintArtifact.getDisplayItemList()); 304 size_t foundIndex = findMatchingItemFromIndex(id, m_outOfOrderItemIndices, m _currentPaintArtifact.getDisplayItemList());
313 if (foundIndex != kNotFound) { 305 if (foundIndex != kNotFound) {
314 #if DCHECK_IS_ON() 306 #ifndef NDEBUG
315 ++m_numOutOfOrderMatches; 307 ++m_numOutOfOrderMatches;
316 #endif 308 #endif
317 return foundIndex; 309 return foundIndex;
318 } 310 }
319 311
320 return findOutOfOrderCachedItemForward(id); 312 return findOutOfOrderCachedItemForward(id);
321 } 313 }
322 314
323 // Find forward for the item and index all skipped indexable items. 315 // Find forward for the item and index all skipped indexable items.
324 size_t PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& i d) 316 size_t PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& i d)
325 { 317 {
326 for (size_t i = m_nextItemToIndex; i < m_currentPaintArtifact.getDisplayItem List().size(); ++i) { 318 for (size_t i = m_nextItemToIndex; i < m_currentPaintArtifact.getDisplayItem List().size(); ++i) {
327 const DisplayItem& item = m_currentPaintArtifact.getDisplayItemList()[i] ; 319 const DisplayItem& item = m_currentPaintArtifact.getDisplayItemList()[i] ;
328 DCHECK(item.hasValidClient()); 320 DCHECK(item.hasValidClient());
329 if (id == item.getId()) { 321 if (id == item.getId()) {
330 #if DCHECK_IS_ON() 322 #ifndef NDEBUG
331 ++m_numSequentialMatches; 323 ++m_numSequentialMatches;
332 #endif 324 #endif
333 return i; 325 return i;
334 } 326 }
335 if (item.isCacheable()) { 327 if (item.isCacheable()) {
336 #if DCHECK_IS_ON() 328 #ifndef NDEBUG
337 ++m_numIndexedItems; 329 ++m_numIndexedItems;
338 #endif 330 #endif
339 addItemToIndexIfNeeded(item, i, m_outOfOrderItemIndices); 331 addItemToIndexIfNeeded(item, i, m_outOfOrderItemIndices);
340 } 332 }
341 } 333 }
342 334
343 #ifndef NDEBUG 335 #ifndef NDEBUG
344 showDebugData(); 336 showDebugData();
345 LOG(ERROR) << id.client.debugName() << ":" << DisplayItem::typeAsDebugString (id.type); 337 LOG(ERROR) << id.client.debugName() << ":" << DisplayItem::typeAsDebugString (id.type);
346 #endif 338 #endif
347 NOTREACHED() << "Can't find cached display item"; 339
340 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled())
341 CHECK(false) << "Can't find cached display item";
342
348 // We did not find the cached display item. This should be impossible, but m ay occur if there is a bug 343 // We did not find the cached display item. This should be impossible, but m ay occur if there is a bug
349 // in the system, such as under-invalidation, incorrect cache checking or du plicate display ids. 344 // in the system, such as under-invalidation, incorrect cache checking or du plicate display ids.
350 // In this case, the caller should fall back to repaint the display item. 345 // In this case, the caller should fall back to repaint the display item.
351 return kNotFound; 346 return kNotFound;
352 } 347 }
353 348
354 // Copies a cached subsequence from current list to the new list. On return, 349 // Copies a cached subsequence from current list to the new list. On return,
355 // |cachedItemIndex| points to the item after the EndSubsequence item of the sub sequence. 350 // |cachedItemIndex| points to the item after the EndSubsequence item of the sub sequence.
356 // When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subs equence, 351 // When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subs equence,
357 // but mark the begin and end of the subsequence for under-invalidation checking . 352 // but mark the begin and end of the subsequence for under-invalidation checking .
358 void PaintController::copyCachedSubsequence(size_t& cachedItemIndex) 353 void PaintController::copyCachedSubsequence(size_t& cachedItemIndex)
359 { 354 {
360 DisplayItem* cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cache dItemIndex]; 355 DisplayItem* cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cache dItemIndex];
361 #if DCHECK_IS_ON()
362 DCHECK(cachedItem->getType() == DisplayItem::kSubsequence); 356 DCHECK(cachedItem->getType() == DisplayItem::kSubsequence);
363 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) { 357
358 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
364 DCHECK(!isCheckingUnderInvalidation()); 359 DCHECK(!isCheckingUnderInvalidation());
365 m_underInvalidationCheckingBegin = cachedItemIndex; 360 m_underInvalidationCheckingBegin = cachedItemIndex;
366 m_underInvalidationMessagePrefix = "(In cached subsequence of " + cached Item->client().debugName() + ")"; 361 m_underInvalidationMessagePrefix = "(In cached subsequence of " + cached Item->client().debugName() + ")";
367 } 362 }
368 #endif
369 363
370 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::kEndSubs equence); 364 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::kEndSubs equence);
371 Vector<PaintChunk>::const_iterator cachedChunk; 365 Vector<PaintChunk>::const_iterator cachedChunk;
372 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 366 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
373 cachedChunk = m_currentPaintArtifact.findChunkByDisplayItemIndex(cachedI temIndex); 367 cachedChunk = m_currentPaintArtifact.findChunkByDisplayItemIndex(cachedI temIndex);
374 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChunk->id : nullptr, cachedChunk->properties); 368 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChunk->id : nullptr, cachedChunk->properties);
375 } else { 369 } else {
376 // This is to avoid compilation error about uninitialized variable on Wi ndows. 370 // This is to avoid compilation error about uninitialized variable on Wi ndows.
377 cachedChunk = m_currentPaintArtifact.paintChunks().begin(); 371 cachedChunk = m_currentPaintArtifact.paintChunks().begin();
378 } 372 }
379 373
380 while (true) { 374 while (true) {
381 DCHECK(cachedItem->hasValidClient()); 375 DCHECK(cachedItem->hasValidClient());
382 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 376 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
383 CHECK(cachedItem->client().isAlive()); 377 CHECK(cachedItem->client().isAlive());
384 #endif 378 #endif
385 ++m_numCachedNewItems; 379 ++m_numCachedNewItems;
386 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId; 380 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId;
387 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali dationCheckingEnabled()) { 381 if (!RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
388 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) { 382 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) {
389 ++cachedChunk; 383 ++cachedChunk;
390 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties); 384 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties);
391 } 385 }
392 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem), Fro mCachedSubsequence); 386 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem), Fro mCachedSubsequence);
393 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 387 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
394 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk)); 388 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk));
395 } 389 }
396 390
397 ++cachedItemIndex; 391 ++cachedItemIndex;
398 if (metEndSubsequence) 392 if (metEndSubsequence)
399 break; 393 break;
400 394
401 // We should always be able to find the EndSubsequence display item. 395 // We should always be able to find the EndSubsequence display item.
402 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz e()); 396 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz e());
403 cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cachedItemInde x]; 397 cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cachedItemInde x];
404 } 398 }
405 399
406 #if DCHECK_IS_ON() 400 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
407 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
408 m_underInvalidationCheckingEnd = cachedItemIndex; 401 m_underInvalidationCheckingEnd = cachedItemIndex;
409 DCHECK(isCheckingUnderInvalidation()); 402 DCHECK(isCheckingUnderInvalidation());
410 } 403 }
411 #endif
412 } 404 }
413 405
414 static IntRect visualRectForDisplayItem(const DisplayItem& displayItem, const La youtSize& offsetFromLayoutObject) 406 static IntRect visualRectForDisplayItem(const DisplayItem& displayItem, const La youtSize& offsetFromLayoutObject)
415 { 407 {
416 LayoutRect visualRect = displayItem.client().visualRect(); 408 LayoutRect visualRect = displayItem.client().visualRect();
417 visualRect.move(-offsetFromLayoutObject); 409 visualRect.move(-offsetFromLayoutObject);
418 return enclosingIntRect(visualRect); 410 return enclosingIntRect(visualRect);
419 } 411 }
420 412
421 void PaintController::resetCurrentListIndices() 413 void PaintController::resetCurrentListIndices()
422 { 414 {
423 m_nextItemToMatch = 0; 415 m_nextItemToMatch = 0;
424 m_nextItemToIndex = 0; 416 m_nextItemToIndex = 0;
425 m_nextChunkToMatch = 0; 417 m_nextChunkToMatch = 0;
426 #if DCHECK_IS_ON()
427 m_underInvalidationCheckingBegin = 0; 418 m_underInvalidationCheckingBegin = 0;
428 m_underInvalidationCheckingEnd = 0; 419 m_underInvalidationCheckingEnd = 0;
429 m_skippedProbableUnderInvalidationCount = 0; 420 m_skippedProbableUnderInvalidationCount = 0;
430 #endif
431 } 421 }
432 422
433 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject) 423 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject)
434 { 424 {
435 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", 425 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems",
436 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(), 426 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(),
437 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems); 427 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems);
438 m_numCachedNewItems = 0; 428 m_numCachedNewItems = 0;
439 429
440 // These data structures are used during painting only. 430 // These data structures are used during painting only.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 } 476 }
487 477
488 // We'll allocate the initial buffer when we start the next paint. 478 // We'll allocate the initial buffer when we start the next paint.
489 m_newDisplayItemList = DisplayItemList(0); 479 m_newDisplayItemList = DisplayItemList(0);
490 480
491 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 481 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
492 CHECK(m_currentSubsequenceClients.isEmpty()); 482 CHECK(m_currentSubsequenceClients.isEmpty());
493 DisplayItemClient::endShouldKeepAliveAllClients(this); 483 DisplayItemClient::endShouldKeepAliveAllClients(this);
494 #endif 484 #endif
495 485
496 #if DCHECK_IS_ON() 486 #ifndef NDEBUG
497 m_numSequentialMatches = 0; 487 m_numSequentialMatches = 0;
498 m_numOutOfOrderMatches = 0; 488 m_numOutOfOrderMatches = 0;
499 m_numIndexedItems = 0; 489 m_numIndexedItems = 0;
500 #endif 490 #endif
501 } 491 }
502 492
503 size_t PaintController::approximateUnsharedMemoryUsage() const 493 size_t PaintController::approximateUnsharedMemoryUsage() const
504 { 494 {
505 size_t memoryUsage = sizeof(*this); 495 size_t memoryUsage = sizeof(*this);
506 496
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 if (newChunkClients.add(&newItem.client()).isNewEntry) 597 if (newChunkClients.add(&newItem.client()).isNewEntry)
608 newChunk.rasterInvalidationRects.append(newItem.client().vis ualRect()); 598 newChunk.rasterInvalidationRects.append(newItem.client().vis ualRect());
609 } else { 599 } else {
610 // The cached item was moved from the old chunk which should not contain any item of the client now. 600 // The cached item was moved from the old chunk which should not contain any item of the client now.
611 DCHECK(!oldChunkClients.contains(&newItem.client())); 601 DCHECK(!oldChunkClients.contains(&newItem.client()));
612 } 602 }
613 } 603 }
614 } 604 }
615 } 605 }
616 606
617 #if DCHECK_IS_ON()
618
619 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const 607 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const
620 { 608 {
621 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; 609 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason;
622 #ifndef NDEBUG 610 #ifndef NDEBUG
623 LOG(ERROR) << "New display item: " << newItem.asDebugString(); 611 LOG(ERROR) << "New display item: " << newItem.asDebugString();
624 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() : "None"); 612 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() : "None");
625 #else 613 #else
626 LOG(ERROR) << "Run debug build to get more details."; 614 LOG(ERROR) << "Run debug build to get more details.";
627 #endif 615 #endif
628 LOG(ERROR) << "See http://crbug.com/619103."; 616 LOG(ERROR) << "See http://crbug.com/619103.";
629 617
630 #ifndef NDEBUG 618 #ifndef NDEBUG
631 const SkPicture* newPicture = newItem.isDrawing() ? static_cast<const Drawin gDisplayItem&>(newItem).picture() : nullptr; 619 const SkPicture* newPicture = newItem.isDrawing() ? static_cast<const Drawin gDisplayItem&>(newItem).picture() : nullptr;
632 const SkPicture* oldPicture = oldItem && oldItem->isDrawing() ? static_cast< const DrawingDisplayItem*>(oldItem)->picture() : nullptr; 620 const SkPicture* oldPicture = oldItem && oldItem->isDrawing() ? static_cast< const DrawingDisplayItem*>(oldItem)->picture() : nullptr;
633 LOG(INFO) << "new picture:\n" << (newPicture ? pictureAsDebugString(newPictu re) : "None"); 621 LOG(INFO) << "new picture:\n" << (newPicture ? pictureAsDebugString(newPictu re) : "None");
634 LOG(INFO) << "old picture:\n" << (oldPicture ? pictureAsDebugString(oldPictu re) : "None"); 622 LOG(INFO) << "old picture:\n" << (oldPicture ? pictureAsDebugString(oldPictu re) : "None");
635 623
636 showDebugData(); 624 showDebugData();
637 #endif // NDEBUG 625 #endif // NDEBUG
638 } 626 }
639 627
640 void PaintController::checkUnderInvalidation() 628 void PaintController::checkUnderInvalidation()
641 { 629 {
642 DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 630 DCHECK(RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled());
643 631
644 if (!isCheckingUnderInvalidation()) 632 if (!isCheckingUnderInvalidation())
645 return; 633 return;
646 634
647 const DisplayItem& newItem = m_newDisplayItemList.last(); 635 const DisplayItem& newItem = m_newDisplayItemList.last();
648 size_t oldItemIndex = m_underInvalidationCheckingBegin + m_skippedProbableUn derInvalidationCount; 636 size_t oldItemIndex = m_underInvalidationCheckingBegin + m_skippedProbableUn derInvalidationCount;
649 DisplayItem* oldItem = oldItemIndex < m_currentPaintArtifact.getDisplayItemL ist().size() ? &m_currentPaintArtifact.getDisplayItemList()[oldItemIndex] : null ptr; 637 DisplayItem* oldItem = oldItemIndex < m_currentPaintArtifact.getDisplayItemL ist().size() ? &m_currentPaintArtifact.getDisplayItemList()[oldItemIndex] : null ptr;
650 638
651 bool oldAndNewEqual = oldItem && newItem.equals(*oldItem); 639 bool oldAndNewEqual = oldItem && newItem.equals(*oldItem);
652 if (!oldAndNewEqual) { 640 if (!oldAndNewEqual) {
(...skipping 11 matching lines...) Expand all
664 return; 652 return;
665 } 653 }
666 } 654 }
667 } 655 }
668 656
669 if (m_skippedProbableUnderInvalidationCount || !oldAndNewEqual) { 657 if (m_skippedProbableUnderInvalidationCount || !oldAndNewEqual) {
670 // If we ever skipped reporting any under-invalidations, report the earl iest one. 658 // If we ever skipped reporting any under-invalidations, report the earl iest one.
671 showUnderInvalidationError("under-invalidation: display item changed", 659 showUnderInvalidationError("under-invalidation: display item changed",
672 m_newDisplayItemList[m_newDisplayItemList.size() - m_skippedProbable UnderInvalidationCount - 1], 660 m_newDisplayItemList[m_newDisplayItemList.size() - m_skippedProbable UnderInvalidationCount - 1],
673 &m_currentPaintArtifact.getDisplayItemList()[m_underInvalidationChec kingBegin]); 661 &m_currentPaintArtifact.getDisplayItemList()[m_underInvalidationChec kingBegin]);
674 NOTREACHED(); 662 CHECK(false);
675 } 663 }
676 664
677 // Discard the forced repainted display item and move the cached item into m _newDisplayItemList. 665 // Discard the forced repainted display item and move the cached item into m _newDisplayItemList.
678 // This is to align with the non-under-invalidation-checking path to empty t he original cached slot, 666 // This is to align with the non-under-invalidation-checking path to empty t he original cached slot,
679 // leaving only disappeared or invalidated display items in the old list aft er painting. 667 // leaving only disappeared or invalidated display items in the old list aft er painting.
680 m_newDisplayItemList.removeLast(); 668 m_newDisplayItemList.removeLast();
681 m_newDisplayItemList.appendByMoving(*oldItem); 669 m_newDisplayItemList.appendByMoving(*oldItem);
682 670
683 ++m_underInvalidationCheckingBegin; 671 ++m_underInvalidationCheckingBegin;
684 } 672 }
685 673
686 #endif // DCHECK_IS_ON()
687
688 String PaintController::displayItemListAsDebugString(const DisplayItemList& list ) const 674 String PaintController::displayItemListAsDebugString(const DisplayItemList& list ) const
689 { 675 {
690 StringBuilder stringBuilder; 676 StringBuilder stringBuilder;
691 size_t i = 0; 677 size_t i = 0;
692 for (auto it = list.begin(); it != list.end(); ++it, ++i) { 678 for (auto it = list.begin(); it != list.end(); ++it, ++i) {
693 const DisplayItem& displayItem = *it; 679 const DisplayItem& displayItem = *it;
694 if (i) 680 if (i)
695 stringBuilder.append(",\n"); 681 stringBuilder.append(",\n");
696 stringBuilder.append(String::format("{index: %d, ", (int)i)); 682 stringBuilder.append(String::format("{index: %d, ", (int)i));
697 #ifndef NDEBUG 683 #ifndef NDEBUG
(...skipping 24 matching lines...) Expand all
722 return stringBuilder.toString(); 708 return stringBuilder.toString();
723 } 709 }
724 710
725 void PaintController::showDebugData() const 711 void PaintController::showDebugData() const
726 { 712 {
727 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); 713 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data());
728 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data()); 714 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data());
729 } 715 }
730 716
731 } // namespace blink 717 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698