OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkData.h" | 10 #include "SkData.h" |
11 #include "SkDecodingImageGenerator.h" | 11 #include "SkDecodingImageGenerator.h" |
| 12 #include "SkDiscardablePixelRef.h" |
| 13 #include "SkDiscardableMemoryPool.h" |
12 #include "SkImageDecoder.h" | 14 #include "SkImageDecoder.h" |
13 #include "SkImagePriv.h" | |
14 #include "SkLazyPixelRef.h" | |
15 #include "SkCachingPixelRef.h" | 15 #include "SkCachingPixelRef.h" |
16 #include "SkScaledImageCache.h" | 16 #include "SkScaledImageCache.h" |
17 #include "SkStream.h" | 17 #include "SkStream.h" |
| 18 #include "SkUtils.h" |
18 | 19 |
19 #include "Test.h" | 20 #include "Test.h" |
20 #include "TestClassDef.h" | 21 #include "TestClassDef.h" |
21 | 22 |
22 /** | 23 /** |
23 * Fill this bitmap with some color. | 24 * Fill this bitmap with some color. |
24 */ | 25 */ |
25 static void make_test_image(SkBitmap* bm) { | 26 static void make_test_image(SkBitmap* bm) { |
26 static const int W = 50, H = 50; | 27 static const int W = 50, H = 50; |
27 static const SkBitmap::Config config = SkBitmap::kARGB_8888_Config; | 28 static const SkBitmap::Config config = SkBitmap::kARGB_8888_Config; |
(...skipping 15 matching lines...) Expand all Loading... |
43 */ | 44 */ |
44 static SkData* create_data_from_bitmap(const SkBitmap& bm, | 45 static SkData* create_data_from_bitmap(const SkBitmap& bm, |
45 SkImageEncoder::Type type) { | 46 SkImageEncoder::Type type) { |
46 SkDynamicMemoryWStream stream; | 47 SkDynamicMemoryWStream stream; |
47 if (SkImageEncoder::EncodeStream(&stream, bm, type, 100)) { | 48 if (SkImageEncoder::EncodeStream(&stream, bm, type, 100)) { |
48 return stream.copyToData(); | 49 return stream.copyToData(); |
49 } | 50 } |
50 return NULL; | 51 return NULL; |
51 } | 52 } |
52 | 53 |
53 /** | 54 //////////////////////////////////////////////////////////////////////////////// |
54 * A simplified version of SkBitmapFactory | |
55 */ | |
56 static bool simple_bitmap_factory(SkBitmapFactory::DecodeProc proc, | |
57 SkData* data, | |
58 SkBitmap* dst) { | |
59 SkImageInfo info; | |
60 if (!proc(data->data(), data->size(), &info, NULL)) { | |
61 return false; | |
62 } | |
63 dst->setConfig(SkImageInfoToBitmapConfig(info), info.fWidth, | |
64 info.fHeight, 0, info.fAlphaType); | |
65 SkAutoTUnref<SkLazyPixelRef> ref(SkNEW_ARGS(SkLazyPixelRef, | |
66 (data, proc, NULL))); | |
67 dst->setPixelRef(ref); | |
68 return true; | |
69 } | |
70 | 55 |
71 static void compare_bitmaps(skiatest::Reporter* reporter, | 56 static void compare_bitmaps(skiatest::Reporter* reporter, |
72 const SkBitmap& b1, const SkBitmap& b2, | 57 const SkBitmap& b1, const SkBitmap& b2, |
73 bool pixelPerfect = true) { | 58 bool pixelPerfect = true) { |
74 REPORTER_ASSERT(reporter, b1.empty() == b2.empty()); | 59 REPORTER_ASSERT(reporter, b1.empty() == b2.empty()); |
75 REPORTER_ASSERT(reporter, b1.width() == b2.width()); | 60 REPORTER_ASSERT(reporter, b1.width() == b2.width()); |
76 REPORTER_ASSERT(reporter, b1.height() == b2.height()); | 61 REPORTER_ASSERT(reporter, b1.height() == b2.height()); |
77 REPORTER_ASSERT(reporter, b1.isNull() == b2.isNull()); | 62 REPORTER_ASSERT(reporter, b1.isNull() == b2.isNull()); |
78 SkAutoLockPixels autoLockPixels1(b1); | 63 SkAutoLockPixels autoLockPixels1(b1); |
79 SkAutoLockPixels autoLockPixels2(b2); | 64 SkAutoLockPixels autoLockPixels2(b2); |
(...skipping 18 matching lines...) Expand all Loading... |
98 for (int y = 0; y < b2.height(); ++y) { | 83 for (int y = 0; y < b2.height(); ++y) { |
99 for (int x = 0; x < b2.width(); ++x) { | 84 for (int x = 0; x < b2.width(); ++x) { |
100 if (b1.getColor(x, y) != b2.getColor(x, y)) { | 85 if (b1.getColor(x, y) != b2.getColor(x, y)) { |
101 ++pixelErrors; | 86 ++pixelErrors; |
102 } | 87 } |
103 } | 88 } |
104 } | 89 } |
105 REPORTER_ASSERT(reporter, 0 == pixelErrors); | 90 REPORTER_ASSERT(reporter, 0 == pixelErrors); |
106 } | 91 } |
107 | 92 |
108 | |
109 typedef bool (*InstallEncoded)(SkData* encoded, SkBitmap* dst); | 93 typedef bool (*InstallEncoded)(SkData* encoded, SkBitmap* dst); |
110 | 94 |
111 /** | 95 /** |
112 This function tests three differently encoded images against the | 96 This function tests three differently encoded images against the |
113 original bitmap */ | 97 original bitmap */ |
114 static void test_three_encodings(skiatest::Reporter* reporter, | 98 static void test_three_encodings(skiatest::Reporter* reporter, |
115 InstallEncoded install) { | 99 InstallEncoded install) { |
116 SkBitmap original; | 100 SkBitmap original; |
117 make_test_image(&original); | 101 make_test_image(&original); |
118 REPORTER_ASSERT(reporter, !original.empty()); | 102 REPORTER_ASSERT(reporter, !original.empty()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 REPORTER_ASSERT(reporter, NULL != lazy.getPixels()); | 137 REPORTER_ASSERT(reporter, NULL != lazy.getPixels()); |
154 if (NULL == lazy.getPixels()) { | 138 if (NULL == lazy.getPixels()) { |
155 continue; | 139 continue; |
156 } | 140 } |
157 } | 141 } |
158 bool comparePixels = (SkImageEncoder::kPNG_Type == type); | 142 bool comparePixels = (SkImageEncoder::kPNG_Type == type); |
159 compare_bitmaps(reporter, original, lazy, comparePixels); | 143 compare_bitmaps(reporter, original, lazy, comparePixels); |
160 } | 144 } |
161 } | 145 } |
162 | 146 |
163 | |
164 //////////////////////////////////////////////////////////////////////////////// | 147 //////////////////////////////////////////////////////////////////////////////// |
165 /** | 148 static bool install_skCachingPixelRef(SkData* encoded, SkBitmap* dst) { |
166 * This checks to see that a SkLazyPixelRef works as advertised. | 149 return SkCachingPixelRef::Install( |
167 */ | 150 SkNEW_ARGS(SkDecodingImageGenerator, (encoded)), dst); |
168 static bool install_skLazyPixelRef(SkData* encoded, SkBitmap* dst) { | |
169 static const SkBitmapFactory::DecodeProc decoder = | |
170 &(SkImageDecoder::DecodeMemoryToTarget); | |
171 return simple_bitmap_factory(decoder, encoded, dst); | |
172 } | 151 } |
173 DEF_TEST(LazyPixelRef, reporter) { | 152 static bool install_skDiscardablePixelRef(SkData* encoded, SkBitmap* dst) { |
174 test_three_encodings(reporter, install_skLazyPixelRef); | 153 // Use system-default discardable memory. |
| 154 return SkDecodingImageGenerator::Install(encoded, dst, NULL); |
175 } | 155 } |
176 | 156 |
177 //////////////////////////////////////////////////////////////////////////////// | 157 //////////////////////////////////////////////////////////////////////////////// |
178 /** | 158 /** |
179 * This checks to see that a SkCachingPixelRef works as advertised. | 159 * This checks to see that a SkCachingPixelRef and a |
| 160 * SkDiscardablePixelRef works as advertised with a |
| 161 * SkDecodingImageGenerator. |
180 */ | 162 */ |
181 static bool install_skCachingPixelRef(SkData* encoded, SkBitmap* dst) { | 163 DEF_TEST(DecodingImageGenerator, reporter) { |
182 return SkCachingPixelRef::Install( | |
183 SkNEW_ARGS(SkDecodingImageGenerator, (encoded)), dst); | |
184 } | |
185 DEF_TEST(CachingPixelRef, reporter) { | |
186 test_three_encodings(reporter, install_skCachingPixelRef); | 164 test_three_encodings(reporter, install_skCachingPixelRef); |
| 165 test_three_encodings(reporter, install_skDiscardablePixelRef); |
187 } | 166 } |
188 | 167 |
189 //////////////////////////////////////////////////////////////////////////////// | 168 //////////////////////////////////////////////////////////////////////////////// |
| 169 namespace { |
| 170 class TestImageGenerator : public SkImageGenerator { |
| 171 public: |
| 172 enum TestType { |
| 173 kFailGetInfo_TestType, |
| 174 kFailGetPixels_TestType, |
| 175 kSucceedGetPixels_TestType, |
| 176 kLast_TestType = kSucceedGetPixels_TestType |
| 177 }; |
| 178 static int Width() { return 10; } |
| 179 static int Height() { return 10; } |
| 180 static SkColor Color() { return SK_ColorCYAN; } |
| 181 TestImageGenerator(TestType type, skiatest::Reporter* reporter) |
| 182 : fType(type), fReporter(reporter) { |
| 183 SkASSERT((fType <= kLast_TestType) && (fType >= 0)); |
| 184 } |
| 185 ~TestImageGenerator() { } |
| 186 bool getInfo(SkImageInfo* info) SK_OVERRIDE { |
| 187 REPORTER_ASSERT(fReporter, NULL != info); |
| 188 if ((NULL == info) || (kFailGetInfo_TestType == fType)) { |
| 189 return false; |
| 190 } |
| 191 info->fWidth = TestImageGenerator::Width(); |
| 192 info->fHeight = TestImageGenerator::Height(); |
| 193 info->fColorType = kPMColor_SkColorType; |
| 194 info->fAlphaType = kOpaque_SkAlphaType; |
| 195 return true; |
| 196 } |
| 197 bool getPixels(const SkImageInfo& info, |
| 198 void* pixels, |
| 199 size_t rowBytes) SK_OVERRIDE { |
| 200 REPORTER_ASSERT(fReporter, pixels != NULL); |
| 201 size_t minRowBytes |
| 202 = static_cast<size_t>(info.fWidth * info.bytesPerPixel()); |
| 203 REPORTER_ASSERT(fReporter, rowBytes >= minRowBytes); |
| 204 if ((NULL == pixels) |
| 205 || (fType != kSucceedGetPixels_TestType) |
| 206 || (info.fColorType != kPMColor_SkColorType)) { |
| 207 return false; |
| 208 } |
| 209 char* bytePtr = static_cast<char*>(pixels); |
| 210 for (int y = 0; y < info.fHeight; ++y) { |
| 211 sk_memset32(reinterpret_cast<SkColor*>(bytePtr), |
| 212 TestImageGenerator::Color(), info.fWidth); |
| 213 bytePtr += rowBytes; |
| 214 } |
| 215 return true; |
| 216 } |
| 217 private: |
| 218 const TestType fType; |
| 219 skiatest::Reporter* const fReporter; |
| 220 }; |
| 221 void CheckTestImageGeneratorBitmap(skiatest::Reporter* reporter, |
| 222 const SkBitmap& bm) { |
| 223 REPORTER_ASSERT(reporter, TestImageGenerator::Width() == bm.width()); |
| 224 REPORTER_ASSERT(reporter, TestImageGenerator::Height() == bm.height()); |
| 225 SkAutoLockPixels autoLockPixels(bm); |
| 226 REPORTER_ASSERT(reporter, NULL != bm.getPixels()); |
| 227 if (NULL == bm.getPixels()) { |
| 228 return; |
| 229 } |
| 230 int errors = 0; |
| 231 for (int y = 0; y < bm.height(); ++y) { |
| 232 for (int x = 0; x < bm.width(); ++x) { |
| 233 if (TestImageGenerator::Color() != *bm.getAddr32(x, y)) { |
| 234 ++errors; |
| 235 } |
| 236 } |
| 237 } |
| 238 REPORTER_ASSERT(reporter, 0 == errors); |
| 239 } |
| 240 |
| 241 enum PixelRefType { |
| 242 kSkCaching_PixelRefType, |
| 243 kSkDiscardable_PixelRefType, |
| 244 kLast_PixelRefType = kSkDiscardable_PixelRefType |
| 245 }; |
| 246 void CheckPixelRef(TestImageGenerator::TestType type, |
| 247 skiatest::Reporter* reporter, |
| 248 PixelRefType pixelRefType, |
| 249 SkDiscardableMemory::Factory* factory) { |
| 250 SkASSERT((pixelRefType >= 0) && (pixelRefType <= kLast_PixelRefType)); |
| 251 SkAutoTDelete<SkImageGenerator> gen(SkNEW_ARGS(TestImageGenerator, |
| 252 (type, reporter))); |
| 253 REPORTER_ASSERT(reporter, gen.get() != NULL); |
| 254 SkBitmap lazy; |
| 255 bool success; |
| 256 if (kSkCaching_PixelRefType == pixelRefType) { |
| 257 // Ignore factory; use global SkScaledImageCache. |
| 258 success = SkCachingPixelRef::Install(gen.detach(), &lazy); |
| 259 } else { |
| 260 success = SkDiscardablePixelRef::Install(gen.detach(), &lazy, factory); |
| 261 } |
| 262 REPORTER_ASSERT(reporter, success |
| 263 == (TestImageGenerator::kFailGetInfo_TestType != type)); |
| 264 if (TestImageGenerator::kSucceedGetPixels_TestType == type) { |
| 265 CheckTestImageGeneratorBitmap(reporter, lazy); |
| 266 } else if (TestImageGenerator::kFailGetPixels_TestType == type) { |
| 267 SkAutoLockPixels autoLockPixels(lazy); |
| 268 REPORTER_ASSERT(reporter, NULL == lazy.getPixels()); |
| 269 } |
| 270 } |
| 271 } // namespace |
190 /** | 272 /** |
191 * This checks to see that a SkDecodingImageGenerator works as advertised. | 273 * This tests the basic functionality of SkDiscardablePixelRef with a |
| 274 * basic SkImageGenerator implementation and several |
| 275 * SkDiscardableMemory::Factory choices. |
192 */ | 276 */ |
193 DEF_TEST(DecodingImageGenerator, reporter) { | 277 DEF_TEST(DiscardableAndCachingPixelRef, reporter) { |
194 test_three_encodings(reporter, SkDecodingImageGenerator::Install); | 278 CheckPixelRef(TestImageGenerator::kFailGetInfo_TestType, |
| 279 reporter, kSkCaching_PixelRefType, NULL); |
| 280 CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType, |
| 281 reporter, kSkCaching_PixelRefType, NULL); |
| 282 CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType, |
| 283 reporter, kSkCaching_PixelRefType, NULL); |
| 284 |
| 285 CheckPixelRef(TestImageGenerator::kFailGetInfo_TestType, |
| 286 reporter, kSkDiscardable_PixelRefType, NULL); |
| 287 CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType, |
| 288 reporter, kSkDiscardable_PixelRefType, NULL); |
| 289 CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType, |
| 290 reporter, kSkDiscardable_PixelRefType, NULL); |
| 291 |
| 292 SkAutoTUnref<SkDiscardableMemoryPool> pool( |
| 293 SkNEW_ARGS(SkDiscardableMemoryPool, (1, NULL))); |
| 294 REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed()); |
| 295 CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType, |
| 296 reporter, kSkDiscardable_PixelRefType, pool); |
| 297 REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed()); |
| 298 CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType, |
| 299 reporter, kSkDiscardable_PixelRefType, pool); |
| 300 REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed()); |
| 301 |
| 302 SkDiscardableMemoryPool* globalPool = SkGetGlobalDiscardableMemoryPool(); |
| 303 CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType, |
| 304 reporter, kSkDiscardable_PixelRefType, globalPool); |
| 305 CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType, |
| 306 reporter, kSkDiscardable_PixelRefType, globalPool); |
| 307 |
| 308 // TODO(halcanary): When ashmem-backed SkDiscardableMemory lands, |
| 309 // test that here (on platforms where it is availible). |
195 } | 310 } |
| 311 //////////////////////////////////////////////////////////////////////////////// |
| 312 |
OLD | NEW |