cafc9f9e80
- copyTo() now preserves isOpaqueness, and BitmapCopyTest tests it - bitmap shader doesn't claim to have shadespan16 if dithering is on, since its sampler doesn't auto-dither (note that gradients do auto-dither in their 16bit sampler) - blitter setup just relies on the shader to report if its 16bit sampler can be called (allowing gradients to say yes regardless of dither, but bitmaps to say no if dithering is on) git-svn-id: http://skia.googlecode.com/svn/trunk@331 2bbb7eff-a529-9590-31e7-b0007b416f81
185 lines
7.0 KiB
C++
185 lines
7.0 KiB
C++
#include "Test.h"
|
|
#include "SkBitmap.h"
|
|
#include "SkRect.h"
|
|
|
|
static const char* boolStr(bool value) {
|
|
return value ? "true" : "false";
|
|
}
|
|
|
|
// these are in the same order as the SkBitmap::Config enum
|
|
static const char* gConfigName[] = {
|
|
"None", "A1", "A8", "Index8", "565", "4444", "8888", "RLE_Index8"
|
|
};
|
|
|
|
static void report_opaqueness(skiatest::Reporter* reporter, const SkBitmap& src,
|
|
const SkBitmap& dst) {
|
|
SkString str;
|
|
str.printf("src %s opaque:%d, dst %s opaque:%d",
|
|
gConfigName[src.config()], src.isOpaque(),
|
|
gConfigName[dst.config()], dst.isOpaque());
|
|
reporter->reportFailed(str);
|
|
}
|
|
|
|
static bool canHaveAlpha(SkBitmap::Config config) {
|
|
return config != SkBitmap::kRGB_565_Config;
|
|
}
|
|
|
|
// copyTo() should preserve isOpaque when it makes sense
|
|
static void test_isOpaque(skiatest::Reporter* reporter, const SkBitmap& src,
|
|
SkBitmap::Config dstConfig) {
|
|
SkBitmap bitmap(src);
|
|
SkBitmap dst;
|
|
|
|
// we need the lock so that we get a valid colorTable (when available)
|
|
SkAutoLockPixels alp(bitmap);
|
|
SkColorTable* ctable = bitmap.getColorTable();
|
|
unsigned ctableFlags = ctable ? ctable->getFlags() : 0;
|
|
|
|
if (canHaveAlpha(bitmap.config()) && canHaveAlpha(dstConfig)) {
|
|
bitmap.setIsOpaque(false);
|
|
if (ctable) {
|
|
ctable->setFlags(ctableFlags & ~SkColorTable::kColorsAreOpaque_Flag);
|
|
}
|
|
REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig));
|
|
REPORTER_ASSERT(reporter, dst.config() == dstConfig);
|
|
if (bitmap.isOpaque() != dst.isOpaque()) {
|
|
report_opaqueness(reporter, bitmap, dst);
|
|
}
|
|
}
|
|
|
|
bitmap.setIsOpaque(true);
|
|
if (ctable) {
|
|
ctable->setFlags(ctableFlags | SkColorTable::kColorsAreOpaque_Flag);
|
|
}
|
|
REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig));
|
|
REPORTER_ASSERT(reporter, dst.config() == dstConfig);
|
|
if (bitmap.isOpaque() != dst.isOpaque()) {
|
|
report_opaqueness(reporter, bitmap, dst);
|
|
}
|
|
|
|
if (ctable) {
|
|
ctable->setFlags(ctableFlags);
|
|
}
|
|
}
|
|
|
|
static void init_src(const SkBitmap& bitmap) {
|
|
SkAutoLockPixels lock(bitmap);
|
|
if (bitmap.getPixels()) {
|
|
memset(bitmap.getPixels(), 4, bitmap.getSize());
|
|
}
|
|
}
|
|
|
|
SkColorTable* init_ctable() {
|
|
static const SkColor colors[] = {
|
|
SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE
|
|
};
|
|
return new SkColorTable(colors, SK_ARRAY_COUNT(colors));
|
|
}
|
|
|
|
struct Pair {
|
|
SkBitmap::Config fConfig;
|
|
const char* fValid;
|
|
};
|
|
|
|
static void TestBitmapCopy(skiatest::Reporter* reporter) {
|
|
static const Pair gPairs[] = {
|
|
{ SkBitmap::kNo_Config, "00000000" },
|
|
{ SkBitmap::kA1_Config, "01000000" },
|
|
{ SkBitmap::kA8_Config, "00101110" },
|
|
{ SkBitmap::kIndex8_Config, "00111110" },
|
|
{ SkBitmap::kRGB_565_Config, "00101110" },
|
|
{ SkBitmap::kARGB_4444_Config, "00101110" },
|
|
{ SkBitmap::kARGB_8888_Config, "00101110" },
|
|
// TODO: create valid RLE bitmap to test with
|
|
// { SkBitmap::kRLE_Index8_Config, "00101111" }
|
|
};
|
|
|
|
const int W = 20;
|
|
const int H = 33;
|
|
|
|
for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
|
|
for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) {
|
|
SkBitmap src, dst;
|
|
SkColorTable* ct = NULL;
|
|
|
|
src.setConfig(gPairs[i].fConfig, W, H);
|
|
if (SkBitmap::kIndex8_Config == src.config() ||
|
|
SkBitmap::kRLE_Index8_Config == src.config()) {
|
|
ct = init_ctable();
|
|
}
|
|
src.allocPixels(ct);
|
|
ct->safeRef();
|
|
|
|
init_src(src);
|
|
bool success = src.copyTo(&dst, gPairs[j].fConfig);
|
|
bool expected = gPairs[i].fValid[j] != '0';
|
|
if (success != expected) {
|
|
SkString str;
|
|
str.printf("SkBitmap::copyTo from %s to %s. expected %s returned %s",
|
|
gConfigName[i], gConfigName[j], boolStr(expected),
|
|
boolStr(success));
|
|
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) {
|
|
REPORTER_ASSERT(reporter, src.width() == dst.width());
|
|
REPORTER_ASSERT(reporter, src.height() == dst.height());
|
|
REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig);
|
|
test_isOpaque(reporter, src, dst.config());
|
|
if (src.config() == dst.config()) {
|
|
SkAutoLockPixels srcLock(src);
|
|
SkAutoLockPixels dstLock(dst);
|
|
REPORTER_ASSERT(reporter, src.readyToDraw());
|
|
REPORTER_ASSERT(reporter, dst.readyToDraw());
|
|
const char* srcP = (const char*)src.getAddr(0, 0);
|
|
const char* dstP = (const char*)dst.getAddr(0, 0);
|
|
REPORTER_ASSERT(reporter, srcP != dstP);
|
|
REPORTER_ASSERT(reporter, !memcmp(srcP, dstP,
|
|
src.getSize()));
|
|
}
|
|
// test extractSubset
|
|
{
|
|
SkBitmap subset;
|
|
SkIRect r;
|
|
r.set(1, 1, 2, 2);
|
|
if (src.extractSubset(&subset, r)) {
|
|
REPORTER_ASSERT(reporter, subset.width() == 1);
|
|
REPORTER_ASSERT(reporter, subset.height() == 1);
|
|
|
|
SkBitmap copy;
|
|
REPORTER_ASSERT(reporter,
|
|
subset.copyTo(©, subset.config()));
|
|
REPORTER_ASSERT(reporter, copy.width() == 1);
|
|
REPORTER_ASSERT(reporter, copy.height() == 1);
|
|
REPORTER_ASSERT(reporter, copy.rowBytes() <= 4);
|
|
|
|
SkAutoLockPixels alp0(subset);
|
|
SkAutoLockPixels alp1(copy);
|
|
// they should both have, or both not-have, a colortable
|
|
bool hasCT = subset.getColorTable() != NULL;
|
|
REPORTER_ASSERT(reporter,
|
|
(copy.getColorTable() != NULL) == hasCT);
|
|
}
|
|
}
|
|
} else {
|
|
// dst should be unchanged from its initial state
|
|
REPORTER_ASSERT(reporter, dst.config() == SkBitmap::kNo_Config);
|
|
REPORTER_ASSERT(reporter, dst.width() == 0);
|
|
REPORTER_ASSERT(reporter, dst.height() == 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#include "TestClassDef.h"
|
|
DEFINE_TESTCLASS("BitmapCopy", TestBitmapCopyClass, TestBitmapCopy)
|