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

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

Issue 2307623002: [SPv2] Defer decision of raster invalidation after paint for changes z-index, transform, etc. (Closed)
Patch Set: All paint property 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"
11 #include "wtf/AutoReset.h"
11 #include "wtf/text/StringBuilder.h" 12 #include "wtf/text/StringBuilder.h"
12 13
13 #ifndef NDEBUG 14 #ifndef NDEBUG
14 #include "platform/graphics/LoggingCanvas.h" 15 #include "platform/graphics/LoggingCanvas.h"
15 #include <stdio.h> 16 #include <stdio.h>
16 #endif 17 #endif
17 18
18 namespace blink { 19 namespace blink {
19 20
20 const PaintArtifact& PaintController::paintArtifact() const 21 const PaintArtifact& PaintController::paintArtifact() const
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 189 }
189 } 190 }
190 #endif 191 #endif
191 192
192 if (isSkippingCache()) { 193 if (isSkippingCache()) {
193 DCHECK(newItemSource == NewPainting); 194 DCHECK(newItemSource == NewPainting);
194 displayItem.setSkippedCache(); 195 displayItem.setSkippedCache();
195 } 196 }
196 197
197 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 198 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
198 if (newItemSource != FromCachedSubsequence)
199 m_currentChunkIsFromCachedSubsequence = false;
200
201 size_t lastChunkIndex = m_newPaintChunks.lastChunkIndex(); 199 size_t lastChunkIndex = m_newPaintChunks.lastChunkIndex();
202 if (m_newPaintChunks.incrementDisplayItemIndex(displayItem)) { 200 if (m_newPaintChunks.incrementDisplayItemIndex(displayItem)) {
203 DCHECK(lastChunkIndex != m_newPaintChunks.lastChunkIndex()); 201 DCHECK(lastChunkIndex != m_newPaintChunks.lastChunkIndex());
204 if (lastChunkIndex != kNotFound) 202 if (lastChunkIndex != kNotFound)
205 generateChunkRasterInvalidationRects(m_newPaintChunks.paintChunk At(lastChunkIndex)); 203 generateChunkRasterInvalidationRects(m_newPaintChunks.paintChunk At(lastChunkIndex));
206 m_currentChunkIsFromCachedSubsequence = true;
207 } 204 }
208 } 205 }
209 206
210 #if DCHECK_IS_ON() 207 #if DCHECK_IS_ON()
211 // Verify noop begin/end pairs have been removed. 208 // Verify noop begin/end pairs have been removed.
212 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { 209 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) {
213 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2]; 210 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2];
214 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::kSubsequence && !beginDisplayItem.drawsContent()) 211 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::kSubsequence && !beginDisplayItem.drawsContent())
215 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); 212 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType()));
216 } 213 }
217 214
218 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList); 215 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList);
219 if (index != kNotFound) { 216 if (index != kNotFound) {
220 #ifndef NDEBUG 217 #ifndef NDEBUG
221 showDebugData(); 218 showDebugData();
222 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n", 219 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% zu)\n",
223 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index)); 220 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), index);
224 #endif 221 #endif
225 NOTREACHED(); 222 NOTREACHED();
226 } 223 }
227 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient); 224 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient);
228 225
229 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) 226 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
230 checkUnderInvalidation(); 227 checkUnderInvalidation();
231 #endif // DCHECK_IS_ON() 228 #endif // DCHECK_IS_ON()
232 } 229 }
233 230
(...skipping 27 matching lines...) Expand all
261 258
262 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st IndicesByClientMap& displayItemIndicesByClient, const DisplayItemList& list) 259 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st IndicesByClientMap& displayItemIndicesByClient, const DisplayItemList& list)
263 { 260 {
264 IndicesByClientMap::const_iterator it = displayItemIndicesByClient.find(&id. client); 261 IndicesByClientMap::const_iterator it = displayItemIndicesByClient.find(&id. client);
265 if (it == displayItemIndicesByClient.end()) 262 if (it == displayItemIndicesByClient.end())
266 return kNotFound; 263 return kNotFound;
267 264
268 const Vector<size_t>& indices = it->value; 265 const Vector<size_t>& indices = it->value;
269 for (size_t index : indices) { 266 for (size_t index : indices) {
270 const DisplayItem& existingItem = list[index]; 267 const DisplayItem& existingItem = list[index];
271 DCHECK(!existingItem.hasValidClient() || existingItem.client() == id.cli ent); 268 if (existingItem.hasBeenMoved())
269 continue;
270 DCHECK(existingItem.client() == id.client);
272 if (id == existingItem.getId()) 271 if (id == existingItem.getId())
273 return index; 272 return index;
274 } 273 }
275 274
276 return kNotFound; 275 return kNotFound;
277 } 276 }
278 277
279 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, IndicesByClientMap& displayItemIndicesByClient) 278 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, IndicesByClientMap& displayItemIndicesByClient)
280 { 279 {
281 if (!displayItem.isCacheable()) 280 if (!displayItem.isCacheable())
282 return; 281 return;
283 282
284 IndicesByClientMap::iterator it = displayItemIndicesByClient.find(&displayIt em.client()); 283 IndicesByClientMap::iterator it = displayItemIndicesByClient.find(&displayIt em.client());
285 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? 284 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ?
286 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value; 285 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value;
287 indices.append(index); 286 indices.append(index);
288 } 287 }
289 288
290 size_t PaintController::findCachedItem(const DisplayItem::Id& id) 289 size_t PaintController::findCachedItem(const DisplayItem::Id& id)
291 { 290 {
292 DCHECK(clientCacheIsValid(id.client)); 291 DCHECK(clientCacheIsValid(id.client));
293 292
294 // Try to find the item sequentially first. This is fast if the current list and the new list are in 293 // 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. 294 // 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) { 295 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. 296 // 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] ; 297 const DisplayItem& item = m_currentPaintArtifact.getDisplayItemList()[i] ;
299 if (!item.hasValidClient()) 298 if (item.hasBeenMoved())
300 break; 299 break;
301 if (id == item.getId()) { 300 if (id == item.getId()) {
302 #if DCHECK_IS_ON() 301 #if DCHECK_IS_ON()
303 ++m_numSequentialMatches; 302 ++m_numSequentialMatches;
304 #endif 303 #endif
305 return i; 304 return i;
306 } 305 }
307 // We encounter a different cacheable item which also indicates we can't do sequential matching. 306 // We encounter a different cacheable item which also indicates we can't do sequential matching.
308 if (item.isCacheable()) 307 if (item.isCacheable())
309 break; 308 break;
310 } 309 }
311 310
312 size_t foundIndex = findMatchingItemFromIndex(id, m_outOfOrderItemIndices, m _currentPaintArtifact.getDisplayItemList()); 311 size_t foundIndex = findMatchingItemFromIndex(id, m_outOfOrderItemIndices, m _currentPaintArtifact.getDisplayItemList());
313 if (foundIndex != kNotFound) { 312 if (foundIndex != kNotFound) {
314 #if DCHECK_IS_ON() 313 #if DCHECK_IS_ON()
315 ++m_numOutOfOrderMatches; 314 ++m_numOutOfOrderMatches;
316 #endif 315 #endif
317 return foundIndex; 316 return foundIndex;
318 } 317 }
319 318
320 return findOutOfOrderCachedItemForward(id); 319 return findOutOfOrderCachedItemForward(id);
321 } 320 }
322 321
323 // Find forward for the item and index all skipped indexable items. 322 // Find forward for the item and index all skipped indexable items.
324 size_t PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& i d) 323 size_t PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& i d)
325 { 324 {
326 for (size_t i = m_nextItemToIndex; i < m_currentPaintArtifact.getDisplayItem List().size(); ++i) { 325 for (size_t i = m_nextItemToIndex; i < m_currentPaintArtifact.getDisplayItem List().size(); ++i) {
327 const DisplayItem& item = m_currentPaintArtifact.getDisplayItemList()[i] ; 326 const DisplayItem& item = m_currentPaintArtifact.getDisplayItemList()[i] ;
328 DCHECK(item.hasValidClient()); 327 DCHECK(!item.hasBeenMoved());
329 if (id == item.getId()) { 328 if (id == item.getId()) {
330 #if DCHECK_IS_ON() 329 #if DCHECK_IS_ON()
331 ++m_numSequentialMatches; 330 ++m_numSequentialMatches;
332 #endif 331 #endif
333 return i; 332 return i;
334 } 333 }
335 if (item.isCacheable()) { 334 if (item.isCacheable()) {
336 #if DCHECK_IS_ON() 335 #if DCHECK_IS_ON()
337 ++m_numIndexedItems; 336 ++m_numIndexedItems;
338 #endif 337 #endif
(...skipping 11 matching lines...) Expand all
350 // In this case, the caller should fall back to repaint the display item. 349 // In this case, the caller should fall back to repaint the display item.
351 return kNotFound; 350 return kNotFound;
352 } 351 }
353 352
354 // Copies a cached subsequence from current list to the new list. On return, 353 // 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. 354 // |cachedItemIndex| points to the item after the EndSubsequence item of the sub sequence.
356 // When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subs equence, 355 // When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subs equence,
357 // but mark the begin and end of the subsequence for under-invalidation checking . 356 // but mark the begin and end of the subsequence for under-invalidation checking .
358 void PaintController::copyCachedSubsequence(size_t& cachedItemIndex) 357 void PaintController::copyCachedSubsequence(size_t& cachedItemIndex)
359 { 358 {
359 AutoReset<size_t> subsequenceBeginIndex(&m_currentCachedSubsequenceBeginInde xInNewList, m_newDisplayItemList.size());
chrishtr 2016/09/06 22:14:12 What does changing to m_currentCachedSubsequenceBe
Xianzhu 2016/09/06 22:42:38 This replaces the original m_currentChunkIsFromCac
360 DisplayItem* cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cache dItemIndex]; 360 DisplayItem* cachedItem = &m_currentPaintArtifact.getDisplayItemList()[cache dItemIndex];
361 #if DCHECK_IS_ON() 361 #if DCHECK_IS_ON()
362 DCHECK(cachedItem->getType() == DisplayItem::kSubsequence); 362 DCHECK(cachedItem->getType() == DisplayItem::kSubsequence);
363 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) { 363 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
364 DCHECK(!isCheckingUnderInvalidation()); 364 DCHECK(!isCheckingUnderInvalidation());
365 m_underInvalidationCheckingBegin = cachedItemIndex; 365 m_underInvalidationCheckingBegin = cachedItemIndex;
366 m_underInvalidationMessagePrefix = "(In cached subsequence of " + cached Item->client().debugName() + ")"; 366 m_underInvalidationMessagePrefix = "(In cached subsequence of " + cached Item->client().debugName() + ")";
367 } 367 }
368 #endif 368 #endif
369 369
370 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::kEndSubs equence); 370 DisplayItem::Id endSubsequenceId(cachedItem->client(), DisplayItem::kEndSubs equence);
371 Vector<PaintChunk>::const_iterator cachedChunk; 371 Vector<PaintChunk>::const_iterator cachedChunk;
372 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 372 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
373 cachedChunk = m_currentPaintArtifact.findChunkByDisplayItemIndex(cachedI temIndex); 373 cachedChunk = m_currentPaintArtifact.findChunkByDisplayItemIndex(cachedI temIndex);
374 DCHECK(cachedChunk != m_currentPaintArtifact.paintChunks().end());
374 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChunk->id : nullptr, cachedChunk->properties); 375 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChunk->id : nullptr, cachedChunk->properties);
375 } else { 376 } else {
376 // This is to avoid compilation error about uninitialized variable on Wi ndows. 377 // This is to avoid compilation error about uninitialized variable on Wi ndows.
377 cachedChunk = m_currentPaintArtifact.paintChunks().begin(); 378 cachedChunk = m_currentPaintArtifact.paintChunks().begin();
378 } 379 }
379 380
380 while (true) { 381 while (true) {
381 DCHECK(cachedItem->hasValidClient()); 382 DCHECK(!cachedItem->hasBeenMoved());
382 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 383 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
383 CHECK(cachedItem->client().isAlive()); 384 CHECK(cachedItem->client().isAlive());
384 #endif 385 #endif
385 ++m_numCachedNewItems; 386 ++m_numCachedNewItems;
386 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId; 387 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId;
387 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali dationCheckingEnabled()) { 388 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali dationCheckingEnabled()) {
388 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) { 389 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) {
389 ++cachedChunk; 390 ++cachedChunk;
391 DCHECK(cachedChunk != m_currentPaintArtifact.paintChunks().end() );
390 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties); 392 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties);
391 } 393 }
392 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem), Fro mCachedSubsequence); 394 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem), Fro mCachedSubsequence);
393 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 395 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
394 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk)); 396 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk));
395 } 397 }
396 398
397 ++cachedItemIndex; 399 ++cachedItemIndex;
398 if (metEndSubsequence) 400 if (metEndSubsequence)
399 break; 401 break;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 DCHECK(m_newDisplayItemList.isEmpty()); 532 DCHECK(m_newDisplayItemList.isEmpty());
531 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList( ).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::kDebu gDrawing, picture); 533 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList( ).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::kDebu gDrawing, picture);
532 displayItem.setSkippedCache(); 534 displayItem.setSkippedCache();
533 // TODO(wkorman): Only compute and append visual rect for drawings. 535 // TODO(wkorman): Only compute and append visual rect for drawings.
534 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi splayItem(displayItem, offsetFromLayoutObject)); 536 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi splayItem(displayItem, offsetFromLayoutObject));
535 } 537 }
536 538
537 void PaintController::generateChunkRasterInvalidationRects(PaintChunk& newChunk) 539 void PaintController::generateChunkRasterInvalidationRects(PaintChunk& newChunk)
538 { 540 {
539 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 541 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
540 if (m_currentChunkIsFromCachedSubsequence) 542 if (newChunk.beginIndex >= m_currentCachedSubsequenceBeginIndexInNewList)
541 return; 543 return;
542 544
543 if (!newChunk.id) { 545 if (!newChunk.id) {
544 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIn tRect())); 546 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIn tRect()));
545 return; 547 return;
546 } 548 }
547 549
548 // Try to match old chunk sequentially first. 550 // Try to match old chunk sequentially first.
549 const auto& oldChunks = m_currentPaintArtifact.paintChunks(); 551 const auto& oldChunks = m_currentPaintArtifact.paintChunks();
550 while (m_nextChunkToMatch < oldChunks.size()) { 552 while (m_nextChunkToMatch < oldChunks.size()) {
(...skipping 26 matching lines...) Expand all
577 } 579 }
578 580
579 // We reach here because the chunk is new. 581 // We reach here because the chunk is new.
580 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIntRec t())); 582 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIntRec t()));
581 } 583 }
582 584
583 void PaintController::generateChunkRasterInvalidationRectsComparingOldChunk(Pain tChunk& newChunk, const PaintChunk& oldChunk) 585 void PaintController::generateChunkRasterInvalidationRectsComparingOldChunk(Pain tChunk& newChunk, const PaintChunk& oldChunk)
584 { 586 {
585 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 587 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
586 588
587 // TODO(wangxianzhu): Support raster invalidation for reordered display item s without invalidating
588 // display item clients. Currently we invalidate display item clients ensuri ng raster invalidation.
589 // TODO(wangxianzhu): Handle PaintInvalidationIncremental. 589 // TODO(wangxianzhu): Handle PaintInvalidationIncremental.
590 // TODO(wangxianzhu): Optimize paint offset change. 590 // TODO(wangxianzhu): Optimize paint offset change.
591 591
592 // Maps from each client to the index of the first drawing-content display i tem of the client. 592 HashSet<const DisplayItemClient*> invalidatedClientsInOldChunk;
593 HashMap<const DisplayItemClient*, size_t> oldChunkClients; 593 size_t highestMovedToIndex = 0;
594 for (size_t i = oldChunk.beginIndex; i < oldChunk.endIndex; ++i) { 594 for (size_t oldIndex = oldChunk.beginIndex; oldIndex < oldChunk.endIndex; ++ oldIndex) {
595 const DisplayItem& oldItem = m_currentPaintArtifact.getDisplayItemList() [i]; 595 const DisplayItem& oldItem = m_currentPaintArtifact.getDisplayItemList() [oldIndex];
596 // oldItem.hasValidClient() indicates that the item has not been copied as a cached item into 596 const DisplayItemClient* clientToInvalidate = nullptr;
597 // m_newDislayItemList, so the item either disappeared or changed, and n eeds raster invalidation. 597 if (oldItem.hasBeenMoved()) {
598 if (oldItem.hasValidClient() && oldItem.drawsContent() && oldChunkClient s.add(&oldItem.client(), i).isNewEntry) 598 size_t movedToIndex = oldItem.movedToIndex();
599 newChunk.rasterInvalidationRects.append(m_currentPaintArtifact.getDi splayItemList().visualRect(i)); 599 if (m_newDisplayItemList[movedToIndex].drawsContent()) {
600 if (movedToIndex < newChunk.beginIndex || movedToIndex >= newChu nk.endIndex) {
601 // The item has been moved into another chunk, so need to in validate it in the old chunk.
602 clientToInvalidate = &m_newDisplayItemList[movedToIndex].cli ent();
603 // And invalidate in the new chunk into which the item was m oved.
604 PaintChunk& movedToChunk = m_newPaintChunks.findChunkByDispl ayItemIndex(movedToIndex);
605 movedToChunk.rasterInvalidationRects.append(clientToInvalida te->visualRect());
606 } else if (movedToIndex < highestMovedToIndex) {
607 // The item has been moved behind other cached items, so nee d to invalidate the area
608 // that is probably exposed by the item.
chrishtr 2016/09/06 22:14:12 "exposed by the item moving earlier"
Xianzhu 2016/09/06 22:42:38 Done.
609 clientToInvalidate = &m_newDisplayItemList[movedToIndex].cli ent();
610 } else {
611 highestMovedToIndex = movedToIndex;
612 }
613 }
614 } else if (oldItem.drawsContent()) {
615 clientToInvalidate = &oldItem.client();
616 }
617 if (clientToInvalidate && invalidatedClientsInOldChunk.add(clientToInval idate).isNewEntry) {
618 newChunk.rasterInvalidationRects.append(m_currentPaintArtifact.getDi splayItemList().visualRect(oldIndex));
619 }
600 } 620 }
601 621
602 HashSet<const DisplayItemClient*> newChunkClients; 622 HashSet<const DisplayItemClient*> invalidatedClientsInNewChunk;
603 for (size_t i = newChunk.beginIndex; i < newChunk.endIndex; ++i) { 623 for (size_t newIndex = newChunk.beginIndex; newIndex < newChunk.endIndex; ++ newIndex) {
604 const DisplayItem& newItem = m_newDisplayItemList[i]; 624 const DisplayItem& newItem = m_newDisplayItemList[newIndex];
605 if (newItem.drawsContent()) { 625 if (newItem.drawsContent() && !clientCacheIsValid(newItem.client()) && i nvalidatedClientsInNewChunk.add(&newItem.client()).isNewEntry)
606 if (!clientCacheIsValid(newItem.client())) { 626 newChunk.rasterInvalidationRects.append(newItem.client().visualRect( ));
607 if (newChunkClients.add(&newItem.client()).isNewEntry)
608 newChunk.rasterInvalidationRects.append(newItem.client().vis ualRect());
609 } else {
610 // 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()));
612 }
613 }
614 } 627 }
615 } 628 }
616 629
617 #if DCHECK_IS_ON() 630 #if DCHECK_IS_ON()
618 631
619 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const 632 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const
620 { 633 {
621 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; 634 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason;
622 #ifndef NDEBUG 635 #ifndef NDEBUG
623 LOG(ERROR) << "New display item: " << newItem.asDebugString(); 636 LOG(ERROR) << "New display item: " << newItem.asDebugString();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 #endif // DCHECK_IS_ON() 699 #endif // DCHECK_IS_ON()
687 700
688 String PaintController::displayItemListAsDebugString(const DisplayItemList& list ) const 701 String PaintController::displayItemListAsDebugString(const DisplayItemList& list ) const
689 { 702 {
690 StringBuilder stringBuilder; 703 StringBuilder stringBuilder;
691 size_t i = 0; 704 size_t i = 0;
692 for (auto it = list.begin(); it != list.end(); ++it, ++i) { 705 for (auto it = list.begin(); it != list.end(); ++it, ++i) {
693 const DisplayItem& displayItem = *it; 706 const DisplayItem& displayItem = *it;
694 if (i) 707 if (i)
695 stringBuilder.append(",\n"); 708 stringBuilder.append(",\n");
696 stringBuilder.append(String::format("{index: %d, ", (int)i)); 709 stringBuilder.append(String::format("{index: %zu, ", i));
697 #ifndef NDEBUG 710 #ifndef NDEBUG
698 displayItem.dumpPropertiesAsDebugString(stringBuilder); 711 displayItem.dumpPropertiesAsDebugString(stringBuilder);
699 #else 712 #else
700 stringBuilder.append(String::format("clientDebugName: %s", displayItem.c lient().debugName().ascii().data())); 713 stringBuilder.append(String::format("clientDebugName: %s", displayItem.c lient().debugName().ascii().data()));
701 #endif 714 #endif
702 if (displayItem.hasValidClient()) { 715 if (!displayItem.hasBeenMoved()) {
703 do { 716 do {
704 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 717 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
705 if (!displayItem.client().isAlive()) { 718 if (!displayItem.client().isAlive()) {
706 stringBuilder.append(", clientIsAlive: false"); 719 stringBuilder.append(", clientIsAlive: false");
707 break; 720 break;
708 } 721 }
709 #endif 722 #endif
710 stringBuilder.append(", cacheIsValid: "); 723 stringBuilder.append(", cacheIsValid: ");
711 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" : "false"); 724 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" : "false");
712 } while (false); 725 } while (false);
713 } 726 }
714 if (list.hasVisualRect(i)) { 727 if (list.hasVisualRect(i)) {
715 IntRect visualRect = list.visualRect(i); 728 IntRect visualRect = list.visualRect(i);
716 stringBuilder.append(String::format(", visualRect: [%d,%d %dx%d]", 729 stringBuilder.append(String::format(", visualRect: [%d,%d %dx%d]",
717 visualRect.x(), visualRect.y(), 730 visualRect.x(), visualRect.y(),
718 visualRect.width(), visualRect.height())); 731 visualRect.width(), visualRect.height()));
719 } 732 }
720 stringBuilder.append('}'); 733 stringBuilder.append('}');
721 } 734 }
722 return stringBuilder.toString(); 735 return stringBuilder.toString();
723 } 736 }
724 737
725 void PaintController::showDebugData() const 738 void PaintController::showDebugData() const
726 { 739 {
727 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); 740 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()); 741 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data());
729 } 742 }
730 743
731 } // namespace blink 744 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698