aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrCaps.cpp18
-rw-r--r--src/gpu/SkGpuDevice.cpp9
-rw-r--r--src/gpu/SkGr.cpp58
-rw-r--r--src/gpu/SkGrPixelRef.cpp2
-rw-r--r--src/gpu/SkGrPriv.h2
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp5
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.cpp2
-rw-r--r--src/gpu/gl/GrGLCaps.cpp43
-rw-r--r--src/gpu/gl/GrGLCaps.h3
-rw-r--r--src/gpu/gl/GrGLDefines.h5
-rw-r--r--src/gpu/gl/GrGLGpu.cpp35
-rw-r--r--src/gpu/gl/GrGLGpu.h3
-rw-r--r--src/gpu/gl/GrGLTexture.h1
13 files changed, 141 insertions, 45 deletions
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index c544d6ef77..000f90c6a6 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -83,6 +83,7 @@ void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
GrCaps::GrCaps(const GrContextOptions& options) {
fMipMapSupport = false;
fNPOTTextureTileSupport = false;
+ fSRGBSupport = false;
fTwoSidedStencilSupport = false;
fStencilWrapOpsSupport = false;
fDiscardRenderTargetSupport = false;
@@ -157,6 +158,7 @@ SkString GrCaps::dump() const {
static const char* gNY[] = {"NO", "YES"};
r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]);
r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
+ r.appendf("sRGB Support : %s\n", gNY[fSRGBSupport]);
r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]);
@@ -210,6 +212,7 @@ SkString GrCaps::dump() const {
"RGBA8888", // kRGBA_8888_GrPixelConfig,
"BGRA8888", // kBGRA_8888_GrPixelConfig,
"SRGBA8888",// kSRGBA_8888_GrPixelConfig,
+ "SBGRA8888",// kSBGRA_8888_GrPixelConfig,
"ETC1", // kETC1_GrPixelConfig,
"LATC", // kLATC_GrPixelConfig,
"R11EAC", // kR11_EAC_GrPixelConfig,
@@ -226,13 +229,14 @@ SkString GrCaps::dump() const {
GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
GR_STATIC_ASSERT(7 == kSRGBA_8888_GrPixelConfig);
- GR_STATIC_ASSERT(8 == kETC1_GrPixelConfig);
- GR_STATIC_ASSERT(9 == kLATC_GrPixelConfig);
- GR_STATIC_ASSERT(10 == kR11_EAC_GrPixelConfig);
- GR_STATIC_ASSERT(11 == kASTC_12x12_GrPixelConfig);
- GR_STATIC_ASSERT(12 == kRGBA_float_GrPixelConfig);
- GR_STATIC_ASSERT(13 == kAlpha_half_GrPixelConfig);
- GR_STATIC_ASSERT(14 == kRGBA_half_GrPixelConfig);
+ GR_STATIC_ASSERT(8 == kSBGRA_8888_GrPixelConfig);
+ GR_STATIC_ASSERT(9 == kETC1_GrPixelConfig);
+ GR_STATIC_ASSERT(10 == kLATC_GrPixelConfig);
+ GR_STATIC_ASSERT(11 == kR11_EAC_GrPixelConfig);
+ GR_STATIC_ASSERT(12 == kASTC_12x12_GrPixelConfig);
+ GR_STATIC_ASSERT(13 == kRGBA_float_GrPixelConfig);
+ GR_STATIC_ASSERT(14 == kAlpha_half_GrPixelConfig);
+ GR_STATIC_ASSERT(15 == kRGBA_half_GrPixelConfig);
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, false));
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index c2d8bdad32..823e9b84ff 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -193,6 +193,7 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(
SkColorType ct = origInfo.colorType();
SkAlphaType at = origInfo.alphaType();
+ SkColorProfileType pt = origInfo.profileType();
if (kRGB_565_SkColorType == ct) {
at = kOpaque_SkAlphaType; // force this setting
} else if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType) {
@@ -202,13 +203,13 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(
if (kOpaque_SkAlphaType != at) {
at = kPremul_SkAlphaType; // force this setting
}
- const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at);
+ const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at, pt);
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = info.width();
desc.fHeight = info.height();
- desc.fConfig = SkImageInfo2GrPixelConfig(info);
+ desc.fConfig = SkImageInfo2GrPixelConfig(info, *context->caps());
desc.fSampleCnt = sampleCount;
desc.fTextureStorageAllocator = textureStorageAllocator;
desc.fIsMipMapped = false;
@@ -227,7 +228,7 @@ bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
ASSERT_SINGLE_OWNER
// TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
- GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo);
+ GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
if (kUnknown_GrPixelConfig == config) {
return false;
}
@@ -244,7 +245,7 @@ bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz
int x, int y) {
ASSERT_SINGLE_OWNER
// TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
- GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
+ GrPixelConfig config = SkImageInfo2GrPixelConfig(info, *fContext->caps());
if (kUnknown_GrPixelConfig == config) {
return false;
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 9ab8843386..61ab4b402a 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 @@ static GrTexture* load_etc1_texture(GrContext* ctx, const SkBitmap &bm, GrSurfac
}
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 @@ GrTexture* GrUploadPixmapToTexture(GrContext* ctx, const SkPixmap& pixmap, SkBud
SkPixmap tmpPixmap;
SkBitmap tmpBitmap;
- GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info());
const GrCaps* caps = ctx->caps();
-
- if (kIndex_8_SkColorType == pixmap.colorType()) {
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *caps);
+
+ 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 @@ GrTexture* GrUploadPixmapToTexture(GrContext* ctx, const SkPixmap& pixmap, SkBud
}
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 @@ void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pix
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 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
// 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 @@ GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf
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 @@ bool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
ct = kRGBA_8888_SkColorType;
pt = kSRGB_SkColorProfileType;
break;
+ case kSBGRA_8888_GrPixelConfig:
+ ct = kBGRA_8888_SkColorType;
+ pt = kSRGB_SkColorProfileType;
+ break;
default:
return false;
}
diff --git a/src/gpu/SkGrPixelRef.cpp b/src/gpu/SkGrPixelRef.cpp
index f61d92e186..e21d3b9d6d 100644
--- a/src/gpu/SkGrPixelRef.cpp
+++ b/src/gpu/SkGrPixelRef.cpp
@@ -75,7 +75,7 @@ static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorTyp
srcRect = *subset;
}
desc.fFlags = kRenderTarget_GrSurfaceFlag;
- desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT);
+ desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT, *context->caps());
desc.fTextureStorageAllocator = texture->desc().fTextureStorageAllocator;
desc.fIsMipMapped = false;
diff --git a/src/gpu/SkGrPriv.h b/src/gpu/SkGrPriv.h
index 75f4000ba4..f43a4e9595 100644
--- a/src/gpu/SkGrPriv.h
+++ b/src/gpu/SkGrPriv.h
@@ -95,7 +95,7 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
//////////////////////////////////////////////////////////////////////////////
-GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&);
+GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&, const GrCaps&);
bool GrPixelConfig2ColorAndProfileType(GrPixelConfig, SkColorType*, SkColorProfileType*);
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index dc41203406..bedcc78370 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -98,7 +98,7 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
const GrSwizzle& swizzle,
PMConversion pmConversion,
const SkMatrix& matrix)
- : INHERITED(texture, matrix)
+ : INHERITED(texture, matrix, GrTextureParams::ClampNoFilterForceAllowSRGB())
, fSwizzle(swizzle)
, fPMConversion(pmConversion) {
this->initClassID<GrConfigConversionEffect>();
@@ -296,7 +296,8 @@ const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture,
// If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect
// then we may pollute our texture cache with redundant shaders. So in the case that no
// conversions were requested we instead return a GrSimpleTextureEffect.
- return GrSimpleTextureEffect::Create(texture, matrix);
+ return GrSimpleTextureEffect::Create(texture, matrix,
+ GrTextureParams::ClampNoFilterForceAllowSRGB());
} else {
if (kRGBA_8888_GrPixelConfig != texture->config() &&
kBGRA_8888_GrPixelConfig != texture->config() &&
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index 1ac3dab2aa..1543a2e9db 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -158,7 +158,7 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) {
// that is not currently in use
fTexture->writePixels(0, rowNumber * fDesc.fRowHeight,
fDesc.fWidth, fDesc.fRowHeight,
- SkImageInfo2GrPixelConfig(data.info()),
+ SkImageInfo2GrPixelConfig(data.info(), *this->getContext()->caps()),
data.getPixels(),
data.rowBytes(),
GrContext::kDontFlush_PixelOpsFlag);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 40885359fb..af31480ba7 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -1435,27 +1435,31 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
}
fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
- // We only enable srgb support if both textures and FBOs support srgb.
- bool srgbSupport = false;
+ // We only enable srgb support if both textures and FBOs support srgb,
+ // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
if (kGL_GrGLStandard == standard) {
if (ctxInfo.version() >= GR_GL_VER(3,0)) {
- srgbSupport = true;
+ fSRGBSupport = true;
} else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
- srgbSupport = true;
+ fSRGBSupport = true;
}
}
// All the above srgb extensions support toggling srgb writes
- fSRGBWriteControl = srgbSupport;
+ fSRGBWriteControl = fSRGBSupport;
} else {
// See https://bug.skia.org/4148 for PowerVR issue.
- srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
+ fSRGBSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
(ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
// ES through 3.1 requires EXT_srgb_write_control to support toggling
// sRGB writing for destinations.
fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
}
+ if (!ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode")) {
+ // To support "legacy" L32 mode, we require the ability to turn off sRGB decode:
+ fSRGBSupport = false;
+ }
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
// GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
@@ -1464,7 +1468,7 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
GR_GL_RGBA;
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
- if (srgbSupport) {
+ if (fSRGBSupport) {
fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
allRenderFlags;
}
@@ -1473,6 +1477,26 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
}
fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
+ // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
+ // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
+ // is in this format, for example).
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
+ // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
+ // external format is GL_BGRA.
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+ GR_GL_BGRA;
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
+ if (fSRGBSupport) {
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
+ allRenderFlags;
+ }
+ if (texStorageSupported) {
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
+ }
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
+
fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
if (this->ES2CompatibilitySupport()) {
fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
@@ -1792,6 +1816,11 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
GR_GL_SRGB_ALPHA;
+
+ // Additionally, because we had to "invent" sBGRA, there is no way to make it work
+ // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
+ // unsupported. (If we have no sRGB support at all, this will get overwritten below).
+ fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
}
// If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 376610d8b0..ed673e7ce7 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -120,12 +120,10 @@ public:
const GrGLInterface* glInterface);
bool isConfigTexturable(GrPixelConfig config) const override {
- SkASSERT(kGrPixelConfigCnt > config);
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
}
bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
- SkASSERT(kGrPixelConfigCnt > config);
if (withMSAA) {
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag);
} else {
@@ -134,7 +132,6 @@ public:
}
bool isConfigTexSupportEnabled(GrPixelConfig config) const {
- SkASSERT(kGrPixelConfigCnt > config);
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseTexStorage_Flag);
}
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index cd73be401b..ff4c457250 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -506,12 +506,17 @@
/* TextureUsage */
#define GR_GL_FRAMEBUFFER_ATTACHMENT 0x93A3
+/* TextureSRGBDecode */
+#define GR_GL_DECODE_EXT 0x8A49
+#define GR_GL_SKIP_DECODE_EXT 0x8A4A
+
/* TextureParameterName */
#define GR_GL_TEXTURE_MAG_FILTER 0x2800
#define GR_GL_TEXTURE_MIN_FILTER 0x2801
#define GR_GL_TEXTURE_WRAP_S 0x2802
#define GR_GL_TEXTURE_WRAP_T 0x2803
#define GR_GL_TEXTURE_USAGE 0x93A2
+#define GR_GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
/* TextureTarget */
/* GL_TEXTURE_2D */
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 76cb1a068a..62baf79002 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -898,6 +898,7 @@ static inline GrGLint config_alignment(GrPixelConfig config) {
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
+ case kSBGRA_8888_GrPixelConfig:
case kRGBA_float_GrPixelConfig:
return 4;
default:
@@ -2100,13 +2101,15 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
SkSTArray<8, const GrTextureAccess*> textureAccesses;
program->setData(primProc, pipeline, &textureAccesses);
+ GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
+ bool allowSRGB = GrAllowSRGBForDestinationPixelConfig(glRT->config());
+
int numTextureAccesses = textureAccesses.count();
for (int i = 0; i < numTextureAccesses; i++) {
- this->bindTexture(i, textureAccesses[i]->getParams(),
+ this->bindTexture(i, textureAccesses[i]->getParams(), allowSRGB,
static_cast<GrGLTexture*>(textureAccesses[i]->getTexture()));
}
- GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
this->flushStencil(pipeline.getStencil());
this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStencil().isDisabled());
@@ -2607,6 +2610,16 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height,
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig;
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+ } else if (readConfig == kSBGRA_8888_GrPixelConfig &&
+ this->glCaps().isConfigRenderable(kSRGBA_8888_GrPixelConfig, false) &&
+ this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, kSRGBA_8888_GrPixelConfig)) {
+ // We're trying to read sBGRA but it's not supported. If sRGBA is renderable and
+ // we can read it back, then do a swizzling draw to a sRGBA and read it back (which
+ // will effectively be sBGRA).
+ tempDrawInfo->fTempSurfaceDesc.fConfig = kSRGBA_8888_GrPixelConfig;
+ tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
+ tempDrawInfo->fReadConfig = kSRGBA_8888_GrPixelConfig;
+ ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
} else if (readConfig == kAlpha_8_GrPixelConfig) {
// onReadPixels implements a fallback for cases where we are want to read kAlpha_8,
// it's unsupported, but 32bit RGBA reads are supported.
@@ -3311,7 +3324,8 @@ static void get_tex_param_swizzle(GrPixelConfig config,
}
}
-void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture) {
+void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, bool dstConfigAllowsSRGB,
+ GrGLTexture* texture) {
SkASSERT(texture);
#ifdef SK_DEBUG
@@ -3347,6 +3361,19 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
bool setAll = timestamp < this->getResetTimestamp();
GrGLTexture::TexParams newTexParams;
+ if (this->caps()->srgbSupport()) {
+ // By default, the decision to allow SRGB decode is based on the destination config.
+ // A texture can override that by specifying a value in GrTextureParams.
+ newTexParams.fSRGBDecode =
+ (dstConfigAllowsSRGB || GrTextureParams::kForceAllowSRGB_SRGBMode == params.srgbMode())
+ ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT;
+
+ if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) {
+ this->setTextureUnit(unitIdx);
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexParams.fSRGBDecode));
+ }
+ }
+
static GrGLenum glMinFilterModes[] = {
GR_GL_NEAREST,
GR_GL_LINEAR,
@@ -4014,7 +4041,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
- this->bindTexture(0, params, srcTex);
+ this->bindTexture(0, params, true, srcTex);
GrGLIRect dstVP;
this->bindSurfaceFBOForCopy(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index e365601e1f..a3582739e7 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -59,7 +59,8 @@ public:
void discard(GrRenderTarget*) override;
// Used by GrGLProgram to configure OpenGL state.
- void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
+ void bindTexture(int unitIdx, const GrTextureParams& params, bool dstConfigAllowsSRGB,
+ GrGLTexture* texture);
bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
GrPixelConfig readConfig, DrawPreference*,
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index 937b8be13e..6ee8dcfe2b 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -25,6 +25,7 @@ public:
GrGLenum fWrapT;
GrGLenum fMaxMipMapLevel;
GrGLenum fSwizzleRGBA[4];
+ GrGLenum fSRGBDecode;
void invalidate() { memset(this, 0xff, sizeof(TexParams)); }
};