diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/SkColorCubeFilter.cpp | 6 | ||||
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrSwizzle.h | 92 | ||||
-rw-r--r-- | src/gpu/GrTextureAccess.cpp | 71 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 92 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 19 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 53 | ||||
-rwxr-xr-x | src/gpu/glsl/GrGLSLCaps.cpp | 6 | ||||
-rwxr-xr-x | src/gpu/glsl/GrGLSLCaps.h | 17 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderBuilder.cpp | 80 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLTextureSampler.h | 4 |
12 files changed, 245 insertions, 207 deletions
diff --git a/src/effects/SkColorCubeFilter.cpp b/src/effects/SkColorCubeFilter.cpp index 5f1f10d53f..7f1f59622e 100644 --- a/src/effects/SkColorCubeFilter.cpp +++ b/src/effects/SkColorCubeFilter.cpp @@ -212,7 +212,7 @@ private: /////////////////////////////////////////////////////////////////////////////// GrColorCubeEffect::GrColorCubeEffect(GrTexture* colorCube) - : fColorCubeAccess(colorCube, GrTextureParams::kBilerp_FilterMode) { + : fColorCubeAccess(colorCube, "bgra", GrTextureParams::kBilerp_FilterMode) { this->initClassID<GrColorCubeEffect>(); this->addTextureAccess(&fColorCubeAccess); } @@ -287,11 +287,11 @@ void GrColorCubeEffect::GLSLProcessor::emitCode(EmitArgs& args) { // Apply the cube. fragBuilder->codeAppendf("%s = vec4(mix(", args.fOutputColor); fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords1); - fragBuilder->codeAppend(".bgr, "); + fragBuilder->codeAppend(".rgb, "); fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords2); // Premultiply color by alpha. Note that the input alpha is not modified by this shader. - fragBuilder->codeAppendf(".bgr, fract(%s.b)) * vec3(%s), %s.a);\n", + fragBuilder->codeAppendf(".rgb, fract(%s.b)) * vec3(%s), %s.a);\n", cubeIdx, nonZeroAlpha, args.fInputColor); } diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index 6996b6a7d4..32617cd6fe 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -487,7 +487,7 @@ const GrFragmentProcessor* ColorTableEffect::Create(GrContext* context, SkBitmap ColorTableEffect::ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, unsigned flags) - : fTextureAccess(texture) + : fTextureAccess(texture, "a") , fFlags(flags) , fAtlas(atlas) , fRow(row) { diff --git a/src/gpu/GrSwizzle.h b/src/gpu/GrSwizzle.h deleted file mode 100644 index 87ea9534b9..0000000000 --- a/src/gpu/GrSwizzle.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrSwizzle_DEFINED -#define GrSwizzle_DEFINED - -#include "GrTypes.h" - -/** Represents a rgba swizzle. It can be converted either into a string or a eight bit int. - Currently there is no way to specify an arbitrary swizzle, just some static swizzles and an - assignment operator. That could be relaxed. */ -class GrSwizzle { -public: - GrSwizzle() { *this = RGBA(); } - - GrSwizzle& operator=(const GrSwizzle& that) { - memcpy(this, &that, sizeof(GrSwizzle)); - return *this; - } - - bool operator==(const GrSwizzle& that) const { return this->asUInt() == that.asUInt(); } - - bool operator!=(const GrSwizzle& that) const { return !(*this == that); } - - /** Compact representation of the swizzle suitable for a key. */ - uint8_t asKey() const { return fKey; } - - /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */ - const char* c_str() const { return fSwiz; } - - static const GrSwizzle& RGBA() { - static GrSwizzle gRGBA("rgba"); - return gRGBA; - } - - static const GrSwizzle& AAAA() { - static GrSwizzle gAAAA("aaaa"); - return gAAAA; - } - - static const GrSwizzle& RRRR() { - static GrSwizzle gRRRR("rrrr"); - return gRRRR; - } - - static const GrSwizzle& BGRA() { - static GrSwizzle gBGRA("bgra"); - return gBGRA; - } - -private: - char fSwiz[5]; - uint8_t fKey; - - static int CharToIdx(char c) { - switch (c) { - case 'r': - return 0; - case 'g': - return 1; - case 'b': - return 2; - case 'a': - return 3; - default: - SkFAIL("Invalid swizzle char"); - return 0; - } - } - - explicit GrSwizzle(const char* str) { - SkASSERT(strlen(str) == 4); - fSwiz[0] = str[0]; - fSwiz[1] = str[1]; - fSwiz[2] = str[2]; - fSwiz[3] = str[3]; - fSwiz[4] = 0; - fKey = SkToU8(CharToIdx(fSwiz[0]) | (CharToIdx(fSwiz[1]) << 2) | - (CharToIdx(fSwiz[2]) << 4) | (CharToIdx(fSwiz[3]) << 6)); - } - - uint32_t* asUIntPtr() { return SkTCast<uint32_t*>(fSwiz); } - uint32_t asUInt() const { return *SkTCast<const uint32_t*>(fSwiz); } - - GR_STATIC_ASSERT(sizeof(char[4]) == sizeof(uint32_t)); -}; - -#endif diff --git a/src/gpu/GrTextureAccess.cpp b/src/gpu/GrTextureAccess.cpp index 277c0e3833..7e1eda6211 100644 --- a/src/gpu/GrTextureAccess.cpp +++ b/src/gpu/GrTextureAccess.cpp @@ -9,7 +9,12 @@ #include "GrColor.h" #include "GrTexture.h" -GrTextureAccess::GrTextureAccess() {} +GrTextureAccess::GrTextureAccess() { +#ifdef SK_DEBUG + memcpy(fSwizzle, "void", 5); + fSwizzleMask = 0xbeeffeed; +#endif +} GrTextureAccess::GrTextureAccess(GrTexture* texture, const GrTextureParams& params) { this->reset(texture, params); @@ -21,12 +26,49 @@ GrTextureAccess::GrTextureAccess(GrTexture* texture, this->reset(texture, filterMode, tileXAndY); } +GrTextureAccess::GrTextureAccess(GrTexture* texture, + const char* swizzle, + const GrTextureParams& params) { + this->reset(texture, swizzle, params); +} + +GrTextureAccess::GrTextureAccess(GrTexture* texture, + const char* swizzle, + GrTextureParams::FilterMode filterMode, + SkShader::TileMode tileXAndY) { + this->reset(texture, swizzle, filterMode, tileXAndY); +} + +void GrTextureAccess::reset(GrTexture* texture, + const char* swizzle, + const GrTextureParams& params) { + SkASSERT(texture); + SkASSERT(strlen(swizzle) >= 1 && strlen(swizzle) <= 4); + + fParams = params; + fTexture.set(SkRef(texture), kRead_GrIOType); + this->setSwizzle(swizzle); +} + +void GrTextureAccess::reset(GrTexture* texture, + const char* swizzle, + GrTextureParams::FilterMode filterMode, + SkShader::TileMode tileXAndY) { + SkASSERT(texture); + SkASSERT(strlen(swizzle) >= 1 && strlen(swizzle) <= 4); + + fParams.reset(tileXAndY, filterMode); + fTexture.set(SkRef(texture), kRead_GrIOType); + this->setSwizzle(swizzle); +} void GrTextureAccess::reset(GrTexture* texture, const GrTextureParams& params) { SkASSERT(texture); fTexture.set(SkRef(texture), kRead_GrIOType); fParams = params; + memcpy(fSwizzle, "rgba", 5); + fSwizzleMask = kRGBA_GrColorComponentFlags; } void GrTextureAccess::reset(GrTexture* texture, @@ -35,4 +77,31 @@ void GrTextureAccess::reset(GrTexture* texture, SkASSERT(texture); fTexture.set(SkRef(texture), kRead_GrIOType); fParams.reset(tileXAndY, filterMode); + memcpy(fSwizzle, "rgba", 5); + fSwizzleMask = kRGBA_GrColorComponentFlags; +} + +void GrTextureAccess::setSwizzle(const char* swizzle) { + fSwizzleMask = 0; + memset(fSwizzle, '\0', 5); + for (int i = 0; i < 4 && '\0' != swizzle[i]; ++i) { + fSwizzle[i] = swizzle[i]; + switch (swizzle[i]) { + case 'r': + fSwizzleMask |= kR_GrColorComponentFlag; + break; + case 'g': + fSwizzleMask |= kG_GrColorComponentFlag; + break; + case 'b': + fSwizzleMask |= kB_GrColorComponentFlag; + break; + case 'a': + fSwizzleMask |= kA_GrColorComponentFlag; + break; + default: + SkFAIL("Unexpected swizzle string character."); + break; + } + } } diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 99ed042139..923c392d31 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -42,7 +42,6 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions, fIsCoreProfile = false; fBindFragDataLocationSupport = false; fExternalTextureSupport = false; - fTextureSwizzleSupport = false; fSRGBWriteControl = false; fRGBA8888PixelsOpsAreSlow = false; fPartialFBOReadIsSlow = false; @@ -219,16 +218,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } } - if (kGL_GrGLStandard == standard) { - if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) { - fTextureSwizzleSupport = true; - } - } else { - if (version >= GR_GL_VER(3,0)) { - fTextureSwizzleSupport = true; - } - } - #ifdef SK_BUILD_FOR_WIN // We're assuming that on Windows Chromium we're using ANGLE. bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() || @@ -448,14 +437,11 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } this->initShaderPrecisionTable(ctxInfo, gli, glslCaps); - - if (contextOptions.fUseShaderSwizzling) { - fTextureSwizzleSupport = false; - } - - // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have - // already been detected. - this->initConfigTable(ctxInfo, gli, glslCaps); + // Requires fTexutreSwizzleSupport and fTextureRedSupport to be set before this point. + this->initConfigSwizzleTable(ctxInfo, glslCaps); + // Requires various members are already correctly initialized (e.g. fTextureRedSupport, + // msaa support). + this->initConfigTable(ctxInfo, gli); this->applyOptionsOverrides(contextOptions); glslCaps->applyOptionsOverrides(contextOptions); @@ -880,8 +866,6 @@ SkString GrGLCaps::dump() const { r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO")); r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO")); r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO")); - r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO")); - r.appendf("Texture swizzle support: %s\n", (fTextureSwizzleSupport ? "YES" : "NO")); r.append("Configs\n-------\n"); for (int i = 0; i < kGrPixelConfigCnt; ++i) { @@ -984,12 +968,49 @@ void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo, } } +void GrGLCaps::initConfigSwizzleTable(const GrGLContextInfo& ctxInfo, GrGLSLCaps* glslCaps) { + GrGLStandard standard = ctxInfo.standard(); + GrGLVersion version = ctxInfo.version(); + + glslCaps->fMustSwizzleInShader = true; + if (kGL_GrGLStandard == standard) { + if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) { + glslCaps->fMustSwizzleInShader = false; + } + } else { + if (version >= GR_GL_VER(3,0)) { + glslCaps->fMustSwizzleInShader = false; + } + } + + glslCaps->fConfigSwizzle[kUnknown_GrPixelConfig] = nullptr; + if (fTextureRedSupport) { + glslCaps->fConfigSwizzle[kAlpha_8_GrPixelConfig] = "rrrr"; + glslCaps->fConfigSwizzle[kAlpha_half_GrPixelConfig] = "rrrr"; + } else { + glslCaps->fConfigSwizzle[kAlpha_8_GrPixelConfig] = "aaaa"; + glslCaps->fConfigSwizzle[kAlpha_half_GrPixelConfig] = "aaaa"; + } + glslCaps->fConfigSwizzle[kIndex_8_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kRGB_565_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kRGBA_4444_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kRGBA_8888_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kBGRA_8888_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kSRGBA_8888_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kETC1_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kLATC_GrPixelConfig] = "rrrr"; + glslCaps->fConfigSwizzle[kR11_EAC_GrPixelConfig] = "rrrr"; + glslCaps->fConfigSwizzle[kASTC_12x12_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kRGBA_float_GrPixelConfig] = "rgba"; + glslCaps->fConfigSwizzle[kRGBA_half_GrPixelConfig] = "rgba"; + +} + bool GrGLCaps::bgraIsInternalFormat() const { return fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat == GR_GL_BGRA; } -void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, - GrGLSLCaps* glslCaps) { +void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { /* Comments on renderability of configs on various GL versions. OpenGL < 3.0: @@ -1072,7 +1093,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat = 0; fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalType = 0; fConfigTable[kUnknown_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType; - fConfigTable[kUnknown_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA; fConfigTable[kRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA8; @@ -1089,7 +1109,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= allRenderFlags; } } - fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat= GR_GL_BGRA; fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE; @@ -1125,7 +1144,6 @@ 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; @@ -1159,7 +1177,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag | allRenderFlags; } - fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB; if (this->ES2CompatibilitySupport()) { @@ -1178,7 +1195,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa } else { fConfigTable[kRGB_565_GrPixelConfig].fFlags |= allRenderFlags; } - fConfigTable[kRGB_565_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGBA; fConfigTable[kRGBA_4444_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGBA4; @@ -1193,18 +1209,15 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa } else { fConfigTable[kRGBA_4444_GrPixelConfig].fFlags |= allRenderFlags; } - fConfigTable[kRGBA_4444_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); if (this->textureRedSupport()) { fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED; fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8; fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RED; - fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR(); } else { fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA; fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8; fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat = GR_GL_ALPHA; - fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::AAAA(); } fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE; fConfigTable[kAlpha_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType; @@ -1260,18 +1273,15 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= fpRenderFlags; } } - fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); if (this->textureRedSupport()) { fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED; fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R16F; fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat = GR_GL_RED; - fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR(); } else { fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA; fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F; fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat = GR_GL_ALPHA; - fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::AAAA(); } if (kGL_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(3, 0)) { fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalType = GR_GL_HALF_FLOAT; @@ -1307,7 +1317,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags; } } - fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); // Compressed texture support @@ -1341,7 +1350,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa } } } - fConfigTable[kIndex_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); // May change the internal format based on extensions. fConfigTable[kLATC_GrPixelConfig].fFormats.fBaseInternalFormat = @@ -1370,7 +1378,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalFormat = 0; fConfigTable[kLATC_GrPixelConfig].fFormats.fExternalType = 0; fConfigTable[kLATC_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType; - fConfigTable[kLATC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR(); fConfigTable[kETC1_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8; fConfigTable[kETC1_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8; @@ -1390,7 +1397,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kETC1_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag; } } - fConfigTable[kETC1_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_R11_EAC; fConfigTable[kR11_EAC_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_COMPRESSED_R11_EAC; @@ -1402,7 +1408,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) { fConfigTable[kR11_EAC_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag; } - fConfigTable[kR11_EAC_GrPixelConfig].fSwizzle = GrSwizzle::RRRR(); fConfigTable[kASTC_12x12_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_COMPRESSED_RGBA_ASTC_12x12; @@ -1416,7 +1421,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa ctxInfo.hasExtension("GL_OES_texture_compression_astc")) { fConfigTable[kASTC_12x12_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag; } - fConfigTable[kASTC_12x12_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); // Bulk populate the texture internal/external formats here and then deal with exceptions below. @@ -1454,14 +1458,6 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fInternalFormatTexImage = GR_GL_BGRA; } - // If we don't have texture swizzle support then the shader generator must insert the - // swizzle into shader code. - if (!this->textureSwizzleSupport()) { - for (int i = 0; i < kGrPixelConfigCnt; ++i) { - glslCaps->fConfigTextureSwizzle[i] = fConfigTable[i].fSwizzle; - } - } - #ifdef SK_DEBUG // Make sure we initialized everything. ConfigFormats defaultEntry; diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index db60ad273a..a650348a13 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -9,10 +9,9 @@ #ifndef GrGLCaps_DEFINED #define GrGLCaps_DEFINED -#include "glsl/GrGLSL.h" #include "GrCaps.h" +#include "glsl/GrGLSL.h" #include "GrGLStencilAttachment.h" -#include "GrSwizzle.h" #include "SkChecksum.h" #include "SkTHash.h" #include "SkTArray.h" @@ -143,11 +142,6 @@ public: return fConfigTable[config].fFormats; } - /** Returns the mapping between GrPixelConfig components and GL internal format components. */ - const GrSwizzle& configSwizzle(GrPixelConfig config) const { - return fConfigTable[config].fSwizzle; - } - /** * Gets an array of legal stencil formats. These formats are not guaranteed * to be supported by the driver but are legal GLenum names given the GL @@ -313,9 +307,6 @@ public: /// Are textures with GL_TEXTURE_EXTERNAL_OES type supported. bool externalTextureSupport() const { return fExternalTextureSupport; } - /// GL_ARB_texture_swizzle - bool textureSwizzleSupport() const { return fTextureSwizzleSupport; } - /** * Is there support for enabling/disabling sRGB writes for sRGB-capable color attachments? * If false this does not mean sRGB is not supported but rather that if it is supported @@ -344,12 +335,15 @@ private: void initBlendEqationSupport(const GrGLContextInfo&); void initStencilFormats(const GrGLContextInfo&); // This must be called after initFSAASupport(). - void initConfigTable(const GrGLContextInfo&, const GrGLInterface* gli, GrGLSLCaps* glslCaps); + void initConfigTable(const GrGLContextInfo&, const GrGLInterface* gli); void initShaderPrecisionTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* intf, GrGLSLCaps* glslCaps); + void initConfigSwizzleTable(const GrGLContextInfo& ctxInfo, GrGLSLCaps* glslCaps); + + SkTArray<StencilFormat, true> fStencilFormats; int fMaxFragmentUniformVectors; @@ -382,7 +376,6 @@ private: bool fPartialFBOReadIsSlow : 1; bool fBindUniformLocationSupport : 1; bool fExternalTextureSupport : 1; - bool fTextureSwizzleSupport : 1; /** Number type of the components (with out considering number of bits.) */ enum FormatType { @@ -425,8 +418,6 @@ private: kRenderableWithMSAA_Flag = 0x8, }; uint32_t fFlags; - - GrSwizzle fSwizzle; }; ConfigInfo fConfigTable[kGrPixelConfigCnt]; diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index e0b7d4aca5..49b8f3acb8 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -2485,11 +2485,11 @@ static GrGLenum get_component_enum_from_char(char component) { /** If texture swizzling is available using tex parameters then it is preferred over mangling the generated shader code. This potentially allows greater reuse of cached shaders. */ static void get_tex_param_swizzle(GrPixelConfig config, - const GrGLCaps& caps, + const GrGLSLCaps& caps, GrGLenum* glSwizzle) { - const GrSwizzle& swizzle = caps.configSwizzle(config); + const char* swizzle = caps.getSwizzleMap(config); for (int i = 0; i < 4; ++i) { - glSwizzle[i] = get_component_enum_from_char(swizzle.c_str()[i]); + glSwizzle[i] = get_component_enum_from_char(swizzle[i]); } } @@ -2558,7 +2558,7 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); - get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizzleRGBA); + get_tex_param_swizzle(texture->config(), *this->glCaps().glslCaps(), newTexParams.fSwizzleRGBA); if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { this->setTextureUnit(unitIdx); GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMagFilter)); @@ -2575,7 +2575,7 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur this->setTextureUnit(unitIdx); GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT)); } - if (this->glCaps().textureSwizzleSupport() && + if (!this->glCaps().glslCaps()->mustSwizzleInShader() && (setAll || memcmp(newTexParams.fSwizzleRGBA, oldTexParams.fSwizzleRGBA, sizeof(newTexParams.fSwizzleRGBA)))) { diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index 032562550c..81f92eb243 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -13,23 +13,36 @@ #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" +/** + * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are + * present in the texture's config. swizzleComponentMask indicates the channels present in the + * shader swizzle. + */ +static bool swizzle_requires_alpha_remapping(const GrGLSLCaps& caps, GrPixelConfig config) { + if (!caps.mustSwizzleInShader()) { + // Any remapping is handled using texture swizzling not shader modifications. + return false; + } + const char* swizzleMap = caps.getSwizzleMap(config); + + return SkToBool(memcmp(swizzleMap, "rgba", 4)); +} -static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc, - const GrGLSLCaps& caps) { +static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) { + uint32_t key = 0; int numTextures = proc.numTextures(); - // Need two bytes per key (swizzle and target). - int word32Count = (proc.numTextures() + 1) / 2; - if (0 == word32Count) { - return; - } - uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count)); - for (int i = 0; i < numTextures; ++i) { - const GrTextureAccess& access = proc.textureAccess(i); - bool isExternal = (GR_GL_TEXTURE_EXTERNAL == - static_cast<GrGLTexture*>(access.getTexture())->target()); - k16[i] = caps.configTextureSwizzle(access.getTexture()->config()).asKey() | - (isExternal ? 0xFF00 : 0x0000); + int shift = 0; + for (int t = 0; t < numTextures; ++t) { + const GrTextureAccess& access = proc.textureAccess(t); + if (swizzle_requires_alpha_remapping(*caps.glslCaps(), access.getTexture()->config())) { + key |= 1 << shift; + } + if (GR_GL_TEXTURE_EXTERNAL == static_cast<GrGLTexture*>(access.getTexture())->target()) { + key |= 2 << shift; + } + shift += 2; } + return key; } /** @@ -38,14 +51,15 @@ static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc, * in its key (e.g. the pixel format of textures used). So we create a meta-key for * every effect using this function. It is also responsible for inserting the effect's class ID * which must be different for every GrProcessor subclass. It can fail if an effect uses too many - * transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and GPs share this - * function because it is hairy, though FPs do not have attribs, and GPs do not have transforms + * textures, transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and GPs share + * this function because it is hairy, though FPs do not have attribs, and GPs do not have transforms */ static bool gen_meta_key(const GrProcessor& proc, const GrGLCaps& caps, uint32_t transformKey, GrProcessorKeyBuilder* b) { size_t processorKeySize = b->size(); + uint32_t textureKey = gen_texture_key(proc, caps); uint32_t classID = proc.classID(); // Currently we allow 16 bits for the class id and the overall processor key size. @@ -54,11 +68,10 @@ static bool gen_meta_key(const GrProcessor& proc, return false; } - add_texture_key(b, proc, *caps.glslCaps()); - - uint32_t* key = b->add32n(2); + uint32_t* key = b->add32n(3); key[0] = (classID << 16) | SkToU32(processorKeySize); - key[1] = transformKey; + key[1] = textureKey; + key[2] = transformKey; return true; } diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp index c82d8333df..cf41f8e765 100755 --- a/src/gpu/glsl/GrGLSLCaps.cpp +++ b/src/gpu/glsl/GrGLSLCaps.cpp @@ -31,6 +31,9 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) { fFBFetchColorName = nullptr; fFBFetchExtensionString = nullptr; fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction; + + fMustSwizzleInShader = false; + memset(fConfigSwizzle, 0, sizeof(fConfigSwizzle)); } SkString GrGLSLCaps::dump() const { @@ -64,5 +67,8 @@ SkString GrGLSLCaps::dump() const { } void GrGLSLCaps::onApplyOptionsOverrides(const GrContextOptions& options) { + if (options.fUseShaderSwizzling) { + fMustSwizzleInShader = true; + } } diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h index eba9602e5a..21c59e7b16 100755 --- a/src/gpu/glsl/GrGLSLCaps.h +++ b/src/gpu/glsl/GrGLSLCaps.h @@ -11,7 +11,6 @@ #include "GrCaps.h" #include "GrGLSL.h" -#include "GrSwizzle.h" class GrGLSLCaps : public GrShaderCaps { public: @@ -105,14 +104,14 @@ public: return fExternalTextureExtensionString; } + bool mustSwizzleInShader() const { return fMustSwizzleInShader; } + /** - * Given a texture's config, this determines what swizzle must be appended to accesses to the - * texture in generated shader code. Swizzling may be implemented in texture parameters or a - * sampler rather than in the shader. In this case the shader swizzle will always be "rgba". + * Returns a string which represents how to map from an internal GLFormat to a given + * GrPixelConfig. The function mustSwizzleInShader determines whether this swizzle is applied + * in the generated shader code or using sample state in the 3D API. */ - const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const { - return fConfigTextureSwizzle[config]; - } + const char* getSwizzleMap(GrPixelConfig config) const { return fConfigSwizzle[config]; } GrGLSLGeneration generation() const { return fGLSLGeneration; } @@ -149,11 +148,13 @@ private: AdvBlendEqInteraction fAdvBlendEqInteraction; - GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt]; + bool fMustSwizzleInShader; + const char* fConfigSwizzle[kGrPixelConfigCnt]; friend class GrGLCaps; // For initialization. typedef GrShaderCaps INHERITED; }; + #endif diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp index 2d2ff8768e..5716c0bd12 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp @@ -5,13 +5,70 @@ * found in the LICENSE file. */ -#include "GrSwizzle.h" #include "glsl/GrGLSLShaderBuilder.h" #include "glsl/GrGLSLCaps.h" #include "glsl/GrGLSLShaderVar.h" #include "glsl/GrGLSLTextureSampler.h" #include "glsl/GrGLSLProgramBuilder.h" +static void map_swizzle(const char* swizzleMap, const char* swizzle, char* mangledSwizzle) { + int i; + for (i = 0; '\0' != swizzle[i]; ++i) { + switch (swizzle[i]) { + case 'r': + mangledSwizzle[i] = swizzleMap[0]; + break; + case 'g': + mangledSwizzle[i] = swizzleMap[1]; + break; + case 'b': + mangledSwizzle[i] = swizzleMap[2]; + break; + case 'a': + mangledSwizzle[i] = swizzleMap[3]; + break; + default: + SkFAIL("Unsupported swizzle"); + } + } + mangledSwizzle[i] ='\0'; +} + +static void append_texture_lookup(SkString* out, + const GrGLSLCaps* glslCaps, + const char* samplerName, + const char* coordName, + GrPixelConfig config, + const char* swizzle, + GrSLType varyingType = kVec2f_GrSLType) { + SkASSERT(coordName); + + out->appendf("%s(%s, %s)", + GrGLSLTexture2DFunctionName(varyingType, glslCaps->generation()), + samplerName, + coordName); + + char mangledSwizzle[5]; + + // This refers to any swizzling we may need to get from some backend internal format to the + // format used in GrPixelConfig. Some backends will automatically do the sizzling for us. + if (glslCaps->mustSwizzleInShader()) { + const char* swizzleMap = glslCaps->getSwizzleMap(config); + // if the map is simply 'rgba' then we don't need to do any manual swizzling to get us to + // a GrPixelConfig format. + if (memcmp(swizzleMap, "rgba", 4)) { + // Manually 'swizzle' the swizzle using our mapping + map_swizzle(swizzleMap, swizzle, mangledSwizzle); + swizzle = mangledSwizzle; + } + } + + // For shader prettiness we omit the swizzle rather than appending ".rgba". + if (memcmp(swizzle, "rgba", 4)) { + out->appendf(".%s", swizzle); + } +} + GrGLSLShaderBuilder::GrGLSLShaderBuilder(GrGLSLProgramBuilder* program) : fProgramBuilder(program) , fInputs(GrGLSLProgramBuilder::kVarsPerBlock) @@ -60,21 +117,14 @@ void GrGLSLShaderBuilder::appendTextureLookup(SkString* out, const GrGLSLTextureSampler& sampler, const char* coordName, GrSLType varyingType) const { - const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps(); GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler(); - out->appendf("%s(%s, %s)", - GrGLSLTexture2DFunctionName(varyingType, glslCaps->generation()), - uniformHandler->getUniformCStr(sampler.fSamplerUniform), - coordName); - - // This refers to any swizzling we may need to get from some backend internal format to the - // format used in GrPixelConfig. If this is implemented by the GrGpu object, then swizzle will - // be rgba. For shader prettiness we omit the swizzle rather than appending ".rgba". - const GrSwizzle& configSwizzle = glslCaps->configTextureSwizzle(sampler.config()); - - if (configSwizzle != GrSwizzle::RGBA()) { - out->appendf(".%s", configSwizzle.c_str()); - } + append_texture_lookup(out, + fProgramBuilder->glslCaps(), + uniformHandler->getUniformCStr(sampler.fSamplerUniform), + coordName, + sampler.config(), + sampler.swizzle(), + varyingType); } void GrGLSLShaderBuilder::appendTextureLookup(const GrGLSLTextureSampler& sampler, diff --git a/src/gpu/glsl/GrGLSLTextureSampler.h b/src/gpu/glsl/GrGLSLTextureSampler.h index fd8bcb26e9..a4fbf550f2 100644 --- a/src/gpu/glsl/GrGLSLTextureSampler.h +++ b/src/gpu/glsl/GrGLSLTextureSampler.h @@ -21,13 +21,17 @@ public: : fSamplerUniform(uniform) , fConfig(access.getTexture()->config()) { SkASSERT(kUnknown_GrPixelConfig != fConfig); + memcpy(fSwizzle, access.getSwizzle(), 5); } GrPixelConfig config() const { return fConfig; } + // this is .abcd + const char* swizzle() const { return fSwizzle; } private: UniformHandle fSamplerUniform; GrPixelConfig fConfig; + char fSwizzle[5]; friend class GrGLSLShaderBuilder; }; |