Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Unified Diff: Source/platform/graphics/paint/DisplayItemList.cpp

Issue 1160223004: Avoid false-positives of under-invalidation checking (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Check bitmaps for HTML canvas drawings only Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
}
}

Powered by Google App Engine
This is Rietveld 408576698