Add test for reading back from unpremul texture image
The unpremul->unpremul readback doesn't work today. GrSurfaceContext doesn't track an alpha type and whenever we read into an unpremul buffer we unpremul the texture's colors since we assume they were premuled. Bug: 7580 Change-Id: I307a168799f27b2015e082cf6adde26b906cfe2b Reviewed-on: https://skia-review.googlesource.com/103780 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
efb25fd809
commit
9708af826c
@ -149,6 +149,7 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes)
|
||||
for (int x = 0; x < info.width(); ++x) {
|
||||
row[x] = SkPreMultiplyColor(row[x]);
|
||||
}
|
||||
row = (SkColor*)((char*)(row) + rowBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,6 +510,76 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrContext_colorTypeSupportedAsImage, reporter
|
||||
}
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(UnpremulTextureImage, reporter, ctxInfo) {
|
||||
SkBitmap bmp;
|
||||
bmp.allocPixels(
|
||||
SkImageInfo::Make(256, 256, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType, nullptr));
|
||||
for (int y = 0; y < 256; ++y) {
|
||||
for (int x = 0; x < 256; ++x) {
|
||||
*bmp.getAddr32(x, y) =
|
||||
SkColorSetARGB((U8CPU)y, 255 - (U8CPU)y, (U8CPU)x, 255 - (U8CPU)x);
|
||||
}
|
||||
}
|
||||
auto texImage = SkImage::MakeFromBitmap(bmp)->makeTextureImage(ctxInfo.grContext(), nullptr);
|
||||
if (!texImage || texImage->alphaType() != kUnpremul_SkAlphaType) {
|
||||
ERRORF(reporter, "Failed to make unpremul texture image.");
|
||||
return;
|
||||
}
|
||||
// The GPU backend always unpremuls the values stored in the texture because it assumes they
|
||||
// are premul values. (skbug.com/7580).
|
||||
if (false) {
|
||||
SkBitmap unpremul;
|
||||
unpremul.allocPixels(SkImageInfo::Make(256, 256, kRGBA_8888_SkColorType,
|
||||
kUnpremul_SkAlphaType, nullptr));
|
||||
if (!texImage->readPixels(unpremul.info(), unpremul.getPixels(), unpremul.rowBytes(), 0,
|
||||
0)) {
|
||||
ERRORF(reporter, "Unpremul readback failed.");
|
||||
return;
|
||||
}
|
||||
for (int y = 0; y < 256; ++y) {
|
||||
for (int x = 0; x < 256; ++x) {
|
||||
if (*bmp.getAddr32(x, y) != *unpremul.getAddr32(x, y)) {
|
||||
ERRORF(reporter, "unpremul(0x%08x)->unpremul(0x%08x) at %d, %d.",
|
||||
*bmp.getAddr32(x, y), *unpremul.getAddr32(x, y), x, y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SkBitmap premul;
|
||||
premul.allocPixels(
|
||||
SkImageInfo::Make(256, 256, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr));
|
||||
if (!texImage->readPixels(premul.info(), premul.getPixels(), premul.rowBytes(), 0, 0)) {
|
||||
ERRORF(reporter, "Unpremul readback failed.");
|
||||
return;
|
||||
}
|
||||
for (int y = 0; y < 256; ++y) {
|
||||
for (int x = 0; x < 256; ++x) {
|
||||
// Treat bmp's color as a pm color even though it may be the r/b swap of a PM color.
|
||||
// SkPremultiplyColor acts the same on both channels.
|
||||
uint32_t origColor = SkPreMultiplyColor(*bmp.getAddr32(x, y));
|
||||
int32_t origA = (origColor >> 24) & 0xff;
|
||||
int32_t origB = (origColor >> 16) & 0xff;
|
||||
int32_t origG = (origColor >> 8) & 0xff;
|
||||
int32_t origR = (origColor >> 0) & 0xff;
|
||||
uint32_t read = *premul.getAddr32(x, y);
|
||||
int32_t readA = (read >> 24) & 0xff;
|
||||
int32_t readB = (read >> 16) & 0xff;
|
||||
int32_t readG = (read >> 8) & 0xff;
|
||||
int32_t readR = (read >> 0) & 0xff;
|
||||
// We expect that alpha=1 and alpha=0 should come out exact. Otherwise allow a little
|
||||
// bit of tolerance for GPU vs CPU premul math.
|
||||
int32_t tol = (origA == 0 || origA == 255) ? 0 : 1;
|
||||
if (origA != readA || SkTAbs(readB - origB) > tol || SkTAbs(readG - origG) > tol ||
|
||||
SkTAbs(readR - origR) > tol) {
|
||||
ERRORF(reporter, "unpremul(0x%08x)->premul(0x%08x) at %d, %d.",
|
||||
*bmp.getAddr32(x, y), *premul.getAddr32(x, y), x, y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
class EmptyGenerator : public SkImageGenerator {
|
||||
|
Loading…
Reference in New Issue
Block a user