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
This commit is contained in:
parent
d9c0037211
commit
cdee009886
@ -14,60 +14,33 @@
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
/** A class representing the swizzle access pattern for a texture. Note that if the texture is
|
||||
* an alpha-only texture then the alpha channel is substituted for other components. Any mangling
|
||||
* to handle the r,g,b->a conversions for alpha textures is automatically included in the stage
|
||||
* key. However, if a GrProcessor uses different swizzles based on its input then it must
|
||||
* consider that variation in its key-generation.
|
||||
/**
|
||||
* Used to represent a texture that is required by a GrProcessor. It holds a GrTexture along with
|
||||
* an associated GrTextureParams
|
||||
*/
|
||||
class GrTextureAccess : public SkNoncopyable {
|
||||
public:
|
||||
/**
|
||||
* A default GrTextureAccess must have reset() called on it in a GrProcessor subclass's
|
||||
* constructor if it will be accessible via GrProcessor::textureAccess().
|
||||
* Must be initialized before adding to a GrProcessor's texture access list.
|
||||
*/
|
||||
GrTextureAccess();
|
||||
|
||||
/**
|
||||
* Uses the default swizzle, "rgba".
|
||||
*/
|
||||
GrTextureAccess(GrTexture*, const GrTextureParams&);
|
||||
|
||||
explicit GrTextureAccess(GrTexture*,
|
||||
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
|
||||
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
|
||||
|
||||
/**
|
||||
* swizzle must be a string between one and four (inclusive) characters containing only 'r',
|
||||
* 'g', 'b', and/or 'a'.
|
||||
*/
|
||||
GrTextureAccess(GrTexture*, const char* swizzle, const GrTextureParams&);
|
||||
GrTextureAccess(GrTexture*,
|
||||
const char* swizzle,
|
||||
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
|
||||
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
|
||||
|
||||
void reset(GrTexture*, const GrTextureParams&);
|
||||
void reset(GrTexture*,
|
||||
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
|
||||
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
|
||||
void reset(GrTexture*, const char* swizzle, const GrTextureParams&);
|
||||
void reset(GrTexture*,
|
||||
const char* swizzle,
|
||||
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
|
||||
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
|
||||
|
||||
bool operator== (const GrTextureAccess& other) const {
|
||||
#ifdef SK_DEBUG
|
||||
// below assumes all chars in fSwizzle are initialized even if string is < 4 chars long.
|
||||
SkASSERT(memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1) ==
|
||||
strcmp(fSwizzle, other.fSwizzle));
|
||||
#endif
|
||||
return fParams == other.fParams &&
|
||||
(this->getTexture() == other.getTexture()) &&
|
||||
(0 == memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1));
|
||||
bool operator==(const GrTextureAccess& that) const {
|
||||
return this->getTexture() == that.getTexture() && fParams == that.fParams;
|
||||
}
|
||||
|
||||
bool operator!= (const GrTextureAccess& other) const { return !(*this == other); }
|
||||
bool operator!=(const GrTextureAccess& other) const { return !(*this == other); }
|
||||
|
||||
GrTexture* getTexture() const { return fTexture.get(); }
|
||||
|
||||
@ -76,26 +49,14 @@ public:
|
||||
*/
|
||||
const GrGpuResourceRef* getProgramTexture() const { return &fTexture; }
|
||||
|
||||
/**
|
||||
* Returns a string representing the swizzle. The string is is null-terminated.
|
||||
*/
|
||||
const char* getSwizzle() const { return fSwizzle; }
|
||||
|
||||
/** Returns a mask indicating which components are referenced in the swizzle. The return
|
||||
is a bitfield of GrColorComponentFlags. */
|
||||
uint32_t swizzleMask() const { return fSwizzleMask; }
|
||||
|
||||
const GrTextureParams& getParams() const { return fParams; }
|
||||
|
||||
private:
|
||||
void setSwizzle(const char*);
|
||||
|
||||
typedef GrTGpuResourceRef<GrTexture> ProgramTexture;
|
||||
|
||||
ProgramTexture fTexture;
|
||||
GrTextureParams fParams;
|
||||
uint32_t fSwizzleMask;
|
||||
char fSwizzle[5];
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
@ -12,10 +12,10 @@
|
||||
#include "SkTArray.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
/**
|
||||
* Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
|
||||
* but should be applicable to other shader languages.)
|
||||
*/
|
||||
/**
|
||||
* Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
|
||||
* but should be applicable to other shader languages.)
|
||||
*/
|
||||
enum GrSLType {
|
||||
kVoid_GrSLType,
|
||||
kFloat_GrSLType,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
92
src/gpu/GrSwizzle.h
Normal file
92
src/gpu/GrSwizzle.h
Normal file
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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)))) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user