remove dead mipmap code from SkBitmap

BUG=skia:
R=fmalita@google.com, fmalita@chromium.org

Author: reed@google.com

Review URL: https://codereview.chromium.org/271693002

git-svn-id: http://skia.googlecode.com/svn/trunk@14611 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2014-05-07 15:05:34 +00:00
parent f5bf3cf025
commit eaca36b657
4 changed files with 4 additions and 431 deletions

View File

@ -1,111 +0,0 @@
/*
* 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 "gm.h"
#include "SkImageDecoder.h"
#include "SkStream.h"
class ScaleBitmapGM : public skiagm::GM {
public:
ScaleBitmapGM(const char filename[], float scale)
: fFilename(filename), fScale(scale)
{
this->setBGColor(0xFFDDDDDD);
fName.printf("scalebitmap_%s_%f", filename, scale);
SkString path(skiagm::GM::gResourcePath);
path.append("/");
path.append(fFilename);
SkImageDecoder *codec = NULL;
SkFILEStream stream(path.c_str());
if (stream.isValid()) {
codec = SkImageDecoder::Factory(&stream);
}
if (codec) {
stream.rewind();
codec->decode(&stream, &fBM, SkBitmap::kARGB_8888_Config,
SkImageDecoder::kDecodePixels_Mode);
SkDELETE(codec);
} else {
fBM.allocN32Pixels(1, 1);
*(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad
}
fSize = fBM.height();
}
protected:
SkBitmap fBM;
SkString fName;
SkString fFilename;
int fSize;
float fScale;
virtual SkString onShortName() SK_OVERRIDE {
return fName;
}
virtual SkISize onISize() SK_OVERRIDE {
return SkISize::Make(fBM.width() * fScale, fBM.height() * fScale);
}
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
SkBitmap dst;
dst.allocN32Pixels(fBM.width() * fScale, fBM.height() * fScale);
fBM.scale(&dst);
canvas->drawBitmap(dst, 0, 0);
}
private:
typedef skiagm::GM INHERITED;
};
class ScaleBitmapMipmapGM: public ScaleBitmapGM {
SkMatrix fMatrix;
public:
ScaleBitmapMipmapGM(const char filename[], float scale)
: INHERITED(filename, scale)
{
fName.printf("scalebitmap_mipmap_%s_%f", filename, scale);
fBM.buildMipMap();
fMatrix.setScale(scale, scale);
}
protected:
virtual void onDraw(SkCanvas *canvas) SK_OVERRIDE {
SkPaint paint;
paint.setFilterBitmap(true);
canvas->drawBitmapMatrix(fBM, fMatrix, &paint);
}
private:
typedef ScaleBitmapGM INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_GM( return new ScaleBitmapGM("mandrill_128.png", 2); )
DEF_GM( return new ScaleBitmapGM("mandrill_64.png", 4); )
DEF_GM( return new ScaleBitmapGM("mandrill_32.png", 8); )
DEF_GM( return new ScaleBitmapGM("mandrill_16.png", 16); )
DEF_GM( return new ScaleBitmapGM("nature.jpg", 0.5f); )
DEF_GM( return new ScaleBitmapGM("nature.jpg", 0.25f); )
DEF_GM( return new ScaleBitmapGM("nature.jpg", 0.125f); )
DEF_GM( return new ScaleBitmapGM("nature.jpg", 0.0625f); )
DEF_GM( return new ScaleBitmapMipmapGM("nature.jpg", 0.5f); )
DEF_GM( return new ScaleBitmapMipmapGM("nature.jpg", 0.25f); )
DEF_GM( return new ScaleBitmapMipmapGM("nature.jpg", 0.125f); )
DEF_GM( return new ScaleBitmapMipmapGM("nature.jpg", 0.0625f); )

View File

@ -16,6 +16,7 @@
'SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1',
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
'SK_SUPPORT_LEGACY_N32_NAME',
'SK_SUPPORT_LEGACY_BUILDMIPMAP',
'SK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE',
],
},

View File

@ -647,8 +647,10 @@ public:
*/
bool deepCopyTo(SkBitmap* dst) const;
#ifdef SK_SUPPORT_LEGACY_BUILDMIPMAP
SK_ATTR_DEPRECATED("use setFilterLevel on SkPaint")
void buildMipMap(bool forceRebuild = false);
void buildMipMap(bool forceRebuild = false) {}
#endif
#ifdef SK_BUILD_FOR_ANDROID
bool hasHardwareMipMap() const {
@ -750,9 +752,6 @@ public:
SK_TO_STRING_NONVIRT()
private:
struct MipMap;
mutable MipMap* fMipMap;
mutable SkPixelRef* fPixelRef;
mutable int fPixelLockCount;
// These are just caches from the locked pixelref
@ -798,16 +797,6 @@ private:
void freePixels();
void updatePixelsFromRef() const;
static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy);
/** Given scale factors sx, sy, determine the miplevel available in the
bitmap, and return it (this is the amount to shift matrix iterators
by). If dst is not null, it is set to the correct level.
*/
int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
bool hasMipMap() const;
void freeMipMap();
friend struct SkBitmapProcState;
};

View File

@ -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;
}
@ -1188,251 +1127,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,