add canCopyTo(), to preflight if copyTo can succeed. update unittests for it

git-svn-id: http://skia.googlecode.com/svn/trunk@169 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@android.com 2009-05-06 17:44:34 +00:00
Родитель 311c82db31
Коммит fbaa88d969
3 изменённых файлов: 40 добавлений и 17 удалений

Просмотреть файл

@ -367,12 +367,11 @@ public:
*/ */
bool extractSubset(SkBitmap* dst, const SkIRect& subset) const; bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
/** Tries to make a new bitmap based on the dimensions of this bitmap, /** Makes a deep copy of this bitmap, respecting the requested config.
setting the new bitmap's config to the one specified, and then copying Returns false if either there is an error (i.e. the src does not have
this bitmap's pixels into the new bitmap. If the conversion is not pixels) or the request cannot be satisfied (e.g. the src has per-pixel
supported, or the allocator fails, then this method returns false and alpha, and the requested config does not support alpha).
dst is left unchanged. @param dst The bitmap to be sized and allocated
@param dst The bitmap to be sized and allocated
@param c The desired config for dst @param c The desired config for dst
@param allocator Allocator used to allocate the pixelref for the dst @param allocator Allocator used to allocate the pixelref for the dst
bitmap. If this is null, the standard HeapAllocator bitmap. If this is null, the standard HeapAllocator
@ -380,6 +379,11 @@ public:
@return true if the copy could be made. @return true if the copy could be made.
*/ */
bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const; bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const;
/** Returns true if this bitmap can be deep copied into the requested config
by calling copyTo().
*/
bool canCopyTo(Config newConfig) const;
bool hasMipMap() const; bool hasMipMap() const;
void buildMipMap(bool forceRebuild = false); void buildMipMap(bool forceRebuild = false);

Просмотреть файл

@ -682,13 +682,12 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
#include "SkCanvas.h" #include "SkCanvas.h"
#include "SkPaint.h" #include "SkPaint.h"
bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { bool SkBitmap::canCopyTo(Config dstConfig) const {
if (NULL == dst || this->getConfig() == kNo_Config if (this->getConfig() == kNo_Config) {
|| this->width() == 0 || this->height() == 0) {
return false; return false;
} }
bool sameConfigs = (dstConfig == this->config()); bool sameConfigs = (this->config() == dstConfig);
switch (dstConfig) { switch (dstConfig) {
case kA8_Config: case kA8_Config:
case kARGB_4444_Config: case kARGB_4444_Config:
@ -710,8 +709,19 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
return false; return false;
} }
return true;
}
bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
if (!this->canCopyTo(dstConfig)) {
return false;
}
// we lock this now, since we may need its colortable // we lock this now, since we may need its colortable
SkAutoLockPixels srclock(*this); SkAutoLockPixels srclock(*this);
if (!this->readyToDraw()) {
return false;
}
SkBitmap tmp; SkBitmap tmp;
tmp.setConfig(dstConfig, this->width(), this->height()); tmp.setConfig(dstConfig, this->width(), this->height());
@ -725,16 +735,14 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
} }
SkAutoLockPixels dstlock(tmp); SkAutoLockPixels dstlock(tmp);
if (!tmp.readyToDraw()) {
if (!this->readyToDraw() || !tmp.readyToDraw()) {
// allocator/lock failed // allocator/lock failed
return false; return false;
} }
/* do memcpy for the sameConfigs cases and /* do memcpy for the same configs cases, else use drawing
re-draw for the !sameConfigs cases
*/ */
if (sameConfigs) { if (this->config() == dstConfig) {
if (tmp.getSize() == this->getSize()) { if (tmp.getSize() == this->getSize()) {
memcpy(tmp.getPixels(), this->getPixels(), this->getSize()); memcpy(tmp.getPixels(), this->getPixels(), this->getSize());
} else { } else {

Просмотреть файл

@ -39,7 +39,8 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
{ SkBitmap::kRGB_565_Config, "00101110" }, { SkBitmap::kRGB_565_Config, "00101110" },
{ SkBitmap::kARGB_4444_Config, "00101110" }, { SkBitmap::kARGB_4444_Config, "00101110" },
{ SkBitmap::kARGB_8888_Config, "00101110" }, { SkBitmap::kARGB_8888_Config, "00101110" },
{ SkBitmap::kRLE_Index8_Config, "00000000" } // TODO: create valid RLE bitmap to test with
// { SkBitmap::kRLE_Index8_Config, "00101111" }
}; };
const int W = 20; const int W = 20;
@ -51,7 +52,8 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
SkColorTable* ct = NULL; SkColorTable* ct = NULL;
src.setConfig(gPairs[i].fConfig, W, H); src.setConfig(gPairs[i].fConfig, W, H);
if (SkBitmap::kIndex8_Config == src.config()) { if (SkBitmap::kIndex8_Config == src.config() ||
SkBitmap::kRLE_Index8_Config == src.config()) {
ct = init_ctable(); ct = init_ctable();
} }
src.allocPixels(ct); src.allocPixels(ct);
@ -67,6 +69,15 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
boolStr(success)); boolStr(success));
reporter->reportFailed(str); reporter->reportFailed(str);
} }
bool canSucceed = src.canCopyTo(gPairs[j].fConfig);
if (success != canSucceed) {
SkString str;
str.printf("SkBitmap::copyTo from %s to %s. returned %s canCopyTo %s",
gConfigName[i], gConfigName[j], boolStr(success),
boolStr(canSucceed));
reporter->reportFailed(str);
}
if (success) { if (success) {
REPORTER_ASSERT(reporter, src.width() == dst.width()); REPORTER_ASSERT(reporter, src.width() == dst.width());