| 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/DisplayItemList.h" | 6 #include "platform/graphics/paint/DisplayItemList.h" |
| 7 | 7 |
| 8 #include "platform/NotImplemented.h" | 8 #include "platform/NotImplemented.h" |
| 9 #include "platform/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
| 10 #include "platform/TraceEvent.h" | 10 #include "platform/TraceEvent.h" |
| 11 #include "platform/graphics/paint/DrawingDisplayItem.h" | 11 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 12 |
| 13 #if ENABLE(ASSERT) |
| 14 #include "third_party/skia/include/core/SkBitmap.h" |
| 15 #include "third_party/skia/include/core/SkCanvas.h" |
| 12 #include "third_party/skia/include/core/SkData.h" | 16 #include "third_party/skia/include/core/SkData.h" |
| 13 #include "third_party/skia/include/core/SkStream.h" | 17 #include "third_party/skia/include/core/SkStream.h" |
| 18 #endif |
| 14 | 19 |
| 15 #ifndef NDEBUG | 20 #ifndef NDEBUG |
| 16 #include "platform/graphics/LoggingCanvas.h" | 21 #include "platform/graphics/LoggingCanvas.h" |
| 17 #include "wtf/text/StringBuilder.h" | 22 #include "wtf/text/StringBuilder.h" |
| 18 #include <stdio.h> | 23 #include <stdio.h> |
| 19 #endif | 24 #endif |
| 20 | 25 |
| 21 namespace blink { | 26 namespace blink { |
| 22 | 27 |
| 23 const DisplayItems& DisplayItemList::displayItems() const | 28 const DisplayItems& DisplayItemList::displayItems() const |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 | 294 |
| 290 static void showUnderInvalidationError(const char* reason, const DisplayItem& di
splayItem) | 295 static void showUnderInvalidationError(const char* reason, const DisplayItem& di
splayItem) |
| 291 { | 296 { |
| 292 #ifndef NDEBUG | 297 #ifndef NDEBUG |
| 293 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD
ebugString().utf8().data()); | 298 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD
ebugString().utf8().data()); |
| 294 #else | 299 #else |
| 295 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/
450725.", reason); | 300 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/
450725.", reason); |
| 296 #endif // NDEBUG | 301 #endif // NDEBUG |
| 297 } | 302 } |
| 298 | 303 |
| 304 static bool bitmapIsAllZero(const SkBitmap& bitmap) |
| 305 { |
| 306 bitmap.lockPixels(); |
| 307 bool result = true; |
| 308 for (int x = 0; result && x < bitmap.width(); ++x) { |
| 309 for (int y = 0; result && y < bitmap.height(); ++y) { |
| 310 if (SkColorSetA(bitmap.getColor(x, y), 0) != SK_ColorTRANSPARENT) |
| 311 result = false; |
| 312 } |
| 313 } |
| 314 bitmap.unlockPixels(); |
| 315 return result; |
| 316 } |
| 317 |
| 299 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ
ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) | 318 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ
ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) |
| 300 { | 319 { |
| 301 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); | 320 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled
()); |
| 302 | 321 |
| 303 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) | 322 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) |
| 304 return; | 323 return; |
| 305 | 324 |
| 306 if (static_cast<const DrawingDisplayItem&>(displayItem).skipUnderInvalidatio
nChecking()) | 325 DrawingDisplayItem::UnderInvalidationCheckingMode mode = static_cast<const D
rawingDisplayItem&>(displayItem).underInvalidationCheckingMode(); |
| 326 if (mode == DrawingDisplayItem::DontCheck) |
| 307 return; | 327 return; |
| 308 | 328 |
| 309 // If checking under-invalidation, we always generate new display item even
if the client is not invalidated. | 329 // If checking under-invalidation, we always generate new display item even
if the client is not invalidated. |
| 310 // Checks if the new picture is the same as the cached old picture. If the n
ew picture is different but | 330 // Checks if the new picture is the same as the cached old picture. If the n
ew picture is different but |
| 311 // the client is not invalidated, issue error about under-invalidation. | 331 // the client is not invalidated, issue error about under-invalidation. |
| 312 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di
splayItemIndicesByClient, m_currentDisplayItems); | 332 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di
splayItemIndicesByClient, m_currentDisplayItems); |
| 313 if (index == kNotFound) { | 333 if (index == kNotFound) { |
| 314 showUnderInvalidationError("ERROR: under-invalidation: no cached display
item", displayItem); | 334 showUnderInvalidationError("ERROR: under-invalidation: no cached display
item", displayItem); |
| 315 ASSERT_NOT_REACHED(); | 335 ASSERT_NOT_REACHED(); |
| 316 return; | 336 return; |
| 317 } | 337 } |
| 318 | 338 |
| 319 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>(
displayItem).picture(); | 339 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>(
displayItem).picture(); |
| 320 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(
*m_currentDisplayItems[index]).picture(); | 340 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(
*m_currentDisplayItems[index]).picture(); |
| 321 // Remove the display item from cache so that we can check if there are any
remaining cached display items after merging. | 341 // Remove the display item from cache so that we can check if there are any
remaining cached display items after merging. |
| 322 m_currentDisplayItems[index] = nullptr; | 342 m_currentDisplayItems[index] = nullptr; |
| 323 | 343 |
| 324 if (!newPicture && !oldPicture) | 344 if (!newPicture && !oldPicture) |
| 325 return; | 345 return; |
| 326 if (newPicture && oldPicture && newPicture->approximateOpCount() == oldPictu
re->approximateOpCount()) { | 346 if (newPicture && oldPicture) { |
| 327 SkDynamicMemoryWStream newPictureSerialized; | 347 switch (mode) { |
| 328 newPicture->serialize(&newPictureSerialized); | 348 case DrawingDisplayItem::CheckPicture: |
| 329 SkDynamicMemoryWStream oldPictureSerialized; | 349 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou
nt()) { |
| 330 oldPicture->serialize(&oldPictureSerialized); | 350 SkDynamicMemoryWStream newPictureSerialized; |
| 351 newPicture->serialize(&newPictureSerialized); |
| 352 SkDynamicMemoryWStream oldPictureSerialized; |
| 353 oldPicture->serialize(&oldPictureSerialized); |
| 331 | 354 |
| 332 if (newPictureSerialized.bytesWritten() == oldPictureSerialized.bytesWri
tten()) { | 355 if (newPictureSerialized.bytesWritten() == oldPictureSerialized.
bytesWritten()) { |
| 333 RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyToData())
; | 356 RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyT
oData()); |
| 334 RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyToData())
; | 357 RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyT
oData()); |
| 335 if (oldData->equals(newData.get())) | 358 if (oldData->equals(newData.get())) |
| 336 return; | 359 return; |
| 360 } |
| 361 } |
| 362 break; |
| 363 case DrawingDisplayItem::CheckBitmap: |
| 364 if (newPicture->cullRect() == oldPicture->cullRect()) { |
| 365 SkBitmap bitmap; |
| 366 SkRect rect = newPicture->cullRect(); |
| 367 bitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect
.height())); |
| 368 SkCanvas canvas(bitmap); |
| 369 canvas.translate(-rect.x(), -rect.y()); |
| 370 canvas.drawPicture(oldPicture.get()); |
| 371 SkPaint diffPaint; |
| 372 diffPaint.setXfermodeMode(SkXfermode::kDifference_Mode); |
| 373 canvas.drawPicture(newPicture.get(), nullptr, &diffPaint); |
| 374 if (bitmapIsAllZero(bitmap)) // Contents are the same. |
| 375 return; |
| 376 } |
| 377 default: |
| 378 ASSERT_NOT_REACHED(); |
| 337 } | 379 } |
| 338 } | 380 } |
| 339 | 381 |
| 340 showUnderInvalidationError("ERROR: under-invalidation: display item changed"
, displayItem); | 382 showUnderInvalidationError("ERROR: under-invalidation: display item changed"
, displayItem); |
| 341 #ifndef NDEBUG | 383 #ifndef NDEBUG |
| 342 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPicture.
get()) : "None"; | 384 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPicture.
get()) : "None"; |
| 343 String newPictureDebugString = newPicture ? pictureAsDebugString(newPicture.
get()) : "None"; | 385 String newPictureDebugString = newPicture ? pictureAsDebugString(newPicture.
get()) : "None"; |
| 344 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data()); | 386 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data()); |
| 345 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); | 387 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); |
| 346 #endif // NDEBUG | 388 #endif // NDEBUG |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 435 |
| 394 void DisplayItemList::replay(GraphicsContext& context) const | 436 void DisplayItemList::replay(GraphicsContext& context) const |
| 395 { | 437 { |
| 396 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 438 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
| 397 ASSERT(m_newDisplayItems.isEmpty()); | 439 ASSERT(m_newDisplayItems.isEmpty()); |
| 398 for (auto& displayItem : m_currentDisplayItems) | 440 for (auto& displayItem : m_currentDisplayItems) |
| 399 displayItem->replay(context); | 441 displayItem->replay(context); |
| 400 } | 442 } |
| 401 | 443 |
| 402 } // namespace blink | 444 } // namespace blink |
| OLD | NEW |