diff options
author | bsalomon <bsalomon@google.com> | 2016-01-08 13:20:12 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-08 13:20:12 -0800 |
commit | cdee009886babe6df7743a9b5b3e2cc0a5f21adf (patch) | |
tree | 264d7ef0ad3fc31783bd2118c79b3adfe90bfae5 /src | |
parent | d9c0037211e1ae56c7b9628e69659e7f3df9081d (diff) |
Add a class representing texture swizzle.
Store config swizzle GrGLCaps and shader swizzles in GrGLSLCaps.
Remove GrTextureAccess's swizzle and update users of it to swizzle in their shader code.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1567733005
Committed: https://skia.googlesource.com/skia/+/1a1efeacf7cc94a8c2977114dfe230fed3efc105
Review URL: https://codereview.chromium.org/1567733005
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/SkColorCubeFilter.cpp | 6 | ||||
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 10 | ||||
-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, 211 insertions, 249 deletions
diff --git a/src/effects/SkColorCubeFilter.cpp b/src/effects/SkColorCubeFilter.cpp index 7f1f59622e..5f1f10d53f 100644 --- a/src/effects/SkColorCubeFilter.cpp +++ b/src/effects/SkColorCubeFilter.cpp @@ -212,7 +212,7 @@ private: /////////////////////////////////////////////////////////////////////////////// GrColorCubeEffect::GrColorCubeEffect(GrTexture* colorCube) - : fColorCubeAccess(colorCube, "bgra", GrTextureParams::kBilerp_FilterMode) { + : fColorCubeAccess(colorCube, 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(".rgb, "); + fragBuilder->codeAppend(".bgr, "); fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords2); // Premultiply color by alpha. Note that the input alpha is not modified by this shader. - fragBuilder->codeAppendf(".rgb, fract(%s.b)) * vec3(%s), %s.a);\n", + fragBuilder->codeAppendf(".bgr, 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 32617cd6fe..d9c07e254c 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -442,22 +442,22 @@ void GLColorTableEffect::emitCode(EmitArgs& args) { fragBuilder->codeAppendf("\t\t%s.a = ", args.fOutputColor); coord.printf("vec2(coord.a, %s.a)", yoffsets); fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str()); - fragBuilder->codeAppend(";\n"); + fragBuilder->codeAppend(".a;\n"); fragBuilder->codeAppendf("\t\t%s.r = ", args.fOutputColor); coord.printf("vec2(coord.r, %s.r)", yoffsets); fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str()); - fragBuilder->codeAppend(";\n"); + fragBuilder->codeAppend(".a;\n"); fragBuilder->codeAppendf("\t\t%s.g = ", args.fOutputColor); coord.printf("vec2(coord.g, %s.g)", yoffsets); fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str()); - fragBuilder->codeAppend(";\n"); + fragBuilder->codeAppend(".a;\n"); fragBuilder->codeAppendf("\t\t%s.b = ", args.fOutputColor); coord.printf("vec2(coord.b, %s.b)", yoffsets); fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str()); - fragBuilder->codeAppend(";\n"); + fragBuilder->codeAppend(".a;\n"); fragBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor); } @@ -487,7 +487,7 @@ const GrFragmentProcessor* ColorTableEffect::Create(GrContext* context, SkBitmap ColorTableEffect::ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, unsigned flags) - : fTextureAccess(texture, "a") + : fTextureAccess(texture) , fFlags(flags) , fAtlas(atlas) , fRow(row) { diff --git a/src/gpu/GrSwizzle.h b/src/gpu/GrSwizzle.h new file mode 100644 index 0000000000..87ea9534b9 --- /dev/null +++ b/src/gpu/GrSwizzle.h @@ -0,0 +1,92 @@ +/* + * 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 7e1eda6211..277c0e3833 100644 --- a/src/gpu/GrTextureAccess.cpp +++ b/src/gpu/GrTextureAccess.cpp @@ -9,12 +9,7 @@ #include "GrColor.h" #include "GrTexture.h" -GrTextureAccess::GrTextureAccess() { -#ifdef SK_DEBUG - memcpy(fSwizzle, "void", 5); - fSwizzleMask = 0xbeeffeed; -#endif -} +GrTextureAccess::GrTextureAccess() {} GrTextureAccess::GrTextureAccess(GrTexture* texture, const GrTextureParams& params) { this->reset(texture, params); @@ -26,49 +21,12 @@ 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, @@ -77,31 +35,4 @@ 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 923c392d31..99ed042139 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -42,6 +42,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions, fIsCoreProfile = false; fBindFragDataLocationSupport = false; fExternalTextureSupport = false; + fTextureSwizzleSupport = false; fSRGBWriteControl = false; fRGBA8888PixelsOpsAreSlow = false; fPartialFBOReadIsSlow = false; @@ -218,6 +219,16 @@ 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() || @@ -437,11 +448,14 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } this->initShaderPrecisionTable(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); + + if (contextOptions.fUseShaderSwizzling) { + fTextureSwizzleSupport = false; + } + + // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have + // already been detected. + this->initConfigTable(ctxInfo, gli, glslCaps); this->applyOptionsOverrides(contextOptions); glslCaps->applyOptionsOverrides(contextOptions); @@ -866,6 +880,8 @@ 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) { @@ -968,49 +984,12 @@ 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) { +void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, + GrGLSLCaps* glslCaps) { /* Comments on renderability of configs on various GL versions. OpenGL < 3.0: @@ -1093,6 +1072,7 @@ 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; @@ -1109,6 +1089,7 @@ 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; @@ -1144,6 +1125,7 @@ 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; @@ -1177,6 +1159,7 @@ 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()) { @@ -1195,6 +1178,7 @@ 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; @@ -1209,15 +1193,18 @@ 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; @@ -1273,15 +1260,18 @@ 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; @@ -1317,6 +1307,7 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= fpRenderFlags; } } + fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); // Compressed texture support @@ -1350,6 +1341,7 @@ 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 = @@ -1378,6 +1370,7 @@ 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; @@ -1397,6 +1390,7 @@ 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; @@ -1408,6 +1402,7 @@ 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; @@ -1421,6 +1416,7 @@ 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. @@ -1458,6 +1454,14 @@ 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 a650348a13..db60ad273a 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -9,9 +9,10 @@ #ifndef GrGLCaps_DEFINED #define GrGLCaps_DEFINED -#include "GrCaps.h" #include "glsl/GrGLSL.h" +#include "GrCaps.h" #include "GrGLStencilAttachment.h" +#include "GrSwizzle.h" #include "SkChecksum.h" #include "SkTHash.h" #include "SkTArray.h" @@ -142,6 +143,11 @@ 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 @@ -307,6 +313,9 @@ 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 @@ -335,15 +344,12 @@ private: void initBlendEqationSupport(const GrGLContextInfo&); void initStencilFormats(const GrGLContextInfo&); // This must be called after initFSAASupport(). - void initConfigTable(const GrGLContextInfo&, const GrGLInterface* gli); + void initConfigTable(const GrGLContextInfo&, const GrGLInterface* gli, GrGLSLCaps* glslCaps); void initShaderPrecisionTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* intf, GrGLSLCaps* glslCaps); - void initConfigSwizzleTable(const GrGLContextInfo& ctxInfo, GrGLSLCaps* glslCaps); - - SkTArray<StencilFormat, true> fStencilFormats; int fMaxFragmentUniformVectors; @@ -376,6 +382,7 @@ 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 { @@ -418,6 +425,8 @@ 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 49b8f3acb8..e0b7d4aca5 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 GrGLSLCaps& caps, + const GrGLCaps& caps, GrGLenum* glSwizzle) { - const char* swizzle = caps.getSwizzleMap(config); + const GrSwizzle& swizzle = caps.configSwizzle(config); for (int i = 0; i < 4; ++i) { - glSwizzle[i] = get_component_enum_from_char(swizzle[i]); + glSwizzle[i] = get_component_enum_from_char(swizzle.c_str()[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().glslCaps(), newTexParams.fSwizzleRGBA); + get_tex_param_swizzle(texture->config(), this->glCaps(), 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().glslCaps()->mustSwizzleInShader() && + if (this->glCaps().textureSwizzleSupport() && (setAll || memcmp(newTexParams.fSwizzleRGBA, oldTexParams.fSwizzleRGBA, sizeof(newTexParams.fSwizzleRGBA)))) { diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index 81f92eb243..032562550c 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -13,36 +13,23 @@ #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 uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) { - uint32_t key = 0; +static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc, + const GrGLSLCaps& caps) { int numTextures = proc.numTextures(); - 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; + // 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); } - return key; } /** @@ -51,15 +38,14 @@ static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) { * 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 - * 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 + * 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. @@ -68,10 +54,11 @@ static bool gen_meta_key(const GrProcessor& proc, return false; } - uint32_t* key = b->add32n(3); + add_texture_key(b, proc, *caps.glslCaps()); + + uint32_t* key = b->add32n(2); key[0] = (classID << 16) | SkToU32(processorKeySize); - key[1] = textureKey; - key[2] = transformKey; + key[1] = transformKey; return true; } diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp index cf41f8e765..c82d8333df 100755 --- a/src/gpu/glsl/GrGLSLCaps.cpp +++ b/src/gpu/glsl/GrGLSLCaps.cpp @@ -31,9 +31,6 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) { fFBFetchColorName = nullptr; fFBFetchExtensionString = nullptr; fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction; - - fMustSwizzleInShader = false; - memset(fConfigSwizzle, 0, sizeof(fConfigSwizzle)); } SkString GrGLSLCaps::dump() const { @@ -67,8 +64,5 @@ 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 21c59e7b16..eba9602e5a 100755 --- a/src/gpu/glsl/GrGLSLCaps.h +++ b/src/gpu/glsl/GrGLSLCaps.h @@ -11,6 +11,7 @@ #include "GrCaps.h" #include "GrGLSL.h" +#include "GrSwizzle.h" class GrGLSLCaps : public GrShaderCaps { public: @@ -104,14 +105,14 @@ public: return fExternalTextureExtensionString; } - bool mustSwizzleInShader() const { return fMustSwizzleInShader; } - /** - * 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. + * 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". */ - const char* getSwizzleMap(GrPixelConfig config) const { return fConfigSwizzle[config]; } + const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const { + return fConfigTextureSwizzle[config]; + } GrGLSLGeneration generation() const { return fGLSLGeneration; } @@ -148,13 +149,11 @@ private: AdvBlendEqInteraction fAdvBlendEqInteraction; - bool fMustSwizzleInShader; - const char* fConfigSwizzle[kGrPixelConfigCnt]; + GrSwizzle fConfigTextureSwizzle[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 5716c0bd12..2d2ff8768e 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp @@ -5,70 +5,13 @@ * 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) @@ -117,14 +60,21 @@ void GrGLSLShaderBuilder::appendTextureLookup(SkString* out, const GrGLSLTextureSampler& sampler, const char* coordName, GrSLType varyingType) const { + const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps(); GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler(); - append_texture_lookup(out, - fProgramBuilder->glslCaps(), - uniformHandler->getUniformCStr(sampler.fSamplerUniform), - coordName, - sampler.config(), - sampler.swizzle(), - varyingType); + 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()); + } } void GrGLSLShaderBuilder::appendTextureLookup(const GrGLSLTextureSampler& sampler, diff --git a/src/gpu/glsl/GrGLSLTextureSampler.h b/src/gpu/glsl/GrGLSLTextureSampler.h index a4fbf550f2..fd8bcb26e9 100644 --- a/src/gpu/glsl/GrGLSLTextureSampler.h +++ b/src/gpu/glsl/GrGLSLTextureSampler.h @@ -21,17 +21,13 @@ 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; }; |