Index: src/core/SkMipMap.cpp |
diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp |
index cb88eb4596be618e9eab7519f889b2fb6a64d3e0..fdfb660ccc66a2aa06deca8a052350b30ead8aaa 100644 |
--- a/src/core/SkMipMap.cpp |
+++ b/src/core/SkMipMap.cpp |
@@ -109,18 +109,18 @@ static void downsampleby2_proc4444(SkBitmap* dst, int x, int y, |
*dst->getAddr16(x >> 1, y >> 1) = (uint16_t)collaps4444(c >> 2); |
} |
-SkMipMap::Level* SkMipMap::AllocLevels(int levelCount, size_t pixelSize) { |
+size_t SkMipMap::AllocLevelsSize(int levelCount, size_t pixelSize) { |
if (levelCount < 0) { |
- return NULL; |
+ return 0; |
} |
int64_t size = sk_64_mul(levelCount + 1, sizeof(Level)) + pixelSize; |
if (!sk_64_isS32(size)) { |
- return NULL; |
+ return 0; |
} |
- return (Level*)sk_malloc_throw(sk_64_asS32(size)); |
+ return sk_64_asS32(size); |
} |
-SkMipMap* SkMipMap::Build(const SkBitmap& src) { |
+SkMipMap* SkMipMap::Build(const SkBitmap& src, SkDiscardableFactoryProc fact) { |
void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src); |
const SkColorType ct = src.colorType(); |
@@ -165,11 +165,27 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src) { |
return NULL; |
} |
- Level* levels = SkMipMap::AllocLevels(countLevels, size); |
- if (NULL == levels) { |
+ size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size); |
+ if (0 == storageSize) { |
return NULL; |
} |
+ SkMipMap* mipmap; |
+ if (fact) { |
+ SkDiscardableMemory* dm = fact(storageSize); |
+ if (NULL == dm) { |
+ return NULL; |
+ } |
+ mipmap = SkNEW_ARGS(SkMipMap, (storageSize, dm)); |
+ } else { |
+ mipmap = SkNEW_ARGS(SkMipMap, (sk_malloc_throw(storageSize), storageSize)); |
+ } |
+ |
+ // init |
+ mipmap->fCount = countLevels; |
+ mipmap->fLevels = (Level*)mipmap->writable_data(); |
+ |
+ Level* levels = mipmap->fLevels; |
uint8_t* baseAddr = (uint8_t*)&levels[countLevels]; |
uint8_t* addr = baseAddr; |
int width = src.width(); |
@@ -204,25 +220,13 @@ SkMipMap* SkMipMap::Build(const SkBitmap& src) { |
} |
SkASSERT(addr == baseAddr + size); |
- return SkNEW_ARGS(SkMipMap, (levels, countLevels, size)); |
+ return mipmap; |
} |
/////////////////////////////////////////////////////////////////////////////// |
//static int gCounter; |
-SkMipMap::SkMipMap(Level* levels, int count, size_t size) |
- : fSize(size), fLevels(levels), fCount(count) { |
- SkASSERT(levels); |
- SkASSERT(count > 0); |
-// SkDebugf("mips %d\n", ++gCounter); |
-} |
- |
-SkMipMap::~SkMipMap() { |
- sk_free(fLevels); |
-// SkDebugf("mips %d\n", --gCounter); |
-} |
- |
static SkFixed compute_level(SkScalar scale) { |
SkFixed s = SkAbs32(SkScalarToFixed(SkScalarInvert(scale))); |
@@ -235,6 +239,10 @@ static SkFixed compute_level(SkScalar scale) { |
} |
bool SkMipMap::extractLevel(SkScalar scale, Level* levelPtr) const { |
+ if (NULL == fLevels) { |
+ return false; |
+ } |
+ |
if (scale >= SK_Scalar1) { |
return false; |
} |