free cache in destructor, in case endContext was not called. change Resize to return bool indicating success.

BUG=
R=humper@google.com

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

git-svn-id: http://skia.googlecode.com/svn/trunk@10335 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2013-07-24 20:10:42 +00:00
parent 2c88fe87bd
commit 1e182253f8
4 changed files with 58 additions and 39 deletions

View File

@ -157,11 +157,17 @@ void SkBitmapProcState::possiblyScaleImage() {
// All the criteria are met; let's make a new bitmap.
fScaledBitmap = SkBitmapScaler::Resize(fOrigBitmap,
SkBitmapScaler::RESIZE_BEST,
dest_width,
dest_height,
fConvolutionProcs);
if (!SkBitmapScaler::Resize(&fScaledBitmap,
fOrigBitmap,
SkBitmapScaler::RESIZE_BEST,
dest_width,
dest_height,
fConvolutionProcs)) {
// we failed to create fScaledBitmap, so just return and let
// the scanline proc handle it.
return;
}
fScaledCacheID = SkScaledImageCache::AddAndLock(fOrigBitmap,
invScaleX,
invScaleY,
@ -277,6 +283,13 @@ void SkBitmapProcState::endContext() {
}
}
SkBitmapProcState::~SkBitmapProcState() {
if (fScaledCacheID) {
SkScaledImageCache::Unlock(fScaledCacheID);
}
SkDELETE(fBitmapFilter);
}
bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) {
return false;

View File

@ -37,10 +37,7 @@ struct SkConvolutionProcs;
struct SkBitmapProcState {
SkBitmapProcState(): fScaledCacheID(NULL), fBitmapFilter(NULL) {}
~SkBitmapProcState() {
SkASSERT(NULL == fScaledCacheID);
SkDELETE(fBitmapFilter);
}
~SkBitmapProcState();
typedef void (*ShaderProc32)(const SkBitmapProcState&, int x, int y,
SkPMColor[], int count);

View File

@ -233,12 +233,13 @@ static SkBitmapScaler::ResizeMethod ResizeMethodToAlgorithmMethod(
}
// static
SkBitmap SkBitmapScaler::Resize(const SkBitmap& source,
ResizeMethod method,
int destWidth, int destHeight,
const SkIRect& destSubset,
SkConvolutionProcs* convolveProcs,
SkBitmap::Allocator* allocator) {
bool SkBitmapScaler::Resize(SkBitmap* resultPtr,
const SkBitmap& source,
ResizeMethod method,
int destWidth, int destHeight,
const SkIRect& destSubset,
SkConvolutionProcs* convolveProcs,
SkBitmap::Allocator* allocator) {
// Ensure that the ResizeMethod enumeration is sound.
SkASSERT(((RESIZE_FIRST_QUALITY_METHOD <= method) &&
(method <= RESIZE_LAST_QUALITY_METHOD)) ||
@ -257,7 +258,9 @@ SkBitmap SkBitmapScaler::Resize(const SkBitmap& source,
// return empty.
if (source.width() < 1 || source.height() < 1 ||
destWidth < 1 || destHeight < 1) {
return SkBitmap();
// todo: seems like we could handle negative dstWidth/Height, since that
// is just a negative scale (flip)
return false;
}
method = ResizeMethodToAlgorithmMethod(method);
@ -267,8 +270,10 @@ SkBitmap SkBitmapScaler::Resize(const SkBitmap& source,
(method <= SkBitmapScaler::RESIZE_LAST_ALGORITHM_METHOD));
SkAutoLockPixels locker(source);
if (!source.readyToDraw() || source.config() != SkBitmap::kARGB_8888_Config)
return SkBitmap();
if (!source.readyToDraw() ||
source.config() != SkBitmap::kARGB_8888_Config) {
return false;
}
SkResizeFilter filter(method, source.width(), source.height(),
destWidth, destHeight, destSubset, convolveProcs);
@ -284,8 +289,9 @@ SkBitmap SkBitmapScaler::Resize(const SkBitmap& source,
result.setConfig(SkBitmap::kARGB_8888_Config,
destSubset.width(), destSubset.height());
result.allocPixels(allocator, NULL);
if (!result.readyToDraw())
return SkBitmap();
if (!result.readyToDraw()) {
return false;
}
BGRAConvolve2D(sourceSubset, static_cast<int>(source.rowBytes()),
!source.isOpaque(), filter.xFilter(), filter.yFilter(),
@ -295,17 +301,18 @@ SkBitmap SkBitmapScaler::Resize(const SkBitmap& source,
// Preserve the "opaque" flag for use as an optimization later.
result.setIsOpaque(source.isOpaque());
return result;
*resultPtr = result;
return true;
}
// static
SkBitmap SkBitmapScaler::Resize(const SkBitmap& source,
ResizeMethod method,
int destWidth, int destHeight,
SkConvolutionProcs* convolveProcs,
SkBitmap::Allocator* allocator) {
bool SkBitmapScaler::Resize(SkBitmap* resultPtr,
const SkBitmap& source,
ResizeMethod method,
int destWidth, int destHeight,
SkConvolutionProcs* convolveProcs,
SkBitmap::Allocator* allocator) {
SkIRect destSubset = { 0, 0, destWidth, destHeight };
return Resize(source, method, destWidth, destHeight, destSubset,
return Resize(resultPtr, source, method, destWidth, destHeight, destSubset,
convolveProcs, allocator);
}

View File

@ -87,20 +87,22 @@ public:
// will save work if you do not need the entire bitmap.
//
// The destination subset must be smaller than the destination image.
static SkBitmap Resize(const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
const SkIRect& dest_subset,
SkConvolutionProcs *convolveProcs = NULL,
SkBitmap::Allocator* allocator = NULL);
static bool Resize(SkBitmap* result,
const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
const SkIRect& dest_subset,
SkConvolutionProcs *convolveProcs = NULL,
SkBitmap::Allocator* allocator = NULL);
// Alternate version for resizing and returning the entire bitmap rather than
// a subset.
static SkBitmap Resize(const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
SkConvolutionProcs *convolveProcs = NULL,
SkBitmap::Allocator* allocator = NULL);
static bool Resize(SkBitmap* result,
const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
SkConvolutionProcs *convolveProcs = NULL,
SkBitmap::Allocator* allocator = NULL);
};
#endif