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

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

Issue 2277443003: [SPv2] Rasterization invalidation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: - 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 size_t cachedItem = findCachedItem(DisplayItem::Id(client, type)); 45 size_t cachedItem = findCachedItem(DisplayItem::Id(client, type));
46 if (cachedItem == kNotFound) { 46 if (cachedItem == kNotFound) {
47 NOTREACHED(); 47 NOTREACHED();
48 return false; 48 return false;
49 } 49 }
50 50
51 ++m_numCachedNewItems; 51 ++m_numCachedNewItems;
52 ensureNewDisplayItemListInitialCapacity(); 52 ensureNewDisplayItemListInitialCapacity();
53 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidati onCheckingEnabled()) 53 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidati onCheckingEnabled())
54 processNewItem(m_newDisplayItemList.appendByMoving(m_currentPaintArtifac t.getDisplayItemList()[cachedItem])); 54 processNewItem(m_newDisplayItemList.appendByMoving(m_currentPaintArtifac t.getDisplayItemList()[cachedItem]), FromCachedItem);
55 55
56 m_nextItemToMatch = cachedItem + 1; 56 m_nextItemToMatch = cachedItem + 1;
57 // Items before m_nextItemToMatch have been copied so we don't need to index them. 57 // Items before m_nextItemToMatch have been copied so we don't need to index them.
58 if (m_nextItemToMatch > m_nextItemToIndex) 58 if (m_nextItemToMatch > m_nextItemToIndex)
59 m_nextItemToIndex = m_nextItemToMatch; 59 m_nextItemToIndex = m_nextItemToMatch;
60 60
61 #if DCHECK_IS_ON() 61 #if DCHECK_IS_ON()
62 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) { 62 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
63 if (!isCheckingUnderInvalidation()) { 63 if (!isCheckingUnderInvalidation()) {
64 m_underInvalidationCheckingBegin = cachedItem; 64 m_underInvalidationCheckingBegin = cachedItem;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); 126 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent();
127 } 127 }
128 128
129 void PaintController::removeLastDisplayItem() 129 void PaintController::removeLastDisplayItem()
130 { 130 {
131 if (m_newDisplayItemList.isEmpty()) 131 if (m_newDisplayItemList.isEmpty())
132 return; 132 return;
133 133
134 #if DCHECK_IS_ON() 134 #if DCHECK_IS_ON()
135 // Also remove the index pointing to the removed display item. 135 // Also remove the index pointing to the removed display item.
136 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient .find(&m_newDisplayItemList.last().client()); 136 IndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient.find(&m_ne wDisplayItemList.last().client());
137 if (it != m_newDisplayItemIndicesByClient.end()) { 137 if (it != m_newDisplayItemIndicesByClient.end()) {
138 Vector<size_t>& indices = it->value; 138 Vector<size_t>& indices = it->value;
139 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1)) 139 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1))
140 indices.removeLast(); 140 indices.removeLast();
141 } 141 }
142 142
143 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) { 143 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) {
144 if (m_skippedProbableUnderInvalidationCount) { 144 if (m_skippedProbableUnderInvalidationCount) {
145 --m_skippedProbableUnderInvalidationCount; 145 --m_skippedProbableUnderInvalidationCount;
146 } else { 146 } else {
147 DCHECK(m_underInvalidationCheckingBegin); 147 DCHECK(m_underInvalidationCheckingBegin);
148 --m_underInvalidationCheckingBegin; 148 --m_underInvalidationCheckingBegin;
149 } 149 }
150 } 150 }
151 #endif 151 #endif
152 m_newDisplayItemList.removeLast(); 152 m_newDisplayItemList.removeLast();
153 153
154 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 154 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
155 m_newPaintChunks.decrementDisplayItemIndex(); 155 m_newPaintChunks.decrementDisplayItemIndex();
156 } 156 }
157 157
158 const DisplayItem* PaintController::lastDisplayItem(unsigned offset) 158 const DisplayItem* PaintController::lastDisplayItem(unsigned offset)
159 { 159 {
160 if (offset < m_newDisplayItemList.size()) 160 if (offset < m_newDisplayItemList.size())
161 return &m_newDisplayItemList[m_newDisplayItemList.size() - offset - 1]; 161 return &m_newDisplayItemList[m_newDisplayItemList.size() - offset - 1];
162 return nullptr; 162 return nullptr;
163 } 163 }
164 164
165 void PaintController::processNewItem(DisplayItem& displayItem) 165 void PaintController::processNewItem(DisplayItem& displayItem, NewItemSource new ItemSource)
166 { 166 {
167 DCHECK(!m_constructionDisabled); 167 DCHECK(!m_constructionDisabled);
168 168
169 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 169 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
170 if (!isSkippingCache()) { 170 if (!isSkippingCache()) {
171 if (displayItem.isCacheable()) { 171 if (displayItem.isCacheable()) {
172 // Mark the client shouldKeepAlive under this PaintController. 172 // Mark the client shouldKeepAlive under this PaintController.
173 // The status will end after the new display items are committed. 173 // The status will end after the new display items are committed.
174 displayItem.client().beginShouldKeepAlive(this); 174 displayItem.client().beginShouldKeepAlive(this);
175 175
176 if (!m_currentSubsequenceClients.isEmpty()) { 176 if (!m_currentSubsequenceClients.isEmpty()) {
177 // Mark the client shouldKeepAlive under the current subsequence . 177 // Mark the client shouldKeepAlive under the current subsequence .
178 // The status will end when the subsequence owner is invalidated or deleted. 178 // The status will end when the subsequence owner is invalidated or deleted.
179 displayItem.client().beginShouldKeepAlive(m_currentSubsequenceCl ients.last()); 179 displayItem.client().beginShouldKeepAlive(m_currentSubsequenceCl ients.last());
180 } 180 }
181 } 181 }
182 182
183 if (displayItem.getType() == DisplayItem::Subsequence) { 183 if (displayItem.getType() == DisplayItem::Subsequence) {
184 m_currentSubsequenceClients.append(&displayItem.client()); 184 m_currentSubsequenceClients.append(&displayItem.client());
185 } else if (displayItem.getType() == DisplayItem::EndSubsequence) { 185 } else if (displayItem.getType() == DisplayItem::EndSubsequence) {
186 CHECK(m_currentSubsequenceClients.last() == &displayItem.client()); 186 CHECK(m_currentSubsequenceClients.last() == &displayItem.client());
187 m_currentSubsequenceClients.removeLast(); 187 m_currentSubsequenceClients.removeLast();
188 } 188 }
189 } 189 }
190 #endif 190 #endif
191 191
192 if (isSkippingCache()) 192 if (isSkippingCache()) {
193 DCHECK(newItemSource == NewPainting);
193 displayItem.setSkippedCache(); 194 displayItem.setSkippedCache();
195 }
196
197 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
198 if (newItemSource != FromCachedSubsequence)
199 m_currentChunkIsFromCachedSubsequence = false;
200
201 size_t lastChunkIndex = m_newPaintChunks.lastChunkIndex();
202 if (m_newPaintChunks.incrementDisplayItemIndex(displayItem)) {
203 DCHECK(lastChunkIndex != m_newPaintChunks.lastChunkIndex());
204 if (lastChunkIndex != kNotFound)
205 generateChunkRerasterizationRects(m_newPaintChunks.paintChunkAt( lastChunkIndex));
206 m_currentChunkIsFromCachedSubsequence = true;
207 }
208 }
194 209
195 #if DCHECK_IS_ON() 210 #if DCHECK_IS_ON()
196 // Verify noop begin/end pairs have been removed. 211 // Verify noop begin/end pairs have been removed.
197 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { 212 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) {
198 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2]; 213 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2];
199 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::Subsequence && !beginDisplayItem.drawsContent()) 214 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::Subsequence && !beginDisplayItem.drawsContent())
200 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); 215 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType()));
201 } 216 }
202 217
203 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList); 218 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList);
204 if (index != kNotFound) { 219 if (index != kNotFound) {
205 #ifndef NDEBUG 220 #ifndef NDEBUG
206 showDebugData(); 221 showDebugData();
207 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n", 222 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n",
208 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index)); 223 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index));
209 #endif 224 #endif
210 NOTREACHED(); 225 NOTREACHED();
211 } 226 }
212 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient); 227 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient);
213 228
214 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) 229 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
215 checkUnderInvalidation(); 230 checkUnderInvalidation();
216 #endif // DCHECK_IS_ON() 231 #endif // DCHECK_IS_ON()
217
218 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
219 m_newPaintChunks.incrementDisplayItemIndex(displayItem);
220 } 232 }
221 233
222 void PaintController::updateCurrentPaintChunkProperties(const PaintChunk::Id* id , const PaintChunkProperties& newProperties) 234 void PaintController::updateCurrentPaintChunkProperties(const PaintChunk::Id* id , const PaintChunkProperties& newProperties)
223 { 235 {
224 m_newPaintChunks.updateCurrentPaintChunkProperties(id, newProperties); 236 m_newPaintChunks.updateCurrentPaintChunkProperties(id, newProperties);
225 } 237 }
226 238
227 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const 239 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const
228 { 240 {
229 return m_newPaintChunks.currentPaintChunkProperties(); 241 return m_newPaintChunks.currentPaintChunkProperties();
(...skipping 10 matching lines...) Expand all
240 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const 252 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const
241 { 253 {
242 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 254 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
243 CHECK(client.isAlive()); 255 CHECK(client.isAlive());
244 #endif 256 #endif
245 if (isSkippingCache()) 257 if (isSkippingCache())
246 return false; 258 return false;
247 return client.displayItemsAreCached(m_currentCacheGeneration); 259 return client.displayItemsAreCached(m_currentCacheGeneration);
248 } 260 }
249 261
250 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItemL ist& list) 262 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st IndicesByClientMap& displayItemIndicesByClient, const DisplayItemList& list)
251 { 263 {
252 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(&id.client); 264 IndicesByClientMap::const_iterator it = displayItemIndicesByClient.find(&id. client);
253 if (it == displayItemIndicesByClient.end()) 265 if (it == displayItemIndicesByClient.end())
254 return kNotFound; 266 return kNotFound;
255 267
256 const Vector<size_t>& indices = it->value; 268 const Vector<size_t>& indices = it->value;
257 for (size_t index : indices) { 269 for (size_t index : indices) {
258 const DisplayItem& existingItem = list[index]; 270 const DisplayItem& existingItem = list[index];
259 DCHECK(!existingItem.hasValidClient() || existingItem.client() == id.cli ent); 271 DCHECK(!existingItem.hasValidClient() || existingItem.client() == id.cli ent);
260 if (id == existingItem.getId()) 272 if (id == existingItem.getId())
261 return index; 273 return index;
262 } 274 }
263 275
264 return kNotFound; 276 return kNotFound;
265 } 277 }
266 278
267 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient) 279 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, IndicesByClientMap& displayItemIndicesByClient)
268 { 280 {
269 if (!displayItem.isCacheable()) 281 if (!displayItem.isCacheable())
270 return; 282 return;
271 283
272 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find (&displayItem.client()); 284 IndicesByClientMap::iterator it = displayItemIndicesByClient.find(&displayIt em.client());
273 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? 285 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ?
274 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value; 286 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value;
275 indices.append(index); 287 indices.append(index);
276 } 288 }
277 289
278 size_t PaintController::findCachedItem(const DisplayItem::Id& id) 290 size_t PaintController::findCachedItem(const DisplayItem::Id& id)
279 { 291 {
280 DCHECK(clientCacheIsValid(id.client)); 292 DCHECK(clientCacheIsValid(id.client));
281 293
282 // Try to find the item sequentially first. This is fast if the current list and the new list are in 294 // Try to find the item sequentially first. This is fast if the current list and the new list are in
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 382 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
371 CHECK(cachedItem->client().isAlive()); 383 CHECK(cachedItem->client().isAlive());
372 #endif 384 #endif
373 ++m_numCachedNewItems; 385 ++m_numCachedNewItems;
374 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId; 386 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId;
375 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali dationCheckingEnabled()) { 387 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali dationCheckingEnabled()) {
376 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) { 388 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) {
377 ++cachedChunk; 389 ++cachedChunk;
378 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties); 390 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties);
379 } 391 }
380 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem)); 392 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem), Fro mCachedSubsequence);
381 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 393 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
382 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk)); 394 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk));
383 } 395 }
384 396
385 ++cachedItemIndex; 397 ++cachedItemIndex;
386 if (metEndSubsequence) 398 if (metEndSubsequence)
387 break; 399 break;
388 400
389 // We should always be able to find the EndSubsequence display item. 401 // We should always be able to find the EndSubsequence display item.
390 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz e()); 402 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz e());
(...skipping 12 matching lines...) Expand all
403 { 415 {
404 LayoutRect visualRect = displayItem.client().visualRect(); 416 LayoutRect visualRect = displayItem.client().visualRect();
405 visualRect.move(-offsetFromLayoutObject); 417 visualRect.move(-offsetFromLayoutObject);
406 return enclosingIntRect(visualRect); 418 return enclosingIntRect(visualRect);
407 } 419 }
408 420
409 void PaintController::resetCurrentListIndices() 421 void PaintController::resetCurrentListIndices()
410 { 422 {
411 m_nextItemToMatch = 0; 423 m_nextItemToMatch = 0;
412 m_nextItemToIndex = 0; 424 m_nextItemToIndex = 0;
425 m_nextChunkToMatch = 0;
413 #if DCHECK_IS_ON() 426 #if DCHECK_IS_ON()
414 m_underInvalidationCheckingBegin = 0; 427 m_underInvalidationCheckingBegin = 0;
415 m_underInvalidationCheckingEnd = 0; 428 m_underInvalidationCheckingEnd = 0;
416 m_skippedProbableUnderInvalidationCount = 0; 429 m_skippedProbableUnderInvalidationCount = 0;
417 #endif 430 #endif
418 } 431 }
419 432
420 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject) 433 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject)
421 { 434 {
422 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", 435 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems",
423 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(), 436 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(),
424 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems); 437 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems);
425 m_numCachedNewItems = 0; 438 m_numCachedNewItems = 0;
426 439
427 // These data structures are used during painting only. 440 // These data structures are used during painting only.
428 DCHECK(!isSkippingCache()); 441 DCHECK(!isSkippingCache());
429 #if DCHECK_IS_ON() 442 #if DCHECK_IS_ON()
430 m_newDisplayItemIndicesByClient.clear(); 443 m_newDisplayItemIndicesByClient.clear();
431 #endif 444 #endif
432 445
446 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && !m_newDisplayItemLis t.isEmpty())
447 generateChunkRerasterizationRects(m_newPaintChunks.lastChunk());
448
433 SkPictureGpuAnalyzer gpuAnalyzer; 449 SkPictureGpuAnalyzer gpuAnalyzer;
434 450
435 m_currentCacheGeneration = DisplayItemClient::CacheGenerationOrInvalidationR eason::next(); 451 m_currentCacheGeneration = DisplayItemClient::CacheGenerationOrInvalidationR eason::next();
436 Vector<const DisplayItemClient*> skippedCacheClients; 452 Vector<const DisplayItemClient*> skippedCacheClients;
437 for (const auto& item : m_newDisplayItemList) { 453 for (const auto& item : m_newDisplayItemList) {
438 // No reason to continue the analysis once we have a veto. 454 // No reason to continue the analysis once we have a veto.
439 if (gpuAnalyzer.suitableForGpuRasterization()) 455 if (gpuAnalyzer.suitableForGpuRasterization())
440 item.analyzeForGpuRasterization(gpuAnalyzer); 456 item.analyzeForGpuRasterization(gpuAnalyzer);
441 457
442 // TODO(wkorman): Only compute and append visual rect for drawings. 458 // TODO(wkorman): Only compute and append visual rect for drawings.
(...skipping 10 matching lines...) Expand all
453 } 469 }
454 470
455 for (auto* client : skippedCacheClients) 471 for (auto* client : skippedCacheClients)
456 client->setDisplayItemsUncached(); 472 client->setDisplayItemsUncached();
457 473
458 // The new list will not be appended to again so we can release unused memor y. 474 // The new list will not be appended to again so we can release unused memor y.
459 m_newDisplayItemList.shrinkToFit(); 475 m_newDisplayItemList.shrinkToFit();
460 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_ne wPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization()); 476 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_ne wPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization());
461 resetCurrentListIndices(); 477 resetCurrentListIndices();
462 m_outOfOrderItemIndices.clear(); 478 m_outOfOrderItemIndices.clear();
479 m_outOfOrderChunkIndices.clear();
463 480
464 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 481 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
465 for (const auto& chunk : m_currentPaintArtifact.paintChunks()) { 482 for (const auto& chunk : m_currentPaintArtifact.paintChunks()) {
466 if (chunk.id && chunk.id->client.isJustCreated()) 483 if (chunk.id && chunk.id->client.isJustCreated())
467 chunk.id->client.clearIsJustCreated(); 484 chunk.id->client.clearIsJustCreated();
468 } 485 }
469 } 486 }
470 487
471 // We'll allocate the initial buffer when we start the next paint. 488 // We'll allocate the initial buffer when we start the next paint.
472 m_newDisplayItemList = DisplayItemList(0); 489 m_newDisplayItemList = DisplayItemList(0);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 527
511 void PaintController::appendDebugDrawingAfterCommit(const DisplayItemClient& dis playItemClient, PassRefPtr<SkPicture> picture, const LayoutSize& offsetFromLayou tObject) 528 void PaintController::appendDebugDrawingAfterCommit(const DisplayItemClient& dis playItemClient, PassRefPtr<SkPicture> picture, const LayoutSize& offsetFromLayou tObject)
512 { 529 {
513 DCHECK(m_newDisplayItemList.isEmpty()); 530 DCHECK(m_newDisplayItemList.isEmpty());
514 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList( ).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::Debug Drawing, picture); 531 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList( ).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::Debug Drawing, picture);
515 displayItem.setSkippedCache(); 532 displayItem.setSkippedCache();
516 // TODO(wkorman): Only compute and append visual rect for drawings. 533 // TODO(wkorman): Only compute and append visual rect for drawings.
517 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi splayItem(displayItem, offsetFromLayoutObject)); 534 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi splayItem(displayItem, offsetFromLayoutObject));
518 } 535 }
519 536
537 void PaintController::generateChunkRerasterizationRects(PaintChunk& newChunk)
538 {
539 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
540 if (m_currentChunkIsFromCachedSubsequence)
541 return;
542
543 if (!newChunk.id) {
chrishtr 2016/08/26 18:10:51 Why would there be no id?
Xianzhu 2016/08/26 18:39:23 Please see https://cs.chromium.org/chromium/src/th
544 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIn tRect()));
545 return;
546 }
547
548 // Try to match old chunk sequentially first.
549 const auto& oldChunks = m_currentPaintArtifact.paintChunks();
550 while (m_nextChunkToMatch < oldChunks.size()) {
551 const PaintChunk& oldChunk = oldChunks[m_nextChunkToMatch];
552 if (newChunk.matches(oldChunk)) {
553 generateChunkRerasterizationRectsComparingOldChunk(newChunk, oldChun k);
554 ++m_nextChunkToMatch;
555 return;
556 }
557
558 // Add skipped old chunks into the index.
559 if (oldChunk.id) {
560 auto it = m_outOfOrderChunkIndices.find(&oldChunk.id->client);
561 Vector<size_t>& indices = it == m_outOfOrderChunkIndices.end() ?
562 m_outOfOrderChunkIndices.add(&oldChunk.id->client, Vector<size_t >()).storedValue->value : it->value;
563 indices.append(m_nextChunkToMatch);
564 }
565 ++m_nextChunkToMatch;
566 }
567
568 // Sequential matching reaches the end. Find from the out-of-order index.
569 auto it = m_outOfOrderChunkIndices.find(&newChunk.id->client);
570 if (it != m_outOfOrderChunkIndices.end()) {
571 for (size_t i : it->value) {
572 if (newChunk.matches(oldChunks[i])) {
573 generateChunkRerasterizationRectsComparingOldChunk(newChunk, old Chunks[i]);
574 return;
575 }
576 }
577 }
578
579 // We reach here because the chunk is new.
580 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIntRec t()));
581 }
582
583 void PaintController::generateChunkRerasterizationRectsComparingOldChunk(PaintCh unk& newChunk, const PaintChunk& oldChunk)
584 {
585 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
586
587 // TODO(wangxianzhu): Support raster invalidation for recordered display ite ms without invalidating
chrishtr 2016/08/26 18:10:51 Do you mean "reordered"? What is an example where
Xianzhu 2016/08/26 18:39:23 Yes :) An example is z-index change: actually we d
588 // display item clients. Currently we invalidate display item clients ensuri ng raster invalidation.
589
590 // Maps from each client to the index of the first drawing-content display i tem of the client.
591 HashMap<const DisplayItemClient*, size_t> oldChunkClients;
592 for (size_t i = oldChunk.beginIndex; i < oldChunk.endIndex; ++i) {
593 const DisplayItem& oldItem = m_currentPaintArtifact.getDisplayItemList() [i];
594 if (oldItem.hasValidClient() && oldItem.drawsContent())
595 oldChunkClients.add(&oldItem.client(), i);
596 }
597
598 HashSet<const DisplayItemClient*> newChunkClients;
599 for (size_t i = newChunk.beginIndex; i < newChunk.endIndex; ++i) {
600 const DisplayItem& newItem = m_newDisplayItemList[i];
601 if (newItem.drawsContent()) {
602 if (!newItem.client().isJustCreated() && newItem.client().getPaintIn validationReason() == PaintInvalidationNone)
chrishtr 2016/08/26 18:10:51 This is to check for cached items?
Xianzhu 2016/08/26 18:39:23 Yes. Changed to clientCacheIsValid(newItem.client(
603 oldChunkClients.remove(&newItem.client());
604 else
605 newChunkClients.add(&newItem.client());
606 }
607 }
608
609 // TODO(wangxianzhu): Handle PaintInvalidationIncremental and optimize paint offset change.
610 for (const DisplayItemClient* client : newChunkClients)
611 newChunk.rasterInvalidationRects.append(client->visualRect());
612 for (const auto& oldChunkClientInfo : oldChunkClients)
613 newChunk.rasterInvalidationRects.append(m_currentPaintArtifact.getDispla yItemList().visualRect(oldChunkClientInfo.value));
614 }
615
520 #if DCHECK_IS_ON() 616 #if DCHECK_IS_ON()
521 617
522 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const 618 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const
523 { 619 {
524 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; 620 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason;
525 #ifndef NDEBUG 621 #ifndef NDEBUG
526 LOG(ERROR) << "New display item: " << newItem.asDebugString(); 622 LOG(ERROR) << "New display item: " << newItem.asDebugString();
527 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() : "None"); 623 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() : "None");
528 #else 624 #else
529 LOG(ERROR) << "Run debug build to get more details."; 625 LOG(ERROR) << "Run debug build to get more details.";
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 return stringBuilder.toString(); 707 return stringBuilder.toString();
612 } 708 }
613 709
614 void PaintController::showDebugData() const 710 void PaintController::showDebugData() const
615 { 711 {
616 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); 712 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data());
617 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data()); 713 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data());
618 } 714 }
619 715
620 } // namespace blink 716 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698