Big Cleanup: SkBitmapFactory, SkLazyPixelRef, SkImageCache
Removed SkBitmapFactory since no clients were using it. New cache
selection mechanism can simply pass a SkDiscardableMemory::Factory
into the SkDiscardablePixelRef if non-default SkDiscardableMemory
should be used. Removed BitmapFactoryTest.
SkDiscardableMemory::Factory interface. Android will need this
functionality in the future inside their BitmapFactory.
Removed SkLazyPixelRef, since it's functionality is now subsumed into
SkDiscardablePixelRef. Removed LazyPixelRef test.
Modified SkDiscardablePixelRef to optionally allow it to use a
SkDiscardableMemory::Factory. This tiny change makes it a replacement
for SkLazyPixelRef. This functioanlity is also necessary for moving
Android over to SkDiscardablePixelRef from SkImageRef in a later CL.
Added a test for this.
SkDecodingImageGenerator::Install can optionally pass a factory in to
SkDiscardablePixelRef.
Removed SkImageCache, SkLruImageCache, and SkPurgeableImageCache.
This functionality can be handled much more cleanly by
SkDiscardableMemory.
New SkDiscardableMemoryPool class to replace SkLruImageCache. In a
later CL, we will replace SkImageRef_GlobalPool (used by android) as
well. This is a concrete implementation of
SkDiscardableMemory::Factory. Added a test for this.
modified gm/factory.cpp to remove dependnce on SkBitmapFactory +
SkLruImageCache. Now uses SkDecodingImageGenerator +
SkDiscardablePixelRef + SkDiscardableMemoryPool.
SkImageDecoder::Target replaces SkBitmapFactory::Target. The
DecodeMemoryToTarget function may disappear in the future.
Moved SkLazyCachingPixelRef::DecodeProc replaces
SkBitmapFactory::DecodeProc. This is a short term change, since
another CL changes SkLazyCachingPixelRef to use SkImageGenerator
instead of DecodeProc.
Modified DrawBitmapRectTest to use SkDiscardablePixelRef instead of
SkLazyPixelRef.
tools/LazyDecodeBitmap.cpp now uses SkDecodingImageGenerator +
SkDiscardablePixelRef instead of a SkBitmapFactory.
bench_pictures uses the Global SkDiscardableMemoryPool instead of a
global gLruImageCache.
R=reed@google.com, scroggo@google.com
Review URL: https://codereview.chromium.org/103033002
git-svn-id: http://skia.googlecode.com/svn/trunk@12515 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/BitmapFactoryTest.cpp b/tests/BitmapFactoryTest.cpp
deleted file mode 100644
index 9f1fa47..0000000
--- a/tests/BitmapFactoryTest.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifdef SK_DEBUG
-
-#include "SkBitmap.h"
-#include "SkBitmapFactory.h"
-#include "SkCanvas.h"
-#include "SkColor.h"
-#include "SkData.h"
-#include "SkImageDecoder.h"
-#include "SkImageEncoder.h"
-#include "SkLazyPixelRef.h"
-#include "SkLruImageCache.h"
-#include "SkPaint.h"
-#include "SkPurgeableImageCache.h"
-#include "SkStream.h"
-#include "SkTemplates.h"
-#include "Test.h"
-
-static SkBitmap* create_bitmap() {
- SkBitmap* bm = SkNEW(SkBitmap);
- // Use a large bitmap.
- const int W = 1000, H = 1000;
- bm->setConfig(SkBitmap::kARGB_8888_Config, W, H);
- bm->allocPixels();
- bm->eraseColor(SK_ColorBLACK);
- SkCanvas canvas(*bm);
- SkPaint paint;
- paint.setColor(SK_ColorBLUE);
- canvas.drawRectCoords(0, 0, SkIntToScalar(W/2), SkIntToScalar(H/2), paint);
- return bm;
-}
-
-static SkData* create_data_from_bitmap(const SkBitmap& bm) {
- SkDynamicMemoryWStream stream;
- if (SkImageEncoder::EncodeStream(&stream, bm, SkImageEncoder::kPNG_Type, 100)) {
- return stream.copyToData();
- }
- return NULL;
-}
-
-static void assert_bounds_equal(skiatest::Reporter* reporter, const SkBitmap& bm1,
- const SkBitmap& bm2) {
- REPORTER_ASSERT(reporter, bm1.width() == bm2.width());
- REPORTER_ASSERT(reporter, bm1.height() == bm2.height());
-}
-
-static void test_cache(skiatest::Reporter* reporter, SkImageCache* cache) {
- // Test the cache directly:
- cache->purgeAllUnpinnedCaches();
- intptr_t ID = SkImageCache::UNINITIALIZED_ID;
- const size_t size = 1000;
- char buffer[size];
- sk_bzero((void*) buffer, size);
- void* memory = cache->allocAndPinCache(size, &ID);
- if (memory != NULL) {
- memcpy(memory, (void*)buffer, size);
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID) == SkImageCache::kPinned_MemoryStatus);
- cache->releaseCache(ID);
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID) != SkImageCache::kPinned_MemoryStatus);
- SkImageCache::DataStatus dataStatus;
- memory = cache->pinCache(ID, &dataStatus);
- if (memory != NULL) {
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID)
- == SkImageCache::kPinned_MemoryStatus);
- if (SkImageCache::kRetained_DataStatus == dataStatus) {
- REPORTER_ASSERT(reporter, !memcmp(memory, (void*) buffer, size));
- }
- cache->releaseCache(ID);
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID)
- != SkImageCache::kPinned_MemoryStatus);
- cache->purgeAllUnpinnedCaches();
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID)
- != SkImageCache::kPinned_MemoryStatus);
- memory = cache->pinCache(ID, &dataStatus);
- if (memory != NULL) {
- // The memory block may or may not have survived the purging (at the
- // memory manager's whim) so we cannot check dataStatus here.
- cache->releaseCache(ID);
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID)
- != SkImageCache::kPinned_MemoryStatus);
- cache->throwAwayCache(ID);
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID)
- == SkImageCache::kFreed_MemoryStatus);
- } else {
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(ID)
- == SkImageCache::kFreed_MemoryStatus);
- }
- }
- }
-}
-
-static void test_factory(skiatest::Reporter* reporter, SkImageCache* cache, SkData* encodedData,
- const SkBitmap& origBitmap) {
- SkBitmapFactory factory(&SkImageDecoder::DecodeMemoryToTarget);
- factory.setImageCache(cache);
- SkAutoTDelete<SkBitmap> bitmapFromFactory(SkNEW(SkBitmap));
- bool success = factory.installPixelRef(encodedData, bitmapFromFactory.get());
- // This assumes that if the encoder worked, the decoder should also work, so the above call
- // should not fail.
- REPORTER_ASSERT(reporter, success);
- assert_bounds_equal(reporter, origBitmap, *bitmapFromFactory.get());
-
- SkPixelRef* pixelRef = bitmapFromFactory->pixelRef();
- REPORTER_ASSERT(reporter, pixelRef != NULL);
- if (NULL == cache) {
- // This assumes that installPixelRef called lockPixels.
- REPORTER_ASSERT(reporter, bitmapFromFactory->readyToDraw());
- } else {
- // Lazy decoding
- REPORTER_ASSERT(reporter, !bitmapFromFactory->readyToDraw());
- SkLazyPixelRef* lazyRef = static_cast<SkLazyPixelRef*>(pixelRef);
- intptr_t cacheID = lazyRef->getCacheId();
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(cacheID)
- != SkImageCache::kPinned_MemoryStatus);
- {
- SkAutoLockPixels alp(*bitmapFromFactory.get());
- REPORTER_ASSERT(reporter, bitmapFromFactory->readyToDraw());
- cacheID = lazyRef->getCacheId();
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(cacheID)
- == SkImageCache::kPinned_MemoryStatus);
- }
- REPORTER_ASSERT(reporter, !bitmapFromFactory->readyToDraw());
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(cacheID)
- != SkImageCache::kPinned_MemoryStatus);
- bitmapFromFactory.free();
- REPORTER_ASSERT(reporter, cache->getMemoryStatus(cacheID)
- == SkImageCache::kFreed_MemoryStatus);
- }
-}
-
-class ImageCacheHolder : public SkNoncopyable {
-
-public:
- ~ImageCacheHolder() {
- fCaches.safeUnrefAll();
- }
-
- void addImageCache(SkImageCache* cache) {
- SkSafeRef(cache);
- *fCaches.append() = cache;
- }
-
- int count() const { return fCaches.count(); }
-
- SkImageCache* getAt(int i) {
- if (i < 0 || i > fCaches.count()) {
- return NULL;
- }
- return fCaches.getAt(i);
- }
-
-private:
- SkTDArray<SkImageCache*> fCaches;
-};
-
-static void TestBitmapFactory(skiatest::Reporter* reporter) {
- SkAutoTDelete<SkBitmap> bitmap(create_bitmap());
- SkASSERT(bitmap.get() != NULL);
-
- SkAutoDataUnref encodedBitmap(create_data_from_bitmap(*bitmap.get()));
- bool encodeSucceeded = encodedBitmap.get() != NULL;
- SkASSERT(encodeSucceeded);
-
- ImageCacheHolder cacheHolder;
-
- SkAutoTUnref<SkLruImageCache> lruCache(SkNEW_ARGS(SkLruImageCache, (1024 * 1024)));
- cacheHolder.addImageCache(lruCache);
-
- cacheHolder.addImageCache(NULL);
-
- SkImageCache* purgeableCache = SkPurgeableImageCache::Create();
- if (purgeableCache != NULL) {
- cacheHolder.addImageCache(purgeableCache);
- purgeableCache->unref();
- }
-
- for (int i = 0; i < cacheHolder.count(); i++) {
- SkImageCache* cache = cacheHolder.getAt(i);
- if (cache != NULL) {
- test_cache(reporter, cache);
- }
- if (encodeSucceeded) {
- test_factory(reporter, cache, encodedBitmap, *bitmap.get());
- }
- }
-}
-
-#include "TestClassDef.h"
-DEFINE_TESTCLASS("BitmapFactory", TestBitmapFactoryClass, TestBitmapFactory)
-
-#endif // SK_DEBUG
diff --git a/tests/CachedDecodingPixelRefTest.cpp b/tests/CachedDecodingPixelRefTest.cpp
index 0706ab1..f92b1de 100644
--- a/tests/CachedDecodingPixelRefTest.cpp
+++ b/tests/CachedDecodingPixelRefTest.cpp
@@ -9,12 +9,13 @@
#include "SkCanvas.h"
#include "SkData.h"
#include "SkDecodingImageGenerator.h"
+#include "SkDiscardablePixelRef.h"
+#include "SkDiscardableMemoryPool.h"
#include "SkImageDecoder.h"
-#include "SkImagePriv.h"
-#include "SkLazyPixelRef.h"
#include "SkCachingPixelRef.h"
#include "SkScaledImageCache.h"
#include "SkStream.h"
+#include "SkUtils.h"
#include "Test.h"
#include "TestClassDef.h"
@@ -50,23 +51,7 @@
return NULL;
}
-/**
- * A simplified version of SkBitmapFactory
- */
-static bool simple_bitmap_factory(SkBitmapFactory::DecodeProc proc,
- SkData* data,
- SkBitmap* dst) {
- SkImageInfo info;
- if (!proc(data->data(), data->size(), &info, NULL)) {
- return false;
- }
- dst->setConfig(SkImageInfoToBitmapConfig(info), info.fWidth,
- info.fHeight, 0, info.fAlphaType);
- SkAutoTUnref<SkLazyPixelRef> ref(SkNEW_ARGS(SkLazyPixelRef,
- (data, proc, NULL)));
- dst->setPixelRef(ref);
- return true;
-}
+////////////////////////////////////////////////////////////////////////////////
static void compare_bitmaps(skiatest::Reporter* reporter,
const SkBitmap& b1, const SkBitmap& b2,
@@ -105,7 +90,6 @@
REPORTER_ASSERT(reporter, 0 == pixelErrors);
}
-
typedef bool (*InstallEncoded)(SkData* encoded, SkBitmap* dst);
/**
@@ -160,36 +144,169 @@
}
}
-
////////////////////////////////////////////////////////////////////////////////
-/**
- * This checks to see that a SkLazyPixelRef works as advertised.
- */
-static bool install_skLazyPixelRef(SkData* encoded, SkBitmap* dst) {
- static const SkBitmapFactory::DecodeProc decoder =
- &(SkImageDecoder::DecodeMemoryToTarget);
- return simple_bitmap_factory(decoder, encoded, dst);
-}
-DEF_TEST(LazyPixelRef, reporter) {
- test_three_encodings(reporter, install_skLazyPixelRef);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/**
- * This checks to see that a SkCachingPixelRef works as advertised.
- */
static bool install_skCachingPixelRef(SkData* encoded, SkBitmap* dst) {
return SkCachingPixelRef::Install(
SkNEW_ARGS(SkDecodingImageGenerator, (encoded)), dst);
}
-DEF_TEST(CachingPixelRef, reporter) {
- test_three_encodings(reporter, install_skCachingPixelRef);
+static bool install_skDiscardablePixelRef(SkData* encoded, SkBitmap* dst) {
+ // Use system-default discardable memory.
+ return SkDecodingImageGenerator::Install(encoded, dst, NULL);
}
////////////////////////////////////////////////////////////////////////////////
/**
- * This checks to see that a SkDecodingImageGenerator works as advertised.
+ * This checks to see that a SkCachingPixelRef and a
+ * SkDiscardablePixelRef works as advertised with a
+ * SkDecodingImageGenerator.
*/
DEF_TEST(DecodingImageGenerator, reporter) {
- test_three_encodings(reporter, SkDecodingImageGenerator::Install);
+ test_three_encodings(reporter, install_skCachingPixelRef);
+ test_three_encodings(reporter, install_skDiscardablePixelRef);
}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+class TestImageGenerator : public SkImageGenerator {
+public:
+ enum TestType {
+ kFailGetInfo_TestType,
+ kFailGetPixels_TestType,
+ kSucceedGetPixels_TestType,
+ kLast_TestType = kSucceedGetPixels_TestType
+ };
+ static int Width() { return 10; }
+ static int Height() { return 10; }
+ static SkColor Color() { return SK_ColorCYAN; }
+ TestImageGenerator(TestType type, skiatest::Reporter* reporter)
+ : fType(type), fReporter(reporter) {
+ SkASSERT((fType <= kLast_TestType) && (fType >= 0));
+ }
+ ~TestImageGenerator() { }
+ bool getInfo(SkImageInfo* info) SK_OVERRIDE {
+ REPORTER_ASSERT(fReporter, NULL != info);
+ if ((NULL == info) || (kFailGetInfo_TestType == fType)) {
+ return false;
+ }
+ info->fWidth = TestImageGenerator::Width();
+ info->fHeight = TestImageGenerator::Height();
+ info->fColorType = kPMColor_SkColorType;
+ info->fAlphaType = kOpaque_SkAlphaType;
+ return true;
+ }
+ bool getPixels(const SkImageInfo& info,
+ void* pixels,
+ size_t rowBytes) SK_OVERRIDE {
+ REPORTER_ASSERT(fReporter, pixels != NULL);
+ size_t minRowBytes
+ = static_cast<size_t>(info.fWidth * info.bytesPerPixel());
+ REPORTER_ASSERT(fReporter, rowBytes >= minRowBytes);
+ if ((NULL == pixels)
+ || (fType != kSucceedGetPixels_TestType)
+ || (info.fColorType != kPMColor_SkColorType)) {
+ return false;
+ }
+ char* bytePtr = static_cast<char*>(pixels);
+ for (int y = 0; y < info.fHeight; ++y) {
+ sk_memset32(reinterpret_cast<SkColor*>(bytePtr),
+ TestImageGenerator::Color(), info.fWidth);
+ bytePtr += rowBytes;
+ }
+ return true;
+ }
+private:
+ const TestType fType;
+ skiatest::Reporter* const fReporter;
+};
+void CheckTestImageGeneratorBitmap(skiatest::Reporter* reporter,
+ const SkBitmap& bm) {
+ REPORTER_ASSERT(reporter, TestImageGenerator::Width() == bm.width());
+ REPORTER_ASSERT(reporter, TestImageGenerator::Height() == bm.height());
+ SkAutoLockPixels autoLockPixels(bm);
+ REPORTER_ASSERT(reporter, NULL != bm.getPixels());
+ if (NULL == bm.getPixels()) {
+ return;
+ }
+ int errors = 0;
+ for (int y = 0; y < bm.height(); ++y) {
+ for (int x = 0; x < bm.width(); ++x) {
+ if (TestImageGenerator::Color() != *bm.getAddr32(x, y)) {
+ ++errors;
+ }
+ }
+ }
+ REPORTER_ASSERT(reporter, 0 == errors);
+}
+
+enum PixelRefType {
+ kSkCaching_PixelRefType,
+ kSkDiscardable_PixelRefType,
+ kLast_PixelRefType = kSkDiscardable_PixelRefType
+};
+void CheckPixelRef(TestImageGenerator::TestType type,
+ skiatest::Reporter* reporter,
+ PixelRefType pixelRefType,
+ SkDiscardableMemory::Factory* factory) {
+ SkASSERT((pixelRefType >= 0) && (pixelRefType <= kLast_PixelRefType));
+ SkAutoTDelete<SkImageGenerator> gen(SkNEW_ARGS(TestImageGenerator,
+ (type, reporter)));
+ REPORTER_ASSERT(reporter, gen.get() != NULL);
+ SkBitmap lazy;
+ bool success;
+ if (kSkCaching_PixelRefType == pixelRefType) {
+ // Ignore factory; use global SkScaledImageCache.
+ success = SkCachingPixelRef::Install(gen.detach(), &lazy);
+ } else {
+ success = SkDiscardablePixelRef::Install(gen.detach(), &lazy, factory);
+ }
+ REPORTER_ASSERT(reporter, success
+ == (TestImageGenerator::kFailGetInfo_TestType != type));
+ if (TestImageGenerator::kSucceedGetPixels_TestType == type) {
+ CheckTestImageGeneratorBitmap(reporter, lazy);
+ } else if (TestImageGenerator::kFailGetPixels_TestType == type) {
+ SkAutoLockPixels autoLockPixels(lazy);
+ REPORTER_ASSERT(reporter, NULL == lazy.getPixels());
+ }
+}
+} // namespace
+/**
+ * This tests the basic functionality of SkDiscardablePixelRef with a
+ * basic SkImageGenerator implementation and several
+ * SkDiscardableMemory::Factory choices.
+ */
+DEF_TEST(DiscardableAndCachingPixelRef, reporter) {
+ CheckPixelRef(TestImageGenerator::kFailGetInfo_TestType,
+ reporter, kSkCaching_PixelRefType, NULL);
+ CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType,
+ reporter, kSkCaching_PixelRefType, NULL);
+ CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType,
+ reporter, kSkCaching_PixelRefType, NULL);
+
+ CheckPixelRef(TestImageGenerator::kFailGetInfo_TestType,
+ reporter, kSkDiscardable_PixelRefType, NULL);
+ CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType,
+ reporter, kSkDiscardable_PixelRefType, NULL);
+ CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType,
+ reporter, kSkDiscardable_PixelRefType, NULL);
+
+ SkAutoTUnref<SkDiscardableMemoryPool> pool(
+ SkNEW_ARGS(SkDiscardableMemoryPool, (1, NULL)));
+ REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
+ CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType,
+ reporter, kSkDiscardable_PixelRefType, pool);
+ REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
+ CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType,
+ reporter, kSkDiscardable_PixelRefType, pool);
+ REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
+
+ SkDiscardableMemoryPool* globalPool = SkGetGlobalDiscardableMemoryPool();
+ CheckPixelRef(TestImageGenerator::kFailGetPixels_TestType,
+ reporter, kSkDiscardable_PixelRefType, globalPool);
+ CheckPixelRef(TestImageGenerator::kSucceedGetPixels_TestType,
+ reporter, kSkDiscardable_PixelRefType, globalPool);
+
+ // TODO(halcanary): When ashmem-backed SkDiscardableMemory lands,
+ // test that here (on platforms where it is availible).
+}
+////////////////////////////////////////////////////////////////////////////////
+
diff --git a/tests/DiscardableMemoryPool.cpp b/tests/DiscardableMemoryPool.cpp
new file mode 100644
index 0000000..8af7358
--- /dev/null
+++ b/tests/DiscardableMemoryPool.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkDiscardableMemoryPool.h"
+
+#include "Test.h"
+#include "TestClassDef.h"
+
+DEF_TEST(DiscardableMemoryPool, reporter) {
+ SkAutoTUnref<SkDiscardableMemoryPool> pool(
+ SkNEW_ARGS(SkDiscardableMemoryPool, (1, NULL)));
+ pool->setRAMBudget(3);
+ REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
+
+ SkAutoTDelete<SkDiscardableMemory> dm1(pool->create(100));
+ REPORTER_ASSERT(reporter, dm1->data() != NULL);
+ REPORTER_ASSERT(reporter, 100 == pool->getRAMUsed());
+ dm1->unlock();
+ REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
+ REPORTER_ASSERT(reporter, !dm1->lock());
+
+
+ SkAutoTDelete<SkDiscardableMemory> dm2(pool->create(200));
+ REPORTER_ASSERT(reporter, 200 == pool->getRAMUsed());
+ pool->setRAMBudget(400);
+ dm2->unlock();
+ REPORTER_ASSERT(reporter, 200 == pool->getRAMUsed());
+ REPORTER_ASSERT(reporter, dm2->lock());
+ dm2->unlock();
+ pool->dumpPool();
+ REPORTER_ASSERT(reporter, !dm2->lock());
+ REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
+}
+
diff --git a/tests/DrawBitmapRectTest.cpp b/tests/DrawBitmapRectTest.cpp
index 4c6d634..9289e11 100644
--- a/tests/DrawBitmapRectTest.cpp
+++ b/tests/DrawBitmapRectTest.cpp
@@ -9,41 +9,47 @@
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkData.h"
+#include "SkDiscardableMemoryPool.h"
+#include "SkDiscardablePixelRef.h"
#include "SkPaint.h"
#include "SkShader.h"
#include "SkSurface.h"
#include "SkRandom.h"
#include "SkMatrixUtils.h"
-#include "SkLazyPixelRef.h"
-#include "SkLruImageCache.h"
-
+namespace {
// A BitmapFactory that always fails when asked to return pixels.
-static bool FailureDecoder(const void* data, size_t length, SkImageInfo* info,
- const SkBitmapFactory::Target* target) {
- if (info) {
- info->fWidth = info->fHeight = 100;
- info->fColorType = kRGBA_8888_SkColorType;
+class FailureImageGenerator : public SkImageGenerator {
+public:
+ FailureImageGenerator() { }
+ virtual ~FailureImageGenerator() { }
+ virtual bool getInfo(SkImageInfo* info) {
+ info->fWidth = 100;
+ info->fHeight = 100;
+ info->fColorType = kPMColor_SkColorType;
info->fAlphaType = kPremul_SkAlphaType;
+ return true;
}
- // this will deliberately return false if they are asking us to decode
- // into pixels.
- return NULL == target;
-}
+ virtual bool getPixels(const SkImageInfo& info,
+ void* pixels,
+ size_t rowBytes) SK_OVERRIDE {
+ // this will deliberately return false if they are asking us
+ // to decode into pixels.
+ return false;
+ }
+};
+} // namespace
// crbug.com/295895
// Crashing in skia when a pixelref fails in lockPixels
//
static void test_faulty_pixelref(skiatest::Reporter* reporter) {
// need a cache, but don't expect to use it, so the budget is not critical
- SkLruImageCache cache(10 * 1000);
- // construct a garbage data represent "bad" encoded data.
- SkAutoDataUnref data(SkData::NewFromMalloc(malloc(1000), 1000));
- SkAutoTUnref<SkPixelRef> pr(new SkLazyPixelRef(data, FailureDecoder, &cache));
-
+ SkAutoTUnref<SkDiscardableMemoryPool> pool(SkNEW_ARGS(SkDiscardableMemoryPool,
+ (10 * 1000, NULL)));
SkBitmap bm;
- bm.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
- bm.setPixelRef(pr);
+ bool installSuccess = SkDiscardablePixelRef::Install(SkNEW(FailureImageGenerator), &bm, pool);
+ REPORTER_ASSERT(reporter, installSuccess);
// now our bitmap has a pixelref, but we know it will fail to lock
SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(200, 200));