Chromium Code Reviews| 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" |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 | 289 |
| 290 static void showUnderInvalidationError(const char* reason, const DisplayItem& di splayItem) | 290 static void showUnderInvalidationError(const char* reason, const DisplayItem& di splayItem) |
| 291 { | 291 { |
| 292 #ifndef NDEBUG | 292 #ifndef NDEBUG |
| 293 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD ebugString().utf8().data()); | 293 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD ebugString().utf8().data()); |
| 294 #else | 294 #else |
| 295 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/ 450725.", reason); | 295 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/ 450725.", reason); |
| 296 #endif // NDEBUG | 296 #endif // NDEBUG |
| 297 } | 297 } |
| 298 | 298 |
| 299 static bool bitmapIsAllZero(const SkBitmap& bitmap) | |
| 300 { | |
| 301 bitmap.lockPixels(); | |
| 302 bool result = true; | |
| 303 for (int x = 0; result && x < bitmap.width(); ++x) { | |
| 304 for (int y = 0; result && y < bitmap.height(); ++y) { | |
| 305 if (SkColorSetA(bitmap.getColor(x, y), 0) != SK_ColorTRANSPARENT) | |
| 306 result = false; | |
| 307 } | |
| 308 } | |
| 309 bitmap.unlockPixels(); | |
| 310 return result; | |
| 311 } | |
| 312 | |
| 299 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) | 313 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) |
| 300 { | 314 { |
| 301 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); | 315 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); |
| 302 | 316 |
| 303 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) | 317 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) |
| 304 return; | 318 return; |
| 305 | 319 |
| 306 if (static_cast<const DrawingDisplayItem&>(displayItem).skipUnderInvalidatio nChecking()) | 320 DrawingDisplayItem::UnderInvalidationCheckingMode mode = static_cast<const D rawingDisplayItem&>(displayItem).underInvalidationCheckingMode(); |
| 321 if (mode == DrawingDisplayItem::DontCheck) | |
| 307 return; | 322 return; |
| 308 | 323 |
| 309 // If checking under-invalidation, we always generate new display item even if the client is not invalidated. | 324 // 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 | 325 // 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. | 326 // the client is not invalidated, issue error about under-invalidation. |
| 312 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di splayItemIndicesByClient, m_currentDisplayItems); | 327 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di splayItemIndicesByClient, m_currentDisplayItems); |
| 313 if (index == kNotFound) { | 328 if (index == kNotFound) { |
| 314 showUnderInvalidationError("ERROR: under-invalidation: no cached display item", displayItem); | 329 showUnderInvalidationError("ERROR: under-invalidation: no cached display item", displayItem); |
| 315 ASSERT_NOT_REACHED(); | 330 ASSERT_NOT_REACHED(); |
| 316 return; | 331 return; |
| 317 } | 332 } |
| 318 | 333 |
| 319 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>( displayItem).picture(); | 334 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>( displayItem).picture(); |
| 320 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>( *m_currentDisplayItems[index]).picture(); | 335 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. | 336 // 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; | 337 m_currentDisplayItems[index] = nullptr; |
| 323 | 338 |
| 324 if (!newPicture && !oldPicture) | 339 if (!newPicture && !oldPicture) |
| 325 return; | 340 return; |
| 326 if (newPicture && oldPicture && newPicture->approximateOpCount() == oldPictu re->approximateOpCount()) { | 341 if (newPicture && oldPicture) { |
| 327 SkDynamicMemoryWStream newPictureSerialized; | 342 switch (mode) { |
| 328 newPicture->serialize(&newPictureSerialized); | 343 case DrawingDisplayItem::CheckPicture: |
| 329 SkDynamicMemoryWStream oldPictureSerialized; | 344 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou nt()) { |
| 330 oldPicture->serialize(&oldPictureSerialized); | 345 SkDynamicMemoryWStream newPictureSerialized; |
| 346 newPicture->serialize(&newPictureSerialized); | |
| 347 SkDynamicMemoryWStream oldPictureSerialized; | |
| 348 oldPicture->serialize(&oldPictureSerialized); | |
| 331 | 349 |
| 332 if (newPictureSerialized.bytesWritten() == oldPictureSerialized.bytesWri tten()) { | 350 if (newPictureSerialized.bytesWritten() == oldPictureSerialized. bytesWritten()) { |
| 333 RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyToData()) ; | 351 RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyT oData()); |
| 334 RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyToData()) ; | 352 RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyT oData()); |
| 335 if (oldData->equals(newData.get())) | 353 if (oldData->equals(newData.get())) |
| 336 return; | 354 return; |
| 355 } | |
| 356 } | |
| 357 break; | |
| 358 case DrawingDisplayItem::CheckBitmap: | |
|
Justin Novosad
2015/06/01 21:47:34
For now, this strategy will work. In the near futu
| |
| 359 if (newPicture->cullRect() == oldPicture->cullRect()) { | |
| 360 SkBitmap bitmap; | |
| 361 SkRect rect = newPicture->cullRect(); | |
| 362 bitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect .height())); | |
| 363 SkCanvas canvas(bitmap); | |
| 364 canvas.translate(-rect.x(), -rect.y()); | |
| 365 canvas.drawPicture(oldPicture.get()); | |
| 366 SkPaint diffPaint; | |
| 367 diffPaint.setXfermodeMode(SkXfermode::kDifference_Mode); | |
| 368 canvas.drawPicture(newPicture.get(), nullptr, &diffPaint); | |
| 369 if (bitmapIsAllZero(bitmap)) // Contents are the same. | |
| 370 return; | |
| 371 } | |
| 372 default: | |
| 373 ASSERT_NOT_REACHED(); | |
| 337 } | 374 } |
| 338 } | 375 } |
| 339 | 376 |
| 340 showUnderInvalidationError("ERROR: under-invalidation: display item changed" , displayItem); | 377 showUnderInvalidationError("ERROR: under-invalidation: display item changed" , displayItem); |
| 341 #ifndef NDEBUG | 378 #ifndef NDEBUG |
| 342 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPicture. get()) : "None"; | 379 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPicture. get()) : "None"; |
| 343 String newPictureDebugString = newPicture ? pictureAsDebugString(newPicture. get()) : "None"; | 380 String newPictureDebugString = newPicture ? pictureAsDebugString(newPicture. get()) : "None"; |
| 344 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data()); | 381 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data()); |
| 345 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); | 382 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); |
| 346 #endif // NDEBUG | 383 #endif // NDEBUG |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 | 430 |
| 394 void DisplayItemList::replay(GraphicsContext& context) const | 431 void DisplayItemList::replay(GraphicsContext& context) const |
| 395 { | 432 { |
| 396 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 433 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
| 397 ASSERT(m_newDisplayItems.isEmpty()); | 434 ASSERT(m_newDisplayItems.isEmpty()); |
| 398 for (auto& displayItem : m_currentDisplayItems) | 435 for (auto& displayItem : m_currentDisplayItems) |
| 399 displayItem->replay(context); | 436 displayItem->replay(context); |
| 400 } | 437 } |
| 401 | 438 |
| 402 } // namespace blink | 439 } // namespace blink |
| OLD | NEW |