| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "platform/graphics/paint/PaintController.h" | 6 #include "platform/graphics/paint/PaintController.h" |
| 7 | 7 |
| 8 #include "platform/NotImplemented.h" | 8 #include "platform/NotImplemented.h" |
| 9 #include "platform/TraceEvent.h" | 9 #include "platform/TraceEvent.h" |
| 10 #include "platform/graphics/GraphicsLayer.h" | 10 #include "platform/graphics/GraphicsLayer.h" |
| 11 #include "platform/graphics/paint/DisplayItemClient.h" |
| 11 #include "platform/graphics/paint/DrawingDisplayItem.h" | 12 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 12 | 13 |
| 13 #ifndef NDEBUG | 14 #ifndef NDEBUG |
| 14 #include "platform/graphics/LoggingCanvas.h" | 15 #include "platform/graphics/LoggingCanvas.h" |
| 15 #include "wtf/text/StringBuilder.h" | 16 #include "wtf/text/StringBuilder.h" |
| 16 #include <stdio.h> | 17 #include <stdio.h> |
| 17 #endif | 18 #endif |
| 18 | 19 |
| 19 namespace blink { | 20 namespace blink { |
| 20 | 21 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 void PaintController::endScope() | 115 void PaintController::endScope() |
| 115 { | 116 { |
| 116 m_scopeStack.removeLast(); | 117 m_scopeStack.removeLast(); |
| 117 endSkippingCache(); | 118 endSkippingCache(); |
| 118 } | 119 } |
| 119 | 120 |
| 120 void PaintController::invalidate(const DisplayItemClientWrapper& client, PaintIn
validationReason paintInvalidationReason, const IntRect* visualRect) | 121 void PaintController::invalidate(const DisplayItemClientWrapper& client, PaintIn
validationReason paintInvalidationReason, const IntRect* visualRect) |
| 121 { | 122 { |
| 122 invalidateClient(client); | 123 invalidateClient(client); |
| 123 | 124 |
| 124 if (visualRect) { | 125 if (!visualRect) |
| 125 // TODO(wkorman): cache visualRect for the client. | 126 return; |
| 126 } | 127 |
| 128 m_displayItemInvalidationRects.add(client.displayItemClient(), *visualRect); |
| 127 } | 129 } |
| 128 | 130 |
| 129 void PaintController::invalidateClient(const DisplayItemClientWrapper& client) | 131 void PaintController::invalidateClient(const DisplayItemClientWrapper& client) |
| 130 { | 132 { |
| 131 #if ENABLE(ASSERT) | 133 #if ENABLE(ASSERT) |
| 132 // Slimming paint v1 CompositedLayerMapping may invalidate client on extra l
ayers. | 134 // Slimming paint v1 CompositedLayerMapping may invalidate client on extra l
ayers. |
| 133 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() || clientCacheIsValid(c
lient.displayItemClient())) | 135 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() || clientCacheIsValid(c
lient.displayItemClient())) |
| 134 m_invalidations.append(client.debugName()); | 136 m_invalidations.append(client.debugName()); |
| 135 #endif | 137 #endif |
| 136 | 138 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 // The algorithm is O(|m_currentDisplayItemList| + |m_newDisplayItemList|). | 276 // The algorithm is O(|m_currentDisplayItemList| + |m_newDisplayItemList|). |
| 275 // Coefficients are related to the ratio of out-of-order CachedDisplayItems | 277 // Coefficients are related to the ratio of out-of-order CachedDisplayItems |
| 276 // and the average number of (Drawing|Subsequence)DisplayItems per client. | 278 // and the average number of (Drawing|Subsequence)DisplayItems per client. |
| 277 // | 279 // |
| 278 void PaintController::commitNewDisplayItems() | 280 void PaintController::commitNewDisplayItems() |
| 279 { | 281 { |
| 280 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", | 282 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", |
| 281 "current_display_list_size", (int)m_currentPaintArtifact.displayItemList
().size(), | 283 "current_display_list_size", (int)m_currentPaintArtifact.displayItemList
().size(), |
| 282 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach
edItems); | 284 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach
edItems); |
| 283 | 285 |
| 286 // showDebugData(); |
| 287 |
| 288 // TODO(wkorman): Remove entries from m_DisplayItemInvalidationRects for whi
ch their display items are no longer |
| 289 // present in the display item list. |
| 290 fprintf(stderr, "PaintController::commitNewDisplayItems [currentItems=%d, ne
wItems=%d, invalidationRects=%d].\n", |
| 291 (int)m_currentPaintArtifact.displayItemList().size(), |
| 292 (int)m_newDisplayItemList.size(), |
| 293 m_displayItemInvalidationRects.size()); |
| 294 |
| 284 if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled() | 295 if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled() |
| 285 && !m_newDisplayItemList.isEmpty() | 296 && !m_newDisplayItemList.isEmpty() |
| 286 && m_newDisplayItemList.last().type() == DisplayItem::CachedDisplayItemL
ist) { | 297 && m_newDisplayItemList.last().type() == DisplayItem::CachedDisplayItemL
ist) { |
| 287 // The whole display item list is cached. | 298 // The whole display item list is cached. |
| 288 ASSERT(m_newDisplayItemList.size() == 1); | 299 ASSERT(m_newDisplayItemList.size() == 1); |
| 289 ASSERT(m_invalidations.isEmpty()); | 300 ASSERT(m_invalidations.isEmpty()); |
| 290 ASSERT(m_clientsCheckedPaintInvalidation.isEmpty()); | 301 ASSERT(m_clientsCheckedPaintInvalidation.isEmpty()); |
| 291 m_newDisplayItemList.clear(); | 302 m_newDisplayItemList.clear(); |
| 292 m_newPaintChunks.clear(); | 303 m_newPaintChunks.clear(); |
| 293 return; | 304 return; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 319 } | 330 } |
| 320 | 331 |
| 321 updateValidlyCachedClientsIfNeeded(); | 332 updateValidlyCachedClientsIfNeeded(); |
| 322 | 333 |
| 323 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched | 334 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched |
| 324 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched | 335 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched |
| 325 // by later out-of-order CachedDisplayItems in m_newDisplayItemList. This en
sures that when | 336 // by later out-of-order CachedDisplayItems in m_newDisplayItemList. This en
sures that when |
| 326 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems | 337 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems |
| 327 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. | 338 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. |
| 328 OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.display
ItemList().begin()); | 339 OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.display
ItemList().begin()); |
| 329 | 340 HashSet<DisplayItemClient> allDisplayItemClients; |
| 330 // TODO(jbroman): Consider revisiting this heuristic. | 341 // TODO(jbroman): Consider revisiting this heuristic. |
| 331 DisplayItemList updatedList(std::max(m_currentPaintArtifact.displayItemList(
).usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes())); | 342 DisplayItemList updatedList(std::max(m_currentPaintArtifact.displayItemList(
).usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes())); |
| 332 Vector<PaintChunk> updatedPaintChunks; | 343 Vector<PaintChunk> updatedPaintChunks; |
| 333 DisplayItemList::iterator currentIt = m_currentPaintArtifact.displayItemList
().begin(); | 344 DisplayItemList::iterator currentIt = m_currentPaintArtifact.displayItemList
().begin(); |
| 334 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.displayItemLis
t().end(); | 345 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.displayItemLis
t().end(); |
| 335 for (DisplayItemList::iterator newIt = m_newDisplayItemList.begin(); newIt !
= m_newDisplayItemList.end(); ++newIt) { | 346 for (DisplayItemList::iterator newIt = m_newDisplayItemList.begin(); newIt !
= m_newDisplayItemList.end(); ++newIt) { |
| 336 const DisplayItem& newDisplayItem = *newIt; | 347 const DisplayItem& newDisplayItem = *newIt; |
| 337 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 348 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
| 338 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; | 349 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; |
| 339 | 350 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 356 // In this case, attempt to recover rather than crashing or
bailing on display of the rest of the display list. | 367 // In this case, attempt to recover rather than crashing or
bailing on display of the rest of the display list. |
| 357 continue; | 368 continue; |
| 358 } | 369 } |
| 359 } | 370 } |
| 360 #if ENABLE(ASSERT) | 371 #if ENABLE(ASSERT) |
| 361 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn
abled()) { | 372 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn
abled()) { |
| 362 DisplayItemList::iterator temp = currentIt; | 373 DisplayItemList::iterator temp = currentIt; |
| 363 checkUnderInvalidation(newIt, temp); | 374 checkUnderInvalidation(newIt, temp); |
| 364 } | 375 } |
| 365 #endif | 376 #endif |
| 377 |
| 378 allDisplayItemClients.add(currentIt->client()); |
| 379 |
| 366 if (newDisplayItem.isCachedDrawing()) { | 380 if (newDisplayItem.isCachedDrawing()) { |
| 367 updatedList.appendByMoving(*currentIt); | 381 updatedList.appendByMoving(*currentIt); |
| 368 ++currentIt; | 382 ++currentIt; |
| 369 } else { | 383 } else { |
| 370 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence); | 384 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence); |
| 371 copyCachedSubsequence(currentIt, updatedList); | 385 copyCachedSubsequence(currentIt, updatedList); |
| 372 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence)
; | 386 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence)
; |
| 373 } | 387 } |
| 374 } else { | 388 } else { |
| 375 ASSERT(!newDisplayItem.isDrawing() | 389 ASSERT(!newDisplayItem.isDrawing() |
| 376 || newDisplayItem.skippedCache() | 390 || newDisplayItem.skippedCache() |
| 377 || !clientCacheIsValid(newDisplayItem.client()) | 391 || !clientCacheIsValid(newDisplayItem.client()) |
| 378 || (RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled()
&& paintOffsetWasInvalidated(newDisplayItem.client()))); | 392 || (RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled()
&& paintOffsetWasInvalidated(newDisplayItem.client()))); |
| 379 | 393 |
| 394 if (newDisplayItem.client()) { |
| 395 allDisplayItemClients.add(newDisplayItem.client()); |
| 396 } else { |
| 397 // TODO(wkorman): Is this normal/expected as part of delete opti
mization? |
| 398 fprintf(stderr, "Null DisplayItemClient: %s\n", newDisplayItem.a
sDebugString().ascii().data()); |
| 399 } |
| 400 |
| 380 updatedList.appendByMoving(*newIt); | 401 updatedList.appendByMoving(*newIt); |
| 381 | 402 |
| 382 if (isSynchronized) | 403 if (isSynchronized) |
| 383 ++currentIt; | 404 ++currentIt; |
| 384 } | 405 } |
| 385 // Items before currentIt should have been copied so we don't need to in
dex them. | 406 // Items before currentIt should have been copied so we don't need to in
dex them. |
| 386 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) | 407 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) |
| 387 outOfOrderIndexContext.nextItemToIndex = currentIt; | 408 outOfOrderIndexContext.nextItemToIndex = currentIt; |
| 388 } | 409 } |
| 389 | 410 |
| 411 // TODO(wkorman): Rework this to remove through iteration directly. |
| 412 int staleRemoveCount = 0; |
| 413 Vector<DisplayItemClient> staleClients; |
| 414 for (DisplayItemClient client : m_displayItemInvalidationRects.keys()) { |
| 415 if (!allDisplayItemClients.contains(client)) { |
| 416 staleRemoveCount++; |
| 417 staleClients.append(client); |
| 418 IntRect visualRect = m_displayItemInvalidationRects.get(client); |
| 419 fprintf(stderr, "Removing stale invalidation rect [rect=(%d, %d, %d,
%d)].\n", |
| 420 visualRect.x(), visualRect.y(), visualRect.width(), visualRect.h
eight()); |
| 421 } |
| 422 } |
| 423 m_displayItemInvalidationRects.removeAll(staleClients); |
| 424 fprintf(stderr, "Cleaned invalidation rects [newItemClientCount=%d, invalida
tionRectCount=%d, staleRemoveCount=%d].\n", |
| 425 allDisplayItemClients.size(), |
| 426 m_displayItemInvalidationRects.size(), |
| 427 staleRemoveCount); |
| 428 |
| 390 #if ENABLE(ASSERT) | 429 #if ENABLE(ASSERT) |
| 391 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 430 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
| 392 checkNoRemainingCachedDisplayItems(); | 431 checkNoRemainingCachedDisplayItems(); |
| 393 #endif // ENABLE(ASSERT) | 432 #endif // ENABLE(ASSERT) |
| 394 | 433 |
| 395 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to | 434 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to |
| 396 // merge the paint chunks as well. | 435 // merge the paint chunks as well. |
| 397 m_currentPaintArtifact.displayItemList().swap(updatedList); | 436 m_currentPaintArtifact.displayItemList().swap(updatedList); |
| 398 m_currentPaintArtifact.paintChunks() = m_newPaintChunks.releasePaintChunks()
; | 437 m_currentPaintArtifact.paintChunks() = m_newPaintChunks.releasePaintChunks()
; |
| 399 | 438 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 | 608 |
| 570 void PaintController::showDebugData() const | 609 void PaintController::showDebugData() const |
| 571 { | 610 { |
| 572 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.displayItemList()).utf8().data()); | 611 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri
ng(m_currentPaintArtifact.displayItemList()).utf8().data()); |
| 573 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); | 612 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m
_newDisplayItemList).utf8().data()); |
| 574 } | 613 } |
| 575 | 614 |
| 576 #endif // ifndef NDEBUG | 615 #endif // ifndef NDEBUG |
| 577 | 616 |
| 578 } // namespace blink | 617 } // namespace blink |
| OLD | NEW |