зеркало из https://github.com/mozilla/moz-skia.git
Wrap all GrCustomStage textures in GrTextureAccess, remove StageDesc::fInConfigFlags
Review URL: https://codereview.appspot.com/6494114 git-svn-id: http://skia.googlecode.com/svn/trunk@5485 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
4813458d89
Коммит
6d003d1ddc
|
@ -81,12 +81,14 @@ public:
|
|||
in generated shader code. */
|
||||
const char* name() const { return this->getFactory().name(); }
|
||||
|
||||
virtual unsigned int numTextures() const;
|
||||
virtual GrTexture* texture(unsigned int index) const;
|
||||
virtual int numTextures() const;
|
||||
|
||||
/** Returns the access pattern for the texture at index. Returns NULL if index is
|
||||
unused. */
|
||||
virtual const GrTextureAccess* textureAccess(unsigned int index) const;
|
||||
/** Returns the access pattern for the texture at index. index must be valid according to
|
||||
numTextures(). */
|
||||
virtual const GrTextureAccess& textureAccess(int index) const;
|
||||
|
||||
/** Shortcut for textureAccess(index).texture(); */
|
||||
GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
|
||||
|
||||
void* operator new(size_t size);
|
||||
void operator delete(void* target);
|
||||
|
|
|
@ -8,29 +8,62 @@
|
|||
#ifndef GrTextureAccess_DEFINED
|
||||
#define GrTextureAccess_DEFINED
|
||||
|
||||
#include "GrTypes.h"
|
||||
#include "GrNoncopyable.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class GrTexture;
|
||||
class SkString;
|
||||
|
||||
/** A class representing the swizzle access pattern for a texture.
|
||||
/** 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 GrCustomStage uses different swizzles based on its input then it must
|
||||
* consider that variation in its key-generation.
|
||||
*/
|
||||
class GrTextureAccess {
|
||||
class GrTextureAccess : GrNoncopyable {
|
||||
public:
|
||||
typedef char Swizzle[4];
|
||||
/**
|
||||
* A default GrTextureAccess must have reset() called on it in a GrCustomStage subclass's
|
||||
* constructor if it will be accessible via GrCustomStage::textureAccess().
|
||||
*/
|
||||
GrTextureAccess();
|
||||
|
||||
GrTextureAccess(const GrTexture* texture, const SkString& swizzle);
|
||||
/**
|
||||
* 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 GrTexture* getTexture() const { return fTexture; }
|
||||
const Swizzle& getSwizzle() const { return fSwizzle; }
|
||||
/**
|
||||
* Uses the default swizzle, "rgba".
|
||||
*/
|
||||
GrTextureAccess(GrTexture*);
|
||||
|
||||
bool referencesAlpha() const {
|
||||
return fSwizzle[0] == 'a' || fSwizzle[1] == 'a' || fSwizzle[2] == 'a' || fSwizzle[3] == 'a';
|
||||
}
|
||||
void reset(GrTexture*, const char* swizzle);
|
||||
void reset(GrTexture*);
|
||||
|
||||
GrTexture* getTexture() const { return fTexture.get(); }
|
||||
|
||||
/**
|
||||
* Returns a string representing the swizzle. The string is is null-terminated.
|
||||
*/
|
||||
const char* getSwizzle() const { return fSwizzle; }
|
||||
|
||||
enum {
|
||||
kR_SwizzleFlag = 0x1,
|
||||
kG_SwizzleFlag = 0x2,
|
||||
kB_SwizzleFlag = 0x4,
|
||||
kA_SwizzleFlag = 0x8,
|
||||
|
||||
kRGB_SwizzleMask = (kR_SwizzleFlag | kG_SwizzleFlag | kB_SwizzleFlag),
|
||||
};
|
||||
|
||||
/** Returns a mask indicating which components are referenced in the swizzle. */
|
||||
uint32_t swizzleMask() const { return fSwizzleMask; }
|
||||
|
||||
private:
|
||||
const GrTexture* fTexture;
|
||||
Swizzle fSwizzle;
|
||||
SkAutoTUnref<GrTexture> fTexture;
|
||||
uint32_t fSwizzleMask;
|
||||
char fSwizzle[5];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -719,8 +719,7 @@ void GrGLGradientStage::emitColorLookup(GrGLShaderBuilder* builder,
|
|||
GrGradientEffect::GrGradientEffect(GrContext* ctx,
|
||||
const SkGradientShaderBase& shader,
|
||||
GrSamplerState* sampler)
|
||||
: fTexture (NULL)
|
||||
, fUseTexture (true) {
|
||||
: fUseTexture (true) {
|
||||
// TODO: check for simple cases where we don't need a texture:
|
||||
//GradientInfo info;
|
||||
//shader.asAGradient(&info);
|
||||
|
@ -742,35 +741,32 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
|
|||
if (-1 != fRow) {
|
||||
fYCoord = fAtlas->getYOffset(fRow) + GR_ScalarHalf *
|
||||
fAtlas->getVerticalScaleFactor();
|
||||
fTexture = fAtlas->getTexture();
|
||||
fTextureAccess.reset(fAtlas->getTexture());
|
||||
} else {
|
||||
fTexture = GrLockCachedBitmapTexture(ctx, bitmap, sampler->textureParams());
|
||||
SkSafeRef(fTexture);
|
||||
GrTexture* texture = GrLockCachedBitmapTexture(ctx, bitmap, sampler->textureParams());
|
||||
fTextureAccess.reset(texture);
|
||||
fYCoord = GR_ScalarHalf;
|
||||
|
||||
// Unlock immediately, this is not great, but we don't have a way of
|
||||
// knowing when else to unlock it currently, so it may get purged from
|
||||
// the cache, but it'll still be ref'd until it's no longer being used.
|
||||
GrUnlockCachedBitmapTexture(fTexture);
|
||||
GrUnlockCachedBitmapTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
GrGradientEffect::~GrGradientEffect() {
|
||||
if (this->useAtlas()) {
|
||||
fAtlas->unlockRow(fRow);
|
||||
} else {
|
||||
SkSafeUnref(fTexture);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int GrGradientEffect::numTextures() const {
|
||||
int GrGradientEffect::numTextures() const {
|
||||
return fUseTexture ? 1 : 0;
|
||||
}
|
||||
|
||||
GrTexture* GrGradientEffect::texture(unsigned int index)
|
||||
const {
|
||||
const GrTextureAccess& GrGradientEffect::textureAccess(int index) const {
|
||||
GrAssert(fUseTexture && 0 == index);
|
||||
return fTexture;
|
||||
return fTextureAccess;
|
||||
}
|
||||
|
||||
int GrGradientEffect::RandomGradientParams(SkRandom* random,
|
||||
|
|
|
@ -231,14 +231,14 @@ public:
|
|||
|
||||
virtual ~GrGradientEffect();
|
||||
|
||||
unsigned int numTextures() const;
|
||||
GrTexture* texture(unsigned int index) const;
|
||||
virtual int numTextures() const SK_OVERRIDE;
|
||||
virtual const GrTextureAccess& textureAccess(int index) const SK_OVERRIDE;
|
||||
|
||||
bool useTexture() const { return fUseTexture; }
|
||||
bool useAtlas() const { return SkToBool(-1 != fRow); }
|
||||
GrScalar getYCoord() const { GrAssert(fUseTexture); return fYCoord; };
|
||||
|
||||
bool isEqual(const GrCustomStage& stage) const {
|
||||
virtual bool isEqual(const GrCustomStage& stage) const SK_OVERRIDE {
|
||||
const GrGradientEffect& s = static_cast<const GrGradientEffect&>(stage);
|
||||
return INHERITED::isEqual(stage) && this->useAtlas() == s.useAtlas() &&
|
||||
fYCoord == s.getYCoord();
|
||||
|
@ -260,7 +260,7 @@ protected:
|
|||
SkShader::TileMode* tm);
|
||||
|
||||
private:
|
||||
GrTexture* fTexture;
|
||||
GrTextureAccess fTextureAccess;
|
||||
bool fUseTexture;
|
||||
GrScalar fYCoord;
|
||||
GrTextureStripAtlas* fAtlas;
|
||||
|
|
|
@ -54,7 +54,7 @@ bool GrCustomStage::isEqual(const GrCustomStage& s) const {
|
|||
if (this->numTextures() != s.numTextures()) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned int i = 0; i < this->numTextures(); ++i) {
|
||||
for (int i = 0; i < this->numTextures(); ++i) {
|
||||
if (this->texture(i) != s.texture(i)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -62,16 +62,14 @@ bool GrCustomStage::isEqual(const GrCustomStage& s) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned int GrCustomStage::numTextures() const {
|
||||
int GrCustomStage::numTextures() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
GrTexture* GrCustomStage::texture(unsigned int index) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GrTextureAccess* GrCustomStage::textureAccess(unsigned int index) const {
|
||||
return NULL;
|
||||
const GrTextureAccess& GrCustomStage::textureAccess(int index) const {
|
||||
GrCrash("We shouldn't be calling this function on the base class.");
|
||||
static GrTextureAccess kDummy;
|
||||
return kDummy;
|
||||
}
|
||||
|
||||
void * GrCustomStage::operator new(size_t size) {
|
||||
|
|
|
@ -6,16 +6,62 @@
|
|||
*/
|
||||
|
||||
#include "GrTextureAccess.h"
|
||||
#include "SkString.h"
|
||||
|
||||
GrTextureAccess::GrTextureAccess(const GrTexture* texture, const SkString& swizzle)
|
||||
: fTexture(texture) {
|
||||
GrAssert(swizzle.size() <= 4);
|
||||
for (unsigned int offset = 0; offset < swizzle.size(); ++offset) {
|
||||
fSwizzle[offset] = swizzle[offset];
|
||||
}
|
||||
if (swizzle.size() < 4) {
|
||||
fSwizzle[swizzle.size()] = 0;
|
||||
}
|
||||
#include "GrTexture.h"
|
||||
|
||||
GrTextureAccess::GrTextureAccess() {
|
||||
#if GR_DEBUG
|
||||
memcpy(fSwizzle, "void", 5);
|
||||
fSwizzleMask = 0xbeeffeed;
|
||||
#endif
|
||||
}
|
||||
|
||||
GrTextureAccess::GrTextureAccess(GrTexture* texture, const char* swizzle) {
|
||||
this->reset(texture, swizzle);
|
||||
}
|
||||
|
||||
GrTextureAccess::GrTextureAccess(GrTexture* texture) {
|
||||
this->reset(texture);
|
||||
}
|
||||
|
||||
void GrTextureAccess::reset(GrTexture* texture, const char* swizzle) {
|
||||
GrAssert(NULL != texture);
|
||||
GrAssert(strlen(swizzle) >= 1 && strlen(swizzle) <= 4);
|
||||
|
||||
texture->ref();
|
||||
fTexture.reset(texture);
|
||||
|
||||
fSwizzleMask = 0;
|
||||
fSwizzle[4] = '\0';
|
||||
int i = 0;
|
||||
do {
|
||||
fSwizzle[i] = swizzle[i];
|
||||
switch (swizzle[i]) {
|
||||
case 'r':
|
||||
fSwizzleMask |= kR_SwizzleFlag;
|
||||
break;
|
||||
case 'g':
|
||||
fSwizzleMask |= kG_SwizzleFlag;
|
||||
break;
|
||||
case 'b':
|
||||
fSwizzleMask |= kB_SwizzleFlag;
|
||||
break;
|
||||
case 'a':
|
||||
fSwizzleMask |= kA_SwizzleFlag;
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
GrCrash("Unexpected swizzle string character.");
|
||||
break;
|
||||
}
|
||||
} while ('\0' != swizzle[i] && ++i < 4);
|
||||
}
|
||||
|
||||
void GrTextureAccess::reset(GrTexture* texture) {
|
||||
GrAssert(NULL != texture);
|
||||
texture->ref();
|
||||
fTexture.reset(texture);
|
||||
memcpy(fSwizzle, "rgba", 5);
|
||||
fSwizzleMask = (kRGB_SwizzleMask | kA_SwizzleFlag);
|
||||
}
|
||||
|
|
|
@ -91,8 +91,7 @@ GrGLProgramStage::StageKey GrGLColorTableEffect::GenKey(const GrCustomStage& s,
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrColorTableEffect::GrColorTableEffect(GrTexture* texture)
|
||||
: INHERITED(texture)
|
||||
, fTextureAccess(texture, SkString("a")) {
|
||||
: fTextureAccess(texture, "a") {
|
||||
}
|
||||
|
||||
GrColorTableEffect::~GrColorTableEffect() {
|
||||
|
@ -106,11 +105,9 @@ bool GrColorTableEffect::isEqual(const GrCustomStage& sBase) const {
|
|||
return INHERITED::isEqual(sBase);
|
||||
}
|
||||
|
||||
const GrTextureAccess* GrColorTableEffect::textureAccess(unsigned int index) const {
|
||||
if (0 == index)
|
||||
return &fTextureAccess;
|
||||
|
||||
return NULL;
|
||||
const GrTextureAccess& GrColorTableEffect::textureAccess(int index) const {
|
||||
GrAssert(0 == index);
|
||||
return fTextureAccess;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -18,8 +18,7 @@ class GrGLColorTableEffect;
|
|||
* counterpart to the SkTable_ColorFilter effect. A 256 * 4 (single-channel)
|
||||
* LUT is used to transform the input colors of the image.
|
||||
*/
|
||||
class GrColorTableEffect : public GrSingleTextureEffect {
|
||||
|
||||
class GrColorTableEffect : public GrCustomStage {
|
||||
public:
|
||||
|
||||
GrColorTableEffect(GrTexture* texture);
|
||||
|
@ -29,7 +28,8 @@ public:
|
|||
virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE;
|
||||
virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE;
|
||||
|
||||
virtual const GrTextureAccess* textureAccess(unsigned int index) const SK_OVERRIDE;
|
||||
virtual int numTextures() const SK_OVERRIDE { return 1; }
|
||||
virtual const GrTextureAccess& textureAccess(int index) const SK_OVERRIDE;
|
||||
|
||||
typedef GrGLColorTableEffect GLProgramStage;
|
||||
|
||||
|
@ -38,6 +38,6 @@ private:
|
|||
|
||||
GrTextureAccess fTextureAccess;
|
||||
|
||||
typedef GrSingleTextureEffect INHERITED;
|
||||
typedef GrCustomStage INHERITED;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -38,21 +38,19 @@ private:
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture)
|
||||
: fTexture (texture) {
|
||||
SkSafeRef(fTexture);
|
||||
: fTextureAccess(texture) {
|
||||
}
|
||||
|
||||
GrSingleTextureEffect::~GrSingleTextureEffect() {
|
||||
SkSafeUnref(fTexture);
|
||||
}
|
||||
|
||||
unsigned int GrSingleTextureEffect::numTextures() const {
|
||||
int GrSingleTextureEffect::numTextures() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
GrTexture* GrSingleTextureEffect::texture(unsigned int index) const {
|
||||
const GrTextureAccess& GrSingleTextureEffect::textureAccess(int index) const {
|
||||
GrAssert(0 == index);
|
||||
return fTexture;
|
||||
return fTextureAccess;
|
||||
}
|
||||
|
||||
const GrProgramStageFactory& GrSingleTextureEffect::getFactory() const {
|
||||
|
|
|
@ -21,8 +21,8 @@ public:
|
|||
GrSingleTextureEffect(GrTexture* texture);
|
||||
virtual ~GrSingleTextureEffect();
|
||||
|
||||
virtual unsigned int numTextures() const SK_OVERRIDE;
|
||||
virtual GrTexture* texture(unsigned int index) const SK_OVERRIDE;
|
||||
virtual int numTextures() const SK_OVERRIDE;
|
||||
virtual const GrTextureAccess& textureAccess(int index) const SK_OVERRIDE;
|
||||
|
||||
static const char* Name() { return "Single Texture"; }
|
||||
|
||||
|
@ -33,7 +33,7 @@ public:
|
|||
private:
|
||||
GR_DECLARE_CUSTOM_STAGE_TEST;
|
||||
|
||||
GrTexture* fTexture;
|
||||
GrTextureAccess fTextureAccess;
|
||||
|
||||
typedef GrCustomStage INHERITED;
|
||||
};
|
||||
|
|
|
@ -931,8 +931,6 @@ GrGLProgramStage* GrGLProgram::GenStageCode(const GrCustomStage* stage,
|
|||
|
||||
GrGLProgramStage* glStage = stage->getFactory().createGLInstance(*stage);
|
||||
|
||||
GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) == desc.fInConfigFlags);
|
||||
|
||||
/// Vertex Shader Stuff
|
||||
|
||||
// decide whether we need a matrix to transform texture coords and whether the varying needs a
|
||||
|
@ -964,30 +962,11 @@ GrGLProgramStage* GrGLProgram::GenStageCode(const GrCustomStage* stage,
|
|||
|
||||
int numTextures = stage->numTextures();
|
||||
SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
|
||||
// temporary until we force custom stages to provide their own texture access
|
||||
SkSTArray<8, bool, true> deleteTextureAccess;
|
||||
|
||||
textureSamplers.push_back_n(numTextures);
|
||||
deleteTextureAccess.push_back_n(numTextures);
|
||||
|
||||
for (int i = 0; i < numTextures; ++i) {
|
||||
// Right now we don't require a texture access for every texture. This will change soon.
|
||||
const GrTextureAccess* access = stage->textureAccess(i);
|
||||
GrAssert(NULL != stage->texture(i));
|
||||
if (NULL == access) {
|
||||
SkString swizzle;
|
||||
if (desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag) {
|
||||
swizzle.printf("aaaa");
|
||||
} else {
|
||||
swizzle.printf("rgba");
|
||||
}
|
||||
access = SkNEW_ARGS(GrTextureAccess, (stage->texture(i), swizzle));
|
||||
deleteTextureAccess[i] = true;
|
||||
} else {
|
||||
GrAssert(access->getTexture() == stage->texture(i));
|
||||
deleteTextureAccess[i] = false;
|
||||
}
|
||||
textureSamplers[i].init(builder, access);
|
||||
textureSamplers[i].init(builder, &stage->textureAccess(i));
|
||||
uniforms->fSamplerUniforms.push_back(textureSamplers[i].fSamplerUniform);
|
||||
}
|
||||
|
||||
|
@ -1010,10 +989,5 @@ GrGLProgramStage* GrGLProgram::GenStageCode(const GrCustomStage* stage,
|
|||
glStage->emitFS(builder, fsOutColor, fsInColor, textureSamplers);
|
||||
builder->fFSCode.appendf("\t}\n");
|
||||
|
||||
for (int i = 0; i < numTextures; ++i) {
|
||||
if (deleteTextureAccess[i]) {
|
||||
SkDELETE(textureSamplers[i].textureAccess());
|
||||
}
|
||||
}
|
||||
return glStage;
|
||||
}
|
||||
|
|
|
@ -97,35 +97,12 @@ public:
|
|||
kIsEnabled_OptFlagBit = 1 << 7
|
||||
};
|
||||
|
||||
/**
|
||||
Flags set based on a src texture's pixel config. The operations
|
||||
described are performed after reading a texel.
|
||||
*/
|
||||
enum InConfigFlags {
|
||||
kNone_InConfigFlag = 0x00,
|
||||
|
||||
/**
|
||||
Smear alpha across all four channels. It is prefereable to perform the smear
|
||||
outside the shader using GL_ARB_texture_swizzle if possible rather than setting
|
||||
this flag.
|
||||
*/
|
||||
kSmearAlpha_InConfigFlag = 0x01,
|
||||
|
||||
kDummyInConfigFlag,
|
||||
kInConfigBitMask = (kDummyInConfigFlag-1) |
|
||||
(kDummyInConfigFlag-2)
|
||||
};
|
||||
|
||||
uint8_t fOptFlags;
|
||||
uint8_t fInConfigFlags; // bitfield of InConfigFlags values
|
||||
|
||||
/** Non-zero if user-supplied code will write the stage's
|
||||
contribution to the fragment shader. */
|
||||
GrProgramStageFactory::StageKey fCustomStageKey;
|
||||
|
||||
GR_STATIC_ASSERT((InConfigFlags)(uint8_t)kInConfigBitMask ==
|
||||
kInConfigBitMask);
|
||||
|
||||
inline bool isEnabled() const {
|
||||
return SkToBool(fOptFlags & kIsEnabled_OptFlagBit);
|
||||
}
|
||||
|
|
|
@ -30,11 +30,11 @@ void GrGLProgramStage::setData(const GrGLUniformManager&,
|
|||
GrGLProgramStage::StageKey GrGLProgramStage::GenTextureKey(const GrCustomStage& stage,
|
||||
const GrGLCaps& caps) {
|
||||
StageKey key = 0;
|
||||
for (unsigned int index = 0; index < stage.numTextures(); ++index) {
|
||||
if (stage.textureAccess(index)) {
|
||||
key = (key << index) |
|
||||
GrGLShaderBuilder::KeyForTextureAccess(*stage.textureAccess(index), caps);
|
||||
}
|
||||
for (int index = 0; index < stage.numTextures(); ++index) {
|
||||
const GrTextureAccess& access = stage.textureAccess(index);
|
||||
StageKey value = GrGLShaderBuilder::KeyForTextureAccess(access, caps) << index;
|
||||
GrAssert(0 == (value & key)); // keys for each access ought not to overlap
|
||||
key |= value;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
|
|
@ -33,30 +33,40 @@ inline const char* sample_function_name(GrSLType type) {
|
|||
}
|
||||
}
|
||||
|
||||
inline bool texture_requires_alpha_to_red_swizzle(const GrGLCaps& caps,
|
||||
const GrTextureAccess& access) {
|
||||
return GrPixelConfigIsAlphaOnly(access.getTexture()->config()) && caps.textureRedSupport() &&
|
||||
access.referencesAlpha();
|
||||
}
|
||||
|
||||
SkString build_swizzle_string(const GrTextureAccess& textureAccess,
|
||||
const GrGLCaps& caps) {
|
||||
const GrTextureAccess::Swizzle& swizzle = textureAccess.getSwizzle();
|
||||
if (0 == swizzle[0]) {
|
||||
return SkString("");
|
||||
}
|
||||
|
||||
SkString swizzleOut(".");
|
||||
bool alphaIsRed = texture_requires_alpha_to_red_swizzle(caps, textureAccess);
|
||||
for (int offset = 0; offset < 4 && swizzle[offset]; ++offset) {
|
||||
if (alphaIsRed && 'a' == swizzle[offset]) {
|
||||
swizzleOut.appendf("r");
|
||||
} else {
|
||||
swizzleOut.appendf("%c", swizzle[offset]);
|
||||
/**
|
||||
* Do we need to either map r,g,b->a or a->r.
|
||||
*/
|
||||
inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
|
||||
const GrTextureAccess& access) {
|
||||
if (GrPixelConfigIsAlphaOnly(access.getTexture()->config())) {
|
||||
if (caps.textureRedSupport() && (GrTextureAccess::kA_SwizzleFlag & access.swizzleMask())) {
|
||||
return true;
|
||||
}
|
||||
if (GrTextureAccess::kRGB_SwizzleMask & access.swizzleMask()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return swizzleOut;
|
||||
void append_swizzle(SkString* outAppend,
|
||||
const GrTextureAccess& access,
|
||||
const GrGLCaps& caps) {
|
||||
const char* swizzle = access.getSwizzle();
|
||||
char mangledSwizzle[5];
|
||||
|
||||
// The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
|
||||
// is available.
|
||||
if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(access.getTexture()->config())) {
|
||||
char alphaChar = caps.textureRedSupport() ? 'r' : 'a';
|
||||
int i;
|
||||
for (i = 0; '\0' != swizzle[i]; ++i) {
|
||||
mangledSwizzle[i] = alphaChar;
|
||||
}
|
||||
mangledSwizzle[i] ='\0';
|
||||
swizzle = mangledSwizzle;
|
||||
}
|
||||
outAppend->appendf(".%s", swizzle);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -114,16 +124,16 @@ void GrGLShaderBuilder::appendTextureLookup(SkString* out,
|
|||
const char* coordName,
|
||||
GrSLType varyingType) const {
|
||||
GrAssert(NULL != sampler.textureAccess());
|
||||
SkString swizzle = build_swizzle_string(*sampler.textureAccess(), fContext.caps());
|
||||
|
||||
if (NULL == coordName) {
|
||||
coordName = fDefaultTexCoordsName.c_str();
|
||||
varyingType = kVec2f_GrSLType;
|
||||
}
|
||||
out->appendf("%s(%s, %s)%s",
|
||||
out->appendf("%s(%s, %s)",
|
||||
sample_function_name(varyingType),
|
||||
this->getUniformCStr(sampler.fSamplerUniform),
|
||||
coordName, swizzle.c_str());
|
||||
coordName);
|
||||
append_swizzle(out, *sampler.textureAccess(), fContext.caps());
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::appendTextureLookupAndModulate(
|
||||
|
@ -144,17 +154,36 @@ GrCustomStage::StageKey GrGLShaderBuilder::KeyForTextureAccess(const GrTextureAc
|
|||
|
||||
// Assume that swizzle support implies that we never have to modify a shader to adjust
|
||||
// for texture format/swizzle settings.
|
||||
if (caps.textureSwizzleSupport()) {
|
||||
return key;
|
||||
}
|
||||
|
||||
if (texture_requires_alpha_to_red_swizzle(caps, access)) {
|
||||
if (!caps.textureSwizzleSupport() && swizzle_requires_alpha_remapping(caps, access)) {
|
||||
key = 1;
|
||||
}
|
||||
|
||||
#if GR_DEBUG
|
||||
// Assert that key is set iff the swizzle will be modified.
|
||||
SkString origString(access.getSwizzle());
|
||||
origString.prepend(".");
|
||||
SkString modifiedString;
|
||||
append_swizzle(&modifiedString, access, caps);
|
||||
GrAssert(SkToBool(key) == (modifiedString != origString));
|
||||
#endif
|
||||
return key;
|
||||
}
|
||||
|
||||
const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
|
||||
if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
|
||||
if (caps.textureRedSupport()) {
|
||||
static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
|
||||
return gRedSmear;
|
||||
} else {
|
||||
static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
|
||||
GR_GL_ALPHA, GR_GL_ALPHA };
|
||||
return gAlphaSmear;
|
||||
}
|
||||
} else {
|
||||
static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
|
||||
return gStraight;
|
||||
}
|
||||
}
|
||||
|
||||
GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t visibility,
|
||||
GrSLType type,
|
||||
const char* name,
|
||||
|
|
|
@ -125,6 +125,10 @@ public:
|
|||
static GrCustomStage::StageKey KeyForTextureAccess(const GrTextureAccess& access,
|
||||
const GrGLCaps& caps);
|
||||
|
||||
/** 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 const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
|
||||
|
||||
/** Add a uniform variable to the current program, that has visibilty in one or more shaders.
|
||||
visibility is a bitfield of ShaderType values indicating from which shaders the uniform
|
||||
should be accessible. At least one bit must be set. Geometry shader uniforms are not
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "GrGpuGL.h"
|
||||
#include "GrGLStencilBuffer.h"
|
||||
#include "GrGLPath.h"
|
||||
#include "GrGLShaderBuilder.h"
|
||||
#include "GrTemplates.h"
|
||||
#include "GrTypes.h"
|
||||
#include "SkTemplates.h"
|
||||
|
@ -2001,28 +2002,7 @@ void GrGpuGL::flushBlend(bool isLines,
|
|||
}
|
||||
namespace {
|
||||
|
||||
// get_swizzle is only called from this .cpp so it is OK to inline it here
|
||||
inline const GrGLenum* get_swizzle(GrPixelConfig config,
|
||||
const GrSamplerState& sampler,
|
||||
const GrGLCaps& glCaps) {
|
||||
if (GrPixelConfigIsAlphaOnly(config)) {
|
||||
if (glCaps.textureRedSupport()) {
|
||||
static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED,
|
||||
GR_GL_RED, GR_GL_RED };
|
||||
return gRedSmear;
|
||||
} else {
|
||||
static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
|
||||
GR_GL_ALPHA, GR_GL_ALPHA };
|
||||
return gAlphaSmear;
|
||||
}
|
||||
} else {
|
||||
static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN,
|
||||
GR_GL_BLUE, GR_GL_ALPHA };
|
||||
return gStraight;
|
||||
}
|
||||
}
|
||||
|
||||
void set_tex_swizzle(GrGLenum swizzle[4], const GrGLInterface* gl) {
|
||||
inline void set_tex_swizzle(GrGLenum swizzle[4], const GrGLInterface* gl) {
|
||||
GR_GL_CALL(gl, TexParameteriv(GR_GL_TEXTURE_2D,
|
||||
GR_GL_TEXTURE_SWIZZLE_RGBA,
|
||||
reinterpret_cast<const GrGLint*>(swizzle)));
|
||||
|
@ -2089,7 +2069,7 @@ void GrGpuGL::flushBoundTextureAndParams(int stage,
|
|||
newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
|
||||
newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
|
||||
memcpy(newTexParams.fSwizzleRGBA,
|
||||
get_swizzle(nextTexture->config(), drawState->getSampler(stage), this->glCaps()),
|
||||
GrGLShaderBuilder::GetTexParamSwizzle(nextTexture->config(), this->glCaps()),
|
||||
sizeof(newTexParams.fSwizzleRGBA));
|
||||
if (setAll || newTexParams.fFilter != oldTexParams.fFilter) {
|
||||
this->setTextureUnit(stage);
|
||||
|
|
|
@ -708,7 +708,6 @@ void GrGpuGL::buildProgram(bool isPoints,
|
|||
// FIXME: Still assuming one texture per custom stage
|
||||
const GrCustomStage* customStage = drawState.getSampler(s).getCustomStage();
|
||||
const GrGLTexture* texture = static_cast<const GrGLTexture*>(customStage->texture(0));
|
||||
stage.fInConfigFlags = 0;
|
||||
if (NULL != texture) {
|
||||
// We call this helper function rather then simply checking the client-specified
|
||||
// texture matrix. This is because we may have to concat a y-inversion to account
|
||||
|
@ -718,13 +717,6 @@ void GrGpuGL::buildProgram(bool isPoints,
|
|||
} else if (!sampler.getMatrix().hasPerspective()) {
|
||||
stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
|
||||
}
|
||||
if (!this->glCaps().textureSwizzleSupport()) {
|
||||
if (GrPixelConfigIsAlphaOnly(texture->config())) {
|
||||
// If we don't have texture swizzle support then the shader must smear the
|
||||
// single channel after reading the texture.
|
||||
stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup_custom_stage(&stage, sampler, this->glCaps(), customStages,
|
||||
|
@ -732,7 +724,6 @@ void GrGpuGL::buildProgram(bool isPoints,
|
|||
|
||||
} else {
|
||||
stage.fOptFlags = 0;
|
||||
stage.fInConfigFlags = 0;
|
||||
stage.fCustomStageKey = 0;
|
||||
customStages[s] = NULL;
|
||||
}
|
||||
|
|
|
@ -75,10 +75,6 @@ bool GrGpuGL::programUnitTest() {
|
|||
0,
|
||||
StageDesc::kNoPerspective_OptFlagBit,
|
||||
};
|
||||
static const int IN_CONFIG_FLAGS[] = {
|
||||
StageDesc::kNone_InConfigFlag,
|
||||
StageDesc::kSmearAlpha_InConfigFlag,
|
||||
};
|
||||
|
||||
static const int NUM_TESTS = 512;
|
||||
|
||||
|
@ -152,7 +148,6 @@ bool GrGpuGL::programUnitTest() {
|
|||
stage.fCustomStageKey = 0;
|
||||
|
||||
stage.fOptFlags |= STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))];
|
||||
stage.fInConfigFlags = IN_CONFIG_FLAGS[random_int(&random, GR_ARRAY_COUNT(IN_CONFIG_FLAGS))];
|
||||
|
||||
if (stage.isEnabled()) {
|
||||
GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
|
||||
|
|
Загрузка…
Ссылка в новой задаче