Index: src/core/SkBitmap.cpp |
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp |
index b8c7fc7a4c708d0cfded0a0e93f6d5285a44997d..84f363e564f2a7a46e6928c430d2744dca88bb46 100644 |
--- a/src/core/SkBitmap.cpp |
+++ b/src/core/SkBitmap.cpp |
@@ -29,55 +29,6 @@ static bool reset_return_false(SkBitmap* bm) { |
return false; |
} |
-struct MipLevel { |
- void* fPixels; |
- uint32_t fRowBytes; |
- uint32_t fWidth, fHeight; |
-}; |
- |
-struct SkBitmap::MipMap : SkNoncopyable { |
- int32_t fRefCnt; |
- int fLevelCount; |
-// MipLevel fLevel[fLevelCount]; |
-// Pixels[] |
- |
- static MipMap* Alloc(int levelCount, size_t pixelSize) { |
- if (levelCount < 0) { |
- return NULL; |
- } |
- int64_t size = (levelCount + 1) * sizeof(MipLevel); |
- size += sizeof(MipMap) + pixelSize; |
- if (!sk_64_isS32(size)) { |
- return NULL; |
- } |
- MipMap* mm = (MipMap*)sk_malloc_throw(sk_64_asS32(size)); |
- mm->fRefCnt = 1; |
- mm->fLevelCount = levelCount; |
- return mm; |
- } |
- |
- const MipLevel* levels() const { return (const MipLevel*)(this + 1); } |
- MipLevel* levels() { return (MipLevel*)(this + 1); } |
- |
- const void* pixels() const { return levels() + fLevelCount; } |
- void* pixels() { return levels() + fLevelCount; } |
- |
- void ref() { |
- if (SK_MaxS32 == sk_atomic_inc(&fRefCnt)) { |
- sk_throw(); |
- } |
- } |
- void unref() { |
- SkASSERT(fRefCnt > 0); |
- if (sk_atomic_dec(&fRefCnt) == 1) { |
- sk_free(this); |
- } |
- } |
-}; |
- |
-/////////////////////////////////////////////////////////////////////////////// |
-/////////////////////////////////////////////////////////////////////////////// |
- |
SkBitmap::SkBitmap() { |
sk_bzero(this, sizeof(*this)); |
} |
@@ -101,7 +52,6 @@ SkBitmap& SkBitmap::operator=(const SkBitmap& src) { |
// inc src reference counts |
SkSafeRef(src.fPixelRef); |
- SkSafeRef(src.fMipMap); |
// we reset our locks if we get blown away |
fPixelLockCount = 0; |
@@ -128,7 +78,6 @@ void SkBitmap::swap(SkBitmap& other) { |
SkTSwap(fPixelRef, other.fPixelRef); |
SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin); |
SkTSwap(fPixelLockCount, other.fPixelLockCount); |
- SkTSwap(fMipMap, other.fMipMap); |
SkTSwap(fPixels, other.fPixels); |
SkTSwap(fInfo, other.fInfo); |
SkTSwap(fRowBytes, other.fRowBytes); |
@@ -542,9 +491,6 @@ bool SkBitmap::allocConfigPixels(Config config, int width, int height, |
/////////////////////////////////////////////////////////////////////////////// |
void SkBitmap::freePixels() { |
- // if we're gonna free the pixels, we certainly need to free the mipmap |
- this->freeMipMap(); |
- |
if (NULL != fPixelRef) { |
if (fPixelLockCount > 0) { |
fPixelRef->unlockPixels(); |
@@ -558,13 +504,6 @@ void SkBitmap::freePixels() { |
fColorTable = NULL; |
} |
-void SkBitmap::freeMipMap() { |
- if (fMipMap) { |
- fMipMap->unref(); |
- fMipMap = NULL; |
- } |
-} |
- |
uint32_t SkBitmap::getGenerationID() const { |
return (fPixelRef) ? fPixelRef->getGenerationID() : 0; |
} |
@@ -1189,251 +1128,6 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst) const { |
} |
/////////////////////////////////////////////////////////////////////////////// |
-/////////////////////////////////////////////////////////////////////////////// |
- |
-static void downsampleby2_proc32(SkBitmap* dst, int x, int y, |
- const SkBitmap& src) { |
- x <<= 1; |
- y <<= 1; |
- const SkPMColor* p = src.getAddr32(x, y); |
- const SkPMColor* baseP = p; |
- SkPMColor c, ag, rb; |
- |
- c = *p; ag = (c >> 8) & 0xFF00FF; rb = c & 0xFF00FF; |
- if (x < src.width() - 1) { |
- p += 1; |
- } |
- c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF; |
- |
- p = baseP; |
- if (y < src.height() - 1) { |
- p += src.rowBytes() >> 2; |
- } |
- c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF; |
- if (x < src.width() - 1) { |
- p += 1; |
- } |
- c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF; |
- |
- *dst->getAddr32(x >> 1, y >> 1) = |
- ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00); |
-} |
- |
-static inline uint32_t expand16(U16CPU c) { |
- return (c & ~SK_G16_MASK_IN_PLACE) | ((c & SK_G16_MASK_IN_PLACE) << 16); |
-} |
- |
-// returns dirt in the top 16bits, but we don't care, since we only |
-// store the low 16bits. |
-static inline U16CPU pack16(uint32_t c) { |
- return (c & ~SK_G16_MASK_IN_PLACE) | ((c >> 16) & SK_G16_MASK_IN_PLACE); |
-} |
- |
-static void downsampleby2_proc16(SkBitmap* dst, int x, int y, |
- const SkBitmap& src) { |
- x <<= 1; |
- y <<= 1; |
- const uint16_t* p = src.getAddr16(x, y); |
- const uint16_t* baseP = p; |
- SkPMColor c; |
- |
- c = expand16(*p); |
- if (x < src.width() - 1) { |
- p += 1; |
- } |
- c += expand16(*p); |
- |
- p = baseP; |
- if (y < src.height() - 1) { |
- p += src.rowBytes() >> 1; |
- } |
- c += expand16(*p); |
- if (x < src.width() - 1) { |
- p += 1; |
- } |
- c += expand16(*p); |
- |
- *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)pack16(c >> 2); |
-} |
- |
-static uint32_t expand4444(U16CPU c) { |
- return (c & 0xF0F) | ((c & ~0xF0F) << 12); |
-} |
- |
-static U16CPU collaps4444(uint32_t c) { |
- return (c & 0xF0F) | ((c >> 12) & ~0xF0F); |
-} |
- |
-static void downsampleby2_proc4444(SkBitmap* dst, int x, int y, |
- const SkBitmap& src) { |
- x <<= 1; |
- y <<= 1; |
- const uint16_t* p = src.getAddr16(x, y); |
- const uint16_t* baseP = p; |
- uint32_t c; |
- |
- c = expand4444(*p); |
- if (x < src.width() - 1) { |
- p += 1; |
- } |
- c += expand4444(*p); |
- |
- p = baseP; |
- if (y < src.height() - 1) { |
- p += src.rowBytes() >> 1; |
- } |
- c += expand4444(*p); |
- if (x < src.width() - 1) { |
- p += 1; |
- } |
- c += expand4444(*p); |
- |
- *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)collaps4444(c >> 2); |
-} |
- |
-void SkBitmap::buildMipMap(bool forceRebuild) { |
- if (forceRebuild) |
- this->freeMipMap(); |
- else if (fMipMap) |
- return; // we're already built |
- |
- SkASSERT(NULL == fMipMap); |
- |
- void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src); |
- |
- const SkBitmap::Config config = this->config(); |
- |
- switch (config) { |
- case kARGB_8888_Config: |
- proc = downsampleby2_proc32; |
- break; |
- case kRGB_565_Config: |
- proc = downsampleby2_proc16; |
- break; |
- case kARGB_4444_Config: |
- proc = downsampleby2_proc4444; |
- break; |
- case kIndex8_Config: |
- case kA8_Config: |
- default: |
- return; // don't build mipmaps for these configs |
- } |
- |
- SkAutoLockPixels alp(*this); |
- if (!this->readyToDraw()) { |
- return; |
- } |
- |
- // whip through our loop to compute the exact size needed |
- size_t size = 0; |
- int maxLevels = 0; |
- { |
- int width = this->width(); |
- int height = this->height(); |
- for (;;) { |
- width >>= 1; |
- height >>= 1; |
- if (0 == width || 0 == height) { |
- break; |
- } |
- size += ComputeRowBytes(config, width) * height; |
- maxLevels += 1; |
- } |
- } |
- |
- // nothing to build |
- if (0 == maxLevels) { |
- return; |
- } |
- |
- SkBitmap srcBM(*this); |
- srcBM.lockPixels(); |
- if (!srcBM.readyToDraw()) { |
- return; |
- } |
- |
- MipMap* mm = MipMap::Alloc(maxLevels, size); |
- if (NULL == mm) { |
- return; |
- } |
- |
- MipLevel* level = mm->levels(); |
- uint8_t* addr = (uint8_t*)mm->pixels(); |
- int width = this->width(); |
- int height = this->height(); |
- uint32_t rowBytes; |
- SkBitmap dstBM; |
- |
- for (int i = 0; i < maxLevels; i++) { |
- width >>= 1; |
- height >>= 1; |
- rowBytes = SkToU32(ComputeRowBytes(config, width)); |
- |
- level[i].fPixels = addr; |
- level[i].fWidth = width; |
- level[i].fHeight = height; |
- level[i].fRowBytes = rowBytes; |
- |
- dstBM.setConfig(config, width, height, rowBytes); |
- dstBM.setPixels(addr); |
- |
- srcBM.lockPixels(); |
- for (int y = 0; y < height; y++) { |
- for (int x = 0; x < width; x++) { |
- proc(&dstBM, x, y, srcBM); |
- } |
- } |
- srcBM.unlockPixels(); |
- |
- srcBM = dstBM; |
- addr += height * rowBytes; |
- } |
- SkASSERT(addr == (uint8_t*)mm->pixels() + size); |
- fMipMap = mm; |
-} |
- |
-bool SkBitmap::hasMipMap() const { |
- return fMipMap != NULL; |
-} |
- |
-int SkBitmap::extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy) { |
- if (NULL == fMipMap) { |
- return 0; |
- } |
- |
- int level = ComputeMipLevel(sx, sy) >> 16; |
- SkASSERT(level >= 0); |
- if (level <= 0) { |
- return 0; |
- } |
- |
- if (level >= fMipMap->fLevelCount) { |
- level = fMipMap->fLevelCount - 1; |
- } |
- if (dst) { |
- const MipLevel& mip = fMipMap->levels()[level - 1]; |
- dst->setConfig((SkBitmap::Config)this->config(), |
- mip.fWidth, mip.fHeight, mip.fRowBytes); |
- dst->setPixels(mip.fPixels); |
- } |
- return level; |
-} |
- |
-SkFixed SkBitmap::ComputeMipLevel(SkFixed sx, SkFixed sy) { |
- sx = SkAbs32(sx); |
- sy = SkAbs32(sy); |
- if (sx < sy) { |
- sx = sy; |
- } |
- if (sx < SK_Fixed1) { |
- return 0; |
- } |
- int clz = SkCLZ(sx); |
- SkASSERT(clz >= 1 && clz <= 15); |
- return SkIntToFixed(15 - clz) + ((unsigned)(sx << (clz + 1)) >> 16); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////// |
static bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, |
int alphaRowBytes) { |