Chromium Code Reviews| Index: Source/platform/graphics/paint/DisplayItemList.cpp |
| diff --git a/Source/platform/graphics/paint/DisplayItemList.cpp b/Source/platform/graphics/paint/DisplayItemList.cpp |
| index 24227418e7fa6ce1df0b008ca6f5c38a18e2876e..84d4d8707490f21b6bf5ede67efa88791fe5e59f 100644 |
| --- a/Source/platform/graphics/paint/DisplayItemList.cpp |
| +++ b/Source/platform/graphics/paint/DisplayItemList.cpp |
| @@ -296,6 +296,20 @@ static void showUnderInvalidationError(const char* reason, const DisplayItem& di |
| #endif // NDEBUG |
| } |
| +static bool bitmapIsAllZero(const SkBitmap& bitmap) |
| +{ |
| + bitmap.lockPixels(); |
| + bool result = true; |
| + for (int x = 0; result && x < bitmap.width(); ++x) { |
| + for (int y = 0; result && y < bitmap.height(); ++y) { |
| + if (SkColorSetA(bitmap.getColor(x, y), 0) != SK_ColorTRANSPARENT) |
| + result = false; |
| + } |
| + } |
| + bitmap.unlockPixels(); |
| + return result; |
| +} |
| + |
| void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) |
| { |
| ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()); |
| @@ -303,7 +317,8 @@ void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ |
| if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) |
| return; |
| - if (static_cast<const DrawingDisplayItem&>(displayItem).skipUnderInvalidationChecking()) |
| + DrawingDisplayItem::UnderInvalidationCheckingMode mode = static_cast<const DrawingDisplayItem&>(displayItem).underInvalidationCheckingMode(); |
| + if (mode == DrawingDisplayItem::DontCheck) |
| return; |
| // If checking under-invalidation, we always generate new display item even if the client is not invalidated. |
| @@ -323,17 +338,39 @@ void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ |
| if (!newPicture && !oldPicture) |
| return; |
| - if (newPicture && oldPicture && newPicture->approximateOpCount() == oldPicture->approximateOpCount()) { |
| - SkDynamicMemoryWStream newPictureSerialized; |
| - newPicture->serialize(&newPictureSerialized); |
| - SkDynamicMemoryWStream oldPictureSerialized; |
| - oldPicture->serialize(&oldPictureSerialized); |
| - |
| - if (newPictureSerialized.bytesWritten() == oldPictureSerialized.bytesWritten()) { |
| - RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyToData()); |
| - RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyToData()); |
| - if (oldData->equals(newData.get())) |
| - return; |
| + if (newPicture && oldPicture) { |
| + switch (mode) { |
| + case DrawingDisplayItem::CheckPicture: |
| + if (newPicture->approximateOpCount() == oldPicture->approximateOpCount()) { |
| + SkDynamicMemoryWStream newPictureSerialized; |
| + newPicture->serialize(&newPictureSerialized); |
| + SkDynamicMemoryWStream oldPictureSerialized; |
| + oldPicture->serialize(&oldPictureSerialized); |
| + |
| + if (newPictureSerialized.bytesWritten() == oldPictureSerialized.bytesWritten()) { |
| + RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyToData()); |
| + RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyToData()); |
| + if (oldData->equals(newData.get())) |
| + return; |
| + } |
| + } |
| + break; |
| + case DrawingDisplayItem::CheckBitmap: |
|
Justin Novosad
2015/06/01 21:47:34
For now, this strategy will work. In the near futu
|
| + if (newPicture->cullRect() == oldPicture->cullRect()) { |
| + SkBitmap bitmap; |
| + SkRect rect = newPicture->cullRect(); |
| + bitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect.height())); |
| + SkCanvas canvas(bitmap); |
| + canvas.translate(-rect.x(), -rect.y()); |
| + canvas.drawPicture(oldPicture.get()); |
| + SkPaint diffPaint; |
| + diffPaint.setXfermodeMode(SkXfermode::kDifference_Mode); |
| + canvas.drawPicture(newPicture.get(), nullptr, &diffPaint); |
| + if (bitmapIsAllZero(bitmap)) // Contents are the same. |
| + return; |
| + } |
| + default: |
| + ASSERT_NOT_REACHED(); |
| } |
| } |