sRGB support in Ganesh. Several pieces:
sRGB support now also requires GL_EXT_texture_sRGB_decode, which allows
us to disable sRGB -> Linear conversion when reading textures. This gives
us an easy way to support "legacy" L32 mode. We disable decoding based on
the pixel config of the render target. Textures can override that behavior
(specifically for format-conversion draws where we want that behavior).
Added sBGRA pixel config, which is not-really-a-format. It's just sRGBA
internally, and the external format is BGR order, so TexImage calls will
swizzle correctly. This lets us interact with sRGB raster surfaces on BGR
platforms.
Devices without sRGB support behave like they always have: conversion from
color type and profile type ignores sRGB and always returns linear pixel
configs.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1789663002
Review URL: https://codereview.chromium.org/1789663002
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 9ab8843..61ab4b4 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -43,12 +43,12 @@
# include "etc1.h"
#endif
-GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) {
+GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info, const GrCaps& caps) {
GrSurfaceDesc desc;
desc.fFlags = kNone_GrSurfaceFlags;
desc.fWidth = info.width();
desc.fHeight = info.height();
- desc.fConfig = SkImageInfo2GrPixelConfig(info);
+ desc.fConfig = SkImageInfo2GrPixelConfig(info, caps);
desc.fSampleCnt = 0;
return desc;
}
@@ -213,7 +213,7 @@
}
GrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bitmap) {
- GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info(), *ctx->caps());
if (GrTexture *texture = load_etc1_texture(ctx, bitmap, desc)) {
return texture;
}
@@ -238,10 +238,34 @@
SkPixmap tmpPixmap;
SkBitmap tmpBitmap;
- GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info());
const GrCaps* caps = ctx->caps();
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *caps);
- if (kIndex_8_SkColorType == pixmap.colorType()) {
+ if (caps->srgbSupport() && !GrPixelConfigIsSRGB(desc.fConfig) &&
+ kSRGB_SkColorProfileType == pixmap.info().profileType()) {
+ // We we supplied sRGB as the profile type, but we don't have a suitable pixel config.
+ // Convert to 8888 sRGB so we can handle the data correctly. The raster backend doesn't
+ // handle sRGB Index8 -> sRGB 8888 correctly (yet), so lie about both the source and
+ // destination (claim they're linear):
+ SkImageInfo linSrcInfo = SkImageInfo::Make(pixmap.width(), pixmap.height(),
+ pixmap.colorType(), pixmap.alphaType());
+ SkPixmap linSrcPixmap(linSrcInfo, pixmap.addr(), pixmap.rowBytes(), pixmap.ctable());
+
+ SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height(),
+ kSRGB_SkColorProfileType);
+ tmpBitmap.allocPixels(dstInfo);
+
+ SkImageInfo linDstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
+ if (!linSrcPixmap.readPixels(linDstInfo, tmpBitmap.getPixels(), tmpBitmap.rowBytes())) {
+ return nullptr;
+ }
+ if (!tmpBitmap.peekPixels(&tmpPixmap)) {
+ return nullptr;
+ }
+ pmap = &tmpPixmap;
+ // must rebuild desc, since we've forced the info to be N32
+ desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
+ } else if (kIndex_8_SkColorType == pixmap.colorType()) {
if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) {
size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
pixmap.width(), pixmap.height());
@@ -263,7 +287,7 @@
}
pmap = &tmpPixmap;
// must rebuild desc, since we've forced the info to be N32
- desc = GrImageInfoToSurfaceDesc(pmap->info());
+ desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
}
}
@@ -289,7 +313,7 @@
GrTexture* GrGenerateMipMapsAndUploadToTexture(GrContext* ctx, const SkBitmap& bitmap)
{
- GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info(), *ctx->caps());
if (kIndex_8_SkColorType != bitmap.colorType() && !bitmap.readyToDraw()) {
GrTexture* texture = load_etc1_texture(ctx, bitmap, desc);
if (texture) {
@@ -358,7 +382,10 @@
// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
// alpha info, that will be considered.
-GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt) {
+GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt,
+ const GrCaps& caps) {
+ // We intentionally ignore profile type for non-8888 formats. Anything we can't support
+ // in hardware will be expanded to sRGB 8888 in GrUploadPixmapToTexture.
switch (ct) {
case kUnknown_SkColorType:
return kUnknown_GrPixelConfig;
@@ -369,12 +396,11 @@
case kARGB_4444_SkColorType:
return kRGBA_4444_GrPixelConfig;
case kRGBA_8888_SkColorType:
- //if (kSRGB_SkColorProfileType == pt) {
- // return kSRGBA_8888_GrPixelConfig;
- //}
- return kRGBA_8888_GrPixelConfig;
+ return (kSRGB_SkColorProfileType == pt && caps.srgbSupport())
+ ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
case kBGRA_8888_SkColorType:
- return kBGRA_8888_GrPixelConfig;
+ return (kSRGB_SkColorProfileType == pt && caps.srgbSupport())
+ ? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
case kIndex_8_SkColorType:
return kIndex_8_GrPixelConfig;
case kGray_8_SkColorType:
@@ -413,6 +439,10 @@
ct = kRGBA_8888_SkColorType;
pt = kSRGB_SkColorProfileType;
break;
+ case kSBGRA_8888_GrPixelConfig:
+ ct = kBGRA_8888_SkColorType;
+ pt = kSRGB_SkColorProfileType;
+ break;
default:
return false;
}