| 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/DrawingDisplayItem.h" | 5 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 6 | 6 |
| 7 #include "platform/graphics/GraphicsContext.h" | 7 #include "platform/graphics/GraphicsContext.h" |
| 8 #include "public/platform/WebDisplayItemList.h" | 8 #include "public/platform/WebDisplayItemList.h" |
| 9 #include "third_party/skia/include/core/SkPictureAnalyzer.h" | 9 #include "third_party/skia/include/core/SkPictureAnalyzer.h" |
| 10 | 10 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 DisplayItem::dumpPropertiesAsDebugString(stringBuilder); | 45 DisplayItem::dumpPropertiesAsDebugString(stringBuilder); |
| 46 if (m_picture) { | 46 if (m_picture) { |
| 47 stringBuilder.append(WTF::String::format(", rect: [%f,%f %fx%f]", | 47 stringBuilder.append(WTF::String::format(", rect: [%f,%f %fx%f]", |
| 48 m_picture->cullRect().x(), m_picture->cullRect().y(), | 48 m_picture->cullRect().x(), m_picture->cullRect().y(), |
| 49 m_picture->cullRect().width(), m_picture->cullRect().height())); | 49 m_picture->cullRect().width(), m_picture->cullRect().height())); |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 #endif | 52 #endif |
| 53 | 53 |
| 54 #if ENABLE(ASSERT) | 54 #if ENABLE(ASSERT) |
| 55 static bool bitmapIsAllZero(const SkBitmap& bitmap) | 55 static bool picturesEqual(const SkPicture* picture1, const SkPicture* picture2) |
| 56 { | 56 { |
| 57 bitmap.lockPixels(); | 57 if (picture1->approximateOpCount() != picture2->approximateOpCount()) |
| 58 bool result = true; | 58 return false; |
| 59 for (int x = 0; result && x < bitmap.width(); ++x) { | 59 |
| 60 for (int y = 0; result && y < bitmap.height(); ++y) { | 60 SkDynamicMemoryWStream picture1Serialized; |
| 61 if (SkColorSetA(bitmap.getColor(x, y), 0) != SK_ColorTRANSPARENT) { | 61 picture1->serialize(&picture1Serialized); |
| 62 result = false; | 62 SkDynamicMemoryWStream picture2Serialized; |
| 63 break; | 63 picture2->serialize(&picture2Serialized); |
| 64 if (picture1Serialized.bytesWritten() != picture2Serialized.bytesWritten()) |
| 65 return false; |
| 66 |
| 67 RefPtr<SkData> data1 = adoptRef(picture1Serialized.copyToData()); |
| 68 RefPtr<SkData> data2 = adoptRef(picture2Serialized.copyToData()); |
| 69 return data1->equals(data2.get()); |
| 70 } |
| 71 |
| 72 static SkBitmap pictureToBitmap(const SkPicture* picture) |
| 73 { |
| 74 SkBitmap bitmap; |
| 75 SkRect rect = picture->cullRect(); |
| 76 bitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect.height())); |
| 77 SkCanvas canvas(bitmap); |
| 78 canvas.translate(-rect.x(), -rect.y()); |
| 79 canvas.drawPicture(picture); |
| 80 return bitmap; |
| 81 } |
| 82 |
| 83 static bool bitmapsEqual(const SkPicture* picture1, const SkPicture* picture2) |
| 84 { |
| 85 SkRect rect = picture1->cullRect(); |
| 86 if (rect != picture2->cullRect()) |
| 87 return false; |
| 88 |
| 89 SkBitmap bitmap1 = pictureToBitmap(picture1); |
| 90 SkBitmap bitmap2 = pictureToBitmap(picture2); |
| 91 bitmap1.lockPixels(); |
| 92 bitmap2.lockPixels(); |
| 93 int mismatchCount = 0; |
| 94 const int maxMismatches = 10; |
| 95 for (int y = 0; y < rect.height() && mismatchCount < maxMismatches; ++y) { |
| 96 for (int x = 0; x < rect.width() && mismatchCount < maxMismatches; ++x)
{ |
| 97 SkColor pixel1 = bitmap1.getColor(x, y); |
| 98 SkColor pixel2 = bitmap2.getColor(x, y); |
| 99 if (pixel1 != pixel2) { |
| 100 LOG(ERROR) << "x=" << x << " y=" << y << " " << std::hex << pixe
l1 << " vs " << std::hex << pixel2; |
| 101 ++mismatchCount; |
| 64 } | 102 } |
| 65 } | 103 } |
| 66 } | 104 } |
| 67 bitmap.unlockPixels(); | 105 bitmap1.unlockPixels(); |
| 68 return result; | 106 bitmap2.unlockPixels(); |
| 107 return !mismatchCount; |
| 69 } | 108 } |
| 70 | 109 |
| 71 bool DrawingDisplayItem::equals(const DisplayItem& other) const | 110 bool DrawingDisplayItem::equals(const DisplayItem& other) const |
| 72 { | 111 { |
| 73 if (!DisplayItem::equals(other)) | 112 if (!DisplayItem::equals(other)) |
| 74 return false; | 113 return false; |
| 75 | 114 |
| 76 RefPtr<const SkPicture> picture = this->picture(); | 115 const SkPicture* picture = this->picture(); |
| 77 RefPtr<const SkPicture> otherPicture = static_cast<const DrawingDisplayItem&
>(other).picture(); | 116 const SkPicture* otherPicture = static_cast<const DrawingDisplayItem&>(other
).picture(); |
| 78 | 117 |
| 79 if (!picture && !otherPicture) | 118 if (!picture && !otherPicture) |
| 80 return true; | 119 return true; |
| 81 if (!picture || !otherPicture) | 120 if (!picture || !otherPicture) |
| 82 return false; | 121 return false; |
| 83 | 122 |
| 84 switch (getUnderInvalidationCheckingMode()) { | 123 if (picturesEqual(picture, otherPicture)) |
| 85 case DrawingDisplayItem::CheckPicture: { | 124 return true; |
| 86 if (picture->approximateOpCount() != otherPicture->approximateOpCount()) | |
| 87 return false; | |
| 88 | 125 |
| 89 SkDynamicMemoryWStream pictureSerialized; | 126 // Sometimes the client may produce different pictures for the same visual r
esult |
| 90 picture->serialize(&pictureSerialized); | 127 // which should be treated as equal. |
| 91 SkDynamicMemoryWStream otherPictureSerialized; | 128 return bitmapsEqual(picture, otherPicture); |
| 92 otherPicture->serialize(&otherPictureSerialized); | |
| 93 if (pictureSerialized.bytesWritten() != otherPictureSerialized.bytesWrit
ten()) | |
| 94 return false; | |
| 95 | |
| 96 RefPtr<SkData> oldData = adoptRef(otherPictureSerialized.copyToData()); | |
| 97 RefPtr<SkData> newData = adoptRef(pictureSerialized.copyToData()); | |
| 98 return oldData->equals(newData.get()); | |
| 99 } | |
| 100 case DrawingDisplayItem::CheckBitmap: { | |
| 101 SkRect rect = picture->cullRect(); | |
| 102 if (rect != otherPicture->cullRect()) | |
| 103 return false; | |
| 104 | |
| 105 SkBitmap bitmap; | |
| 106 bitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect.height(
))); | |
| 107 SkCanvas canvas(bitmap); | |
| 108 canvas.translate(-rect.x(), -rect.y()); | |
| 109 canvas.drawPicture(otherPicture.get()); | |
| 110 SkPaint diffPaint; | |
| 111 diffPaint.setXfermodeMode(SkXfermode::kDifference_Mode); | |
| 112 canvas.drawPicture(picture.get(), nullptr, &diffPaint); | |
| 113 return bitmapIsAllZero(bitmap); | |
| 114 } | |
| 115 default: | |
| 116 ASSERT_NOT_REACHED(); | |
| 117 } | |
| 118 return false; | |
| 119 } | 129 } |
| 120 #endif // ENABLE(ASSERT) | 130 #endif // ENABLE(ASSERT) |
| 121 | 131 |
| 122 } // namespace blink | 132 } // namespace blink |
| OLD | NEW |