Force Index8 to N32 in deferred texture path.

Ganesh doesn't support Index8, because GPUs don't really
support it. So serializing it in the deferred blob just
meant doing an expansion before upload. This forces that
to happen when we build the blob. It also paves the way
for removing the last usage of MakeTextureFromPixmap,
which I'd like to remove.

BUG=skia:

Change-Id: I7c0292098d71e2f8ec1f9910e1234761822ce957
Reviewed-on: https://skia-review.googlesource.com/7340
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2017-01-20 13:21:56 -05:00 committed by Skia Commit-Bot
parent 3329cceab5
commit aaedae7acb
2 changed files with 42 additions and 37 deletions

View File

@ -85,7 +85,7 @@ static void DrawDeferredTextureImageMipMapTree(SkCanvas* canvas, SkImage* image,
SkPaint paint;
paint.setFilterQuality(params->fQuality);
int mipLevelCount = SkMipMap::ComputeLevelCount(512, 512);
int mipLevelCount = SkMipMap::ComputeLevelCount(image->width(), image->height());
size_t requiredMemoryInBytes = image->getDeferredTextureImageData(
*proxy, params, 1, nullptr, canvas->imageInfo().colorSpace());
if (requiredMemoryInBytes == 0) {
@ -107,13 +107,14 @@ static void DrawDeferredTextureImageMipMapTree(SkCanvas* canvas, SkImage* image,
canvas->translate(10.f, offsetHeight);
canvas->drawImage(uploadedImage, 0, 0, &paint);
canvas->restore();
offsetHeight += 512 + 10;
offsetHeight += image->height() + 10;
// handle generated mipmap levels
for (int i = 0; i < mipLevelCount; i++) {
SkISize mipSize = SkMipMap::ComputeLevelSize(512, 512, i);
SkISize mipSize = SkMipMap::ComputeLevelSize(image->width(), image->height(), i);
canvas->save();
canvas->translate(10.f, offsetHeight);
canvas->scale(mipSize.width() / 512.f, mipSize.height() / 512.f);
canvas->scale(mipSize.width() / static_cast<float>(image->width()),
mipSize.height() / static_cast<float>(image->height()));
canvas->drawImage(uploadedImage, 0, 0, &paint);
canvas->restore();
offsetHeight += mipSize.height() + 10;
@ -123,16 +124,17 @@ static void DrawDeferredTextureImageMipMapTree(SkCanvas* canvas, SkImage* image,
offsetHeight = 10;
// handle base mipmap level
canvas->save();
canvas->translate(512.f + 20.f, offsetHeight);
canvas->translate(image->width() + 20.f, offsetHeight);
canvas->drawImage(image, 0, 0, &paint);
canvas->restore();
offsetHeight += 512 + 10;
offsetHeight += image->height() + 10;
// handle generated mipmap levels
for (int i = 0; i < mipLevelCount; i++) {
SkISize mipSize = SkMipMap::ComputeLevelSize(512, 512, i);
SkISize mipSize = SkMipMap::ComputeLevelSize(image->width(), image->height(), i);
canvas->save();
canvas->translate(512.f + 20.f, offsetHeight);
canvas->scale(mipSize.width() / 512.f, mipSize.height() / 512.f);
canvas->translate(image->width() + 20.f, offsetHeight);
canvas->scale(mipSize.width() / static_cast<float>(image->width()),
mipSize.height() / static_cast<float>(image->height()));
canvas->drawImage(image, 0, 0, &paint);
canvas->restore();
offsetHeight += mipSize.height() + 10;
@ -182,4 +184,29 @@ DEF_SIMPLE_GM(deferred_texture_image_high, canvas, 512 + 512 + 30, 512 + 20) {
DrawDeferredTextureImageData(canvas, &params);
}
DEF_SIMPLE_GM(deferred_texture_image_medium_encoded_indexed, canvas, 128 + 128 + 30, 340) {
sk_sp<SkImage> encodedImage = GetResourceAsImage("color_wheel.gif");
if (!encodedImage) {
SkDebugf("\nCould not load resource.\n");
return;
}
auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f),
kMedium_SkFilterQuality, 0);
DrawDeferredTextureImageMipMapTree(canvas, encodedImage.get(), &params);
}
DEF_SIMPLE_GM(deferred_texture_image_medium_decoded_indexed, canvas, 128 + 128 + 30, 340) {
SkBitmap bitmap;
if (!GetResourceAsBitmap("color_wheel.gif", &bitmap)) {
SkDebugf("\nCould not decode resource.\n");
return;
}
sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap);
auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f),
kMedium_SkFilterQuality, 0);
DrawDeferredTextureImageMipMapTree(canvas, decodedImage.get(), &params);
}
#endif

View File

@ -387,8 +387,6 @@ struct DeferredTextureImage {
SkAlphaType fAlphaType;
void* fColorSpace;
size_t fColorSpaceSize;
int fColorTableCnt;
uint32_t* fColorTableData;
int fMipMapLevelCount;
// The fMipMapLevelData array may contain more than 1 element.
// It contains fMipMapLevelCount elements.
@ -475,15 +473,9 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
SkAutoPixmapStorage pixmap;
SkImageInfo info;
size_t pixelSize = 0;
size_t ctSize = 0;
int ctCount = 0;
if (!isScaled && this->peekPixels(&pixmap)) {
if (!isScaled && this->peekPixels(&pixmap) && !pixmap.ctable()) {
info = pixmap.info();
pixelSize = SkAlign8(pixmap.getSafeSize());
if (pixmap.ctable()) {
ctCount = pixmap.ctable()->count();
ctSize = SkAlign8(pixmap.ctable()->count() * 4);
}
} else {
// Here we're just using presence of data to know whether there is a codec behind the image.
// In the future we will access the cacherator and get the exact data that we want to (e.g.
@ -498,10 +490,13 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
dstColorSpace, proxy.fCaps.get());
info = cacher->buildCacheInfo(cacheFormat).makeWH(scaledSize.width(),
scaledSize.height());
} else {
info = as_IB(this)->onImageInfo().makeWH(scaledSize.width(), scaledSize.height());
}
if (kIndex_8_SkColorType == info.colorType()) {
// Force Index8 to be N32 instead. Index8 is unsupported in Ganesh.
info = info.makeColorType(kN32_SkColorType);
}
pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr));
if (fillMode) {
pixmap.alloc(info);
@ -548,8 +543,6 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
// level in its size
size_t pixelOffset = size;
size += pixelSize;
size_t ctOffset = size;
size += ctSize;
size_t colorSpaceOffset = 0;
size_t colorSpaceSize = 0;
if (info.colorSpace()) {
@ -563,16 +556,9 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
char* bufferAsCharPtr = reinterpret_cast<char*>(buffer);
char* pixelsAsCharPtr = bufferAsCharPtr + pixelOffset;
void* pixels = pixelsAsCharPtr;
void* ct = nullptr;
if (ctSize) {
ct = bufferAsCharPtr + ctOffset;
}
memcpy(reinterpret_cast<void*>(SkAlign8(reinterpret_cast<uintptr_t>(pixelsAsCharPtr))),
pixmap.addr(), pixmap.getSafeSize());
if (ctSize) {
memcpy(ct, pixmap.ctable()->readColors(), ctSize);
}
// If the context has sRGB support, and we're intending to render to a surface with an attached
// color space, and the image has an sRGB-like color space attached, then use our gamma (sRGB)
@ -598,8 +584,6 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
FILL_MEMBER(dtiBufferFiller, fColorType, &colorType);
SkAlphaType alphaType = info.alphaType();
FILL_MEMBER(dtiBufferFiller, fAlphaType, &alphaType);
FILL_MEMBER(dtiBufferFiller, fColorTableCnt, &ctCount);
FILL_MEMBER(dtiBufferFiller, fColorTableData, &ct);
FILL_MEMBER(dtiBufferFiller, fMipMapLevelCount, &mipMapLevelCount);
memcpy(bufferAsCharPtr + offsetof(DeferredTextureImage, fMipMapLevelData[0].fPixelData),
&pixels, sizeof(pixels));
@ -671,11 +655,6 @@ sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con
if (!context || context->uniqueID() != dti->fContextUniqueID) {
return nullptr;
}
sk_sp<SkColorTable> colorTable;
if (dti->fColorTableCnt) {
SkASSERT(dti->fColorTableData);
colorTable.reset(new SkColorTable(dti->fColorTableData, dti->fColorTableCnt));
}
int mipLevelCount = dti->fMipMapLevelCount;
SkASSERT(mipLevelCount >= 1);
sk_sp<SkColorSpace> colorSpace;
@ -686,8 +665,7 @@ sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con
dti->fColorType, dti->fAlphaType, colorSpace);
if (mipLevelCount == 1) {
SkPixmap pixmap;
pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData,
dti->fMipMapLevelData[0].fRowBytes, colorTable.get());
pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, dti->fMipMapLevelData[0].fRowBytes);
return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
} else {
std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);