diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrCaps.cpp | 18 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 9 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 58 | ||||
-rw-r--r-- | src/gpu/SkGrPixelRef.cpp | 2 | ||||
-rw-r--r-- | src/gpu/SkGrPriv.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrConfigConversionEffect.cpp | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 43 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLDefines.h | 5 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 35 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTexture.h | 1 |
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)); } }; |