aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/effects/SkColorCubeFilter.cpp6
-rw-r--r--src/effects/SkTableColorFilter.cpp2
-rw-r--r--src/gpu/GrSwizzle.h92
-rw-r--r--src/gpu/GrTextureAccess.cpp71
-rw-r--r--src/gpu/gl/GrGLCaps.cpp92
-rw-r--r--src/gpu/gl/GrGLCaps.h19
-rw-r--r--src/gpu/gl/GrGLGpu.cpp10
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp53
-rwxr-xr-xsrc/gpu/glsl/GrGLSLCaps.cpp6
-rwxr-xr-xsrc/gpu/glsl/GrGLSLCaps.h17
-rw-r--r--src/gpu/glsl/GrGLSLShaderBuilder.cpp80
-rw-r--r--src/gpu/glsl/GrGLSLTextureSampler.h4
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;
};