| 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 "platform/graphics/paint/PaintController.h" | 5 #include "platform/graphics/paint/PaintController.h" |
| 6 | 6 |
| 7 #include "platform/NotImplemented.h" | 7 #include "platform/NotImplemented.h" |
| 8 #include "platform/TraceEvent.h" | 8 #include "platform/TraceEvent.h" |
| 9 #include "platform/graphics/GraphicsLayer.h" | 9 #include "platform/graphics/GraphicsLayer.h" |
| 10 #include "platform/graphics/paint/DrawingDisplayItem.h" | 10 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 m_scopeStack.append(m_nextScope++); | 109 m_scopeStack.append(m_nextScope++); |
| 110 beginSkippingCache(); | 110 beginSkippingCache(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 void PaintController::endScope() | 113 void PaintController::endScope() |
| 114 { | 114 { |
| 115 m_scopeStack.removeLast(); | 115 m_scopeStack.removeLast(); |
| 116 endSkippingCache(); | 116 endSkippingCache(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 void PaintController::invalidate(const DisplayItemClient& client) | 119 void PaintController::invalidate(const DisplayItemClient& client, PaintInvalidat
ionReason paintInvalidationReason, const IntRect& previousPaintInvalidationRect,
const IntRect& newPaintInvalidationRect) |
| 120 { | 120 { |
| 121 #if ENABLE(ASSERT) | |
| 122 // Slimming paint v1 CompositedLayerMapping may invalidate client on extra l
ayers. | |
| 123 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() || clientCacheIsValid(c
lient)) | |
| 124 m_invalidations.append(client.debugName()); | |
| 125 #endif | |
| 126 | |
| 127 invalidateUntracked(client); | 121 invalidateUntracked(client); |
| 128 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali
dationObjects) | 122 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali
dationObjects) |
| 129 m_trackedPaintInvalidationObjects->append(client.debugName()); | 123 m_trackedPaintInvalidationObjects->append(client.debugName()); |
| 124 |
| 125 fprintf(stderr, "###invalidate %p %s on %p(%s) %s old:%d,%d,%d,%d new:%d,%d,
%d,%d\n", |
| 126 &client, client.debugName().ascii().data(), this, m_debugName.ascii().da
ta(), |
| 127 paintInvalidationReasonToString(paintInvalidationReason), |
| 128 previousPaintInvalidationRect.x(), previousPaintInvalidationRect.y(), pr
eviousPaintInvalidationRect.width(), previousPaintInvalidationRect.height(), |
| 129 newPaintInvalidationRect.x(), newPaintInvalidationRect.y(), newPaintInva
lidationRect.width(), newPaintInvalidationRect.height()); |
| 130 |
| 131 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 132 return; |
| 133 |
| 134 Invalidation invalidation = { client, client.debugName(), previousPaintInval
idationRect, paintInvalidationReason }; |
| 135 if (paintInvalidationReason != PaintInvalidationIncremental) { |
| 136 if (!previousPaintInvalidationRect.isEmpty()) |
| 137 m_invalidations.append(invalidation); |
| 138 if (newPaintInvalidationRect != previousPaintInvalidationRect && !newPai
ntInvalidationRect.isEmpty()) { |
| 139 invalidation.rect = newPaintInvalidationRect; |
| 140 m_invalidations.append(invalidation); |
| 141 } |
| 142 return; |
| 143 } |
| 144 |
| 145 ASSERT(previousPaintInvalidationRect.location() == newPaintInvalidationRect.
location()); |
| 146 if (LayoutUnit deltaRight = newPaintInvalidationRect.maxX() - previousPaintI
nvalidationRect.maxX()) { |
| 147 if (deltaRight > 0) |
| 148 invalidation.rect = IntRect(previousPaintInvalidationRect.maxX(), ne
wPaintInvalidationRect.y(), deltaRight, newPaintInvalidationRect.height()); |
| 149 else |
| 150 invalidation.rect = IntRect(newPaintInvalidationRect.maxX(), previou
sPaintInvalidationRect.y(), -deltaRight, previousPaintInvalidationRect.height())
; |
| 151 if (!invalidation.rect.isEmpty()) |
| 152 m_invalidations.append(invalidation); |
| 153 } |
| 154 if (LayoutUnit deltaBottom = newPaintInvalidationRect.maxY() - previousPaint
InvalidationRect.maxY()) { |
| 155 if (deltaBottom > 0) |
| 156 invalidation.rect = IntRect(newPaintInvalidationRect.x(), previousPa
intInvalidationRect.maxY(), newPaintInvalidationRect.width(), deltaBottom); |
| 157 else if (deltaBottom < 0) |
| 158 invalidation.rect = IntRect(previousPaintInvalidationRect.x(), newPa
intInvalidationRect.maxY(), previousPaintInvalidationRect.width(), -deltaBottom)
; |
| 159 if (!invalidation.rect.isEmpty()) |
| 160 m_invalidations.append(invalidation); |
| 161 } |
| 130 } | 162 } |
| 131 | 163 |
| 132 void PaintController::invalidateUntracked(const DisplayItemClient& client) | 164 void PaintController::invalidateUntracked(const DisplayItemClient& client) |
| 133 { | 165 { |
| 134 // This can be called during painting, but we can't invalidate already paint
ed clients. | 166 // This can be called during painting, but we can't invalidate already paint
ed clients. |
| 135 ASSERT(!m_newDisplayItemIndicesByClient.contains(&client)); | 167 ASSERT(!m_newDisplayItemIndicesByClient.contains(&client)); |
| 136 updateValidlyCachedClientsIfNeeded(); | 168 updateValidlyCachedClientsIfNeeded(); |
| 137 m_validlyCachedClients.remove(&client); | 169 m_validlyCachedClients.remove(&client); |
| 138 } | 170 } |
| 139 | 171 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 152 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const | 184 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const |
| 153 { | 185 { |
| 154 if (skippingCache()) | 186 if (skippingCache()) |
| 155 return false; | 187 return false; |
| 156 updateValidlyCachedClientsIfNeeded(); | 188 updateValidlyCachedClientsIfNeeded(); |
| 157 return m_validlyCachedClients.contains(&client); | 189 return m_validlyCachedClients.contains(&client); |
| 158 } | 190 } |
| 159 | 191 |
| 160 void PaintController::invalidatePaintOffset(const DisplayItemClient& client) | 192 void PaintController::invalidatePaintOffset(const DisplayItemClient& client) |
| 161 { | 193 { |
| 162 ASSERT(RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled()); | 194 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 163 invalidate(client); | 195 invalidate(client); |
| 164 | 196 |
| 165 #if ENABLE(ASSERT) | 197 #if ENABLE(ASSERT) |
| 166 ASSERT(!paintOffsetWasInvalidated(client)); | 198 ASSERT(!paintOffsetWasInvalidated(client)); |
| 167 m_clientsWithPaintOffsetInvalidations.add(&client); | 199 m_clientsWithPaintOffsetInvalidations.add(&client); |
| 168 #endif | 200 #endif |
| 169 } | 201 } |
| 170 | 202 |
| 171 #if ENABLE(ASSERT) | 203 #if ENABLE(ASSERT) |
| 172 bool PaintController::paintOffsetWasInvalidated(const DisplayItemClient& client)
const | 204 bool PaintController::paintOffsetWasInvalidated(const DisplayItemClient& client)
const |
| 173 { | 205 { |
| 174 ASSERT(RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled()); | 206 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 175 return m_clientsWithPaintOffsetInvalidations.contains(&client); | 207 return m_clientsWithPaintOffsetInvalidations.contains(&client); |
| 176 } | 208 } |
| 177 #endif | 209 #endif |
| 178 | 210 |
| 179 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con
st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItemL
ist& list) | 211 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con
st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItemL
ist& list) |
| 180 { | 212 { |
| 181 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(&id.client); | 213 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(&id.client); |
| 182 if (it == displayItemIndicesByClient.end()) | 214 if (it == displayItemIndicesByClient.end()) |
| 183 return kNotFound; | 215 return kNotFound; |
| 184 | 216 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 // Coefficients are related to the ratio of out-of-order CachedDisplayItems | 315 // Coefficients are related to the ratio of out-of-order CachedDisplayItems |
| 284 // and the average number of (Drawing|Subsequence)DisplayItems per client. | 316 // and the average number of (Drawing|Subsequence)DisplayItems per client. |
| 285 // | 317 // |
| 286 void PaintController::commitNewDisplayItemsInternal(const LayoutSize& offsetFrom
LayoutObject) | 318 void PaintController::commitNewDisplayItemsInternal(const LayoutSize& offsetFrom
LayoutObject) |
| 287 { | 319 { |
| 288 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", | 320 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", |
| 289 "current_display_list_size", (int)m_currentPaintArtifact.displayItemList
().size(), | 321 "current_display_list_size", (int)m_currentPaintArtifact.displayItemList
().size(), |
| 290 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach
edNewItems); | 322 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach
edNewItems); |
| 291 m_numCachedNewItems = 0; | 323 m_numCachedNewItems = 0; |
| 292 | 324 |
| 293 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 325 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 326 for (const auto& invalidation : m_invalidations) |
| 327 graphicsLayer->setNeedsDisplayInRect(invalidation.rect, invalidation
.invalidationReason); |
| 328 fprintf(stderr, "PaintController graphicsLayer %p %p(%s) clear invalidat
ions\n", graphicsLayer, this, m_debugName.ascii().data()); |
| 329 m_invalidations.clear(); |
| 294 m_clientsCheckedPaintInvalidation.clear(); | 330 m_clientsCheckedPaintInvalidation.clear(); |
| 331 } |
| 295 | 332 |
| 296 // These data structures are used during painting only. | 333 // These data structures are used during painting only. |
| 297 ASSERT(m_scopeStack.isEmpty()); | 334 ASSERT(m_scopeStack.isEmpty()); |
| 298 m_scopeStack.clear(); | 335 m_scopeStack.clear(); |
| 299 m_nextScope = 1; | 336 m_nextScope = 1; |
| 300 ASSERT(!skippingCache()); | 337 ASSERT(!skippingCache()); |
| 301 #if ENABLE(ASSERT) | 338 #if ENABLE(ASSERT) |
| 302 m_newDisplayItemIndicesByClient.clear(); | 339 m_newDisplayItemIndicesByClient.clear(); |
| 303 m_clientsWithPaintOffsetInvalidations.clear(); | 340 m_clientsWithPaintOffsetInvalidations.clear(); |
| 304 m_invalidations.clear(); | 341 m_invalidations.clear(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 334 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.displayItemLis
t().end(); | 371 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.displayItemLis
t().end(); |
| 335 for (DisplayItemList::iterator newIt = m_newDisplayItemList.begin(); newIt !
= m_newDisplayItemList.end(); ++newIt) { | 372 for (DisplayItemList::iterator newIt = m_newDisplayItemList.begin(); newIt !
= m_newDisplayItemList.end(); ++newIt) { |
| 336 const DisplayItem& newDisplayItem = *newIt; | 373 const DisplayItem& newDisplayItem = *newIt; |
| 337 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 374 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
| 338 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; | 375 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; |
| 339 | 376 |
| 340 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); | 377 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); |
| 341 | 378 |
| 342 if (newDisplayItemHasCachedType) { | 379 if (newDisplayItemHasCachedType) { |
| 343 ASSERT(newDisplayItem.isCached()); | 380 ASSERT(newDisplayItem.isCached()); |
| 344 ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable
dFeatures::slimmingPaintOffsetCachingEnabled() && !paintOffsetWasInvalidated(new
DisplayItem.client()))); | 381 ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable
dFeatures::slimmingPaintSynchronizedPaintingEnabled() && !paintOffsetWasInvalida
ted(newDisplayItem.client()))); |
| 345 if (!isSynchronized) { | 382 if (!isSynchronized) { |
| 346 currentIt = findOutOfOrderCachedItem(newDisplayItemId, outOfOrde
rIndexContext); | 383 currentIt = findOutOfOrderCachedItem(newDisplayItemId, outOfOrde
rIndexContext); |
| 347 | 384 |
| 348 if (currentIt == currentEnd) { | 385 if (currentIt == currentEnd) { |
| 349 #ifndef NDEBUG | 386 #ifndef NDEBUG |
| 350 showDebugData(); | 387 showDebugData(); |
| 351 WTFLogAlways("%s not found in m_currentDisplayItemList\n", n
ewDisplayItem.asDebugString().utf8().data()); | 388 WTFLogAlways("%s not found in m_currentDisplayItemList\n", n
ewDisplayItem.asDebugString().utf8().data()); |
| 352 #endif | 389 #endif |
| 353 ASSERT_NOT_REACHED(); | 390 ASSERT_NOT_REACHED(); |
| 354 // We did not find the cached display item. This should be i
mpossible, but may occur if there is a bug | 391 // We did not find the cached display item. This should be i
mpossible, but may occur if there is a bug |
| (...skipping 13 matching lines...) Expand all Loading... |
| 368 ++currentIt; | 405 ++currentIt; |
| 369 } else { | 406 } else { |
| 370 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence); | 407 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence); |
| 371 copyCachedSubsequence(m_currentPaintArtifact.displayItemList(),
currentIt, updatedList); | 408 copyCachedSubsequence(m_currentPaintArtifact.displayItemList(),
currentIt, updatedList); |
| 372 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence)
; | 409 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence)
; |
| 373 } | 410 } |
| 374 } else { | 411 } else { |
| 375 ASSERT(!newDisplayItem.isDrawing() | 412 ASSERT(!newDisplayItem.isDrawing() |
| 376 || newDisplayItem.skippedCache() | 413 || newDisplayItem.skippedCache() |
| 377 || !clientCacheIsValid(newDisplayItem.client()) | 414 || !clientCacheIsValid(newDisplayItem.client()) |
| 378 || (RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled()
&& paintOffsetWasInvalidated(newDisplayItem.client()))); | 415 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna
bled() && paintOffsetWasInvalidated(newDisplayItem.client()))); |
| 379 | 416 |
| 380 updatedList.appendByMoving(*newIt, visualRectForDisplayItem(*newIt,
offsetFromLayoutObject)); | 417 updatedList.appendByMoving(*newIt, visualRectForDisplayItem(*newIt,
offsetFromLayoutObject)); |
| 381 | 418 |
| 382 if (isSynchronized) | 419 if (isSynchronized) |
| 383 ++currentIt; | 420 ++currentIt; |
| 384 } | 421 } |
| 385 // Items before currentIt should have been copied so we don't need to in
dex them. | 422 // Items before currentIt should have been copied so we don't need to in
dex them. |
| 386 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) | 423 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) |
| 387 outOfOrderIndexContext.nextItemToIndex = currentIt; | 424 outOfOrderIndexContext.nextItemToIndex = currentIt; |
| 388 } | 425 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 size_t i = 0; | 589 size_t i = 0; |
| 553 for (auto it = list.begin(); it != list.end(); ++it, ++i) { | 590 for (auto it = list.begin(); it != list.end(); ++it, ++i) { |
| 554 const DisplayItem& displayItem = *it; | 591 const DisplayItem& displayItem = *it; |
| 555 if (i) | 592 if (i) |
| 556 stringBuilder.append(",\n"); | 593 stringBuilder.append(",\n"); |
| 557 stringBuilder.append(String::format("{index: %d, ", (int)i)); | 594 stringBuilder.append(String::format("{index: %d, ", (int)i)); |
| 558 displayItem.dumpPropertiesAsDebugString(stringBuilder); | 595 displayItem.dumpPropertiesAsDebugString(stringBuilder); |
| 559 stringBuilder.append(", cacheIsValid: "); | 596 stringBuilder.append(", cacheIsValid: "); |
| 560 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" :
"false"); | 597 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" :
"false"); |
| 561 stringBuilder.append('}'); | 598 stringBuilder.append('}'); |
| 599 if (DisplayItem::isDrawingType(displayItem.type())) { |
| 600 if (const SkPicture* picture = static_cast<const DrawingDisplayItem&
>(displayItem).picture()) { |
| 601 stringBuilder.append(", picture: "); |
| 602 stringBuilder.append(pictureAsDebugString(picture)); |
| 603 } |
| 604 } |
| 562 } | 605 } |
| 563 return stringBuilder.toString(); | 606 return stringBuilder.toString(); |
| 564 } | 607 } |
| 565 | 608 |
| 566 void PaintController::showDebugData() const | 609 void PaintController::showDebugData() const |
| 567 { | 610 { |
| 568 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()); |
| 569 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()); |
| 570 } | 613 } |
| 571 | 614 |
| 572 #endif // ifndef NDEBUG | 615 #endif // ifndef NDEBUG |
| 573 | 616 |
| 574 } // namespace blink | 617 } // namespace blink |
| OLD | NEW |