Introduction of set of functions to manage generation of texture fetch shader code.
A new set of routines have been added to GrGLShaderBuilder to emit texture fetches, taking into consideration the format of the texture to be accessed, and the channel swizzle. Review URL: https://codereview.appspot.com/6446072 git-svn-id: http://skia.googlecode.com/svn/trunk@4919 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
eb7ad4a8b9
commit
a5e65ec434
@ -14,6 +14,27 @@
|
||||
|
||||
class GrContext;
|
||||
class GrTexture;
|
||||
class SkString;
|
||||
|
||||
/** A class representing the swizzle access pattern for a texture.
|
||||
*/
|
||||
class GrTextureAccess {
|
||||
public:
|
||||
typedef char Swizzle[4];
|
||||
|
||||
GrTextureAccess(const GrTexture* texture, const SkString& swizzle);
|
||||
|
||||
const GrTexture* getTexture() const { return fTexture; }
|
||||
const Swizzle& getSwizzle() const { return fSwizzle; }
|
||||
|
||||
bool referencesAlpha() const {
|
||||
return fSwizzle[0] == 'a' || fSwizzle[1] == 'a' || fSwizzle[2] == 'a' || fSwizzle[3] == 'a';
|
||||
}
|
||||
|
||||
private:
|
||||
const GrTexture* fTexture;
|
||||
Swizzle fSwizzle;
|
||||
};
|
||||
|
||||
/** Provides custom vertex shader, fragment shader, uniform data for a
|
||||
particular stage of the Ganesh shading pipeline.
|
||||
@ -74,13 +95,17 @@ public:
|
||||
*/
|
||||
virtual bool isEqual(const GrCustomStage&) const;
|
||||
|
||||
/** Human-meaningful string to identify this effect; may be embedded
|
||||
in generated shader code. */
|
||||
/** Human-meaningful string to identify this effect; may be embedded
|
||||
in generated shader code. */
|
||||
const char* name() const { return this->getFactory().name(); }
|
||||
|
||||
virtual unsigned int numTextures() const;
|
||||
virtual GrTexture* texture(unsigned int index) const;
|
||||
|
||||
/** Returns the access pattern for the texture at index. Returns NULL if index is
|
||||
unused. */
|
||||
virtual const GrTextureAccess* textureAccess(unsigned int index) const;
|
||||
|
||||
void* operator new(size_t size);
|
||||
void operator delete(void* target);
|
||||
|
||||
|
@ -19,15 +19,18 @@
|
||||
|
||||
class GrCustomStage;
|
||||
class GrGLProgramStage;
|
||||
class GrGLCaps;
|
||||
|
||||
class GrProgramStageFactory : public GrNoncopyable {
|
||||
public:
|
||||
typedef uint16_t StageKey;
|
||||
typedef uint32_t StageKey;
|
||||
enum {
|
||||
kProgramStageKeyBits = 10,
|
||||
kTexturingStageKeyBits = 6
|
||||
};
|
||||
|
||||
virtual StageKey glStageKey(const GrCustomStage& stage) const = 0;
|
||||
virtual StageKey glStageKey(const GrCustomStage& stage,
|
||||
const GrGLCaps& caps ) const = 0;
|
||||
virtual GrGLProgramStage* createGLInstance(
|
||||
const GrCustomStage& stage) const = 0;
|
||||
|
||||
@ -68,7 +71,7 @@ template <typename StageClass>
|
||||
class GrTProgramStageFactory : public GrProgramStageFactory {
|
||||
|
||||
public:
|
||||
typedef typename StageClass::GLProgramStage GLProgramStage;
|
||||
typedef typename StageClass::GLProgramStage GLProgramStage;
|
||||
|
||||
/** Returns a human-readable name that is accessible via GrCustomStage or
|
||||
GrGLProgramStage and is consistent between the two of them.
|
||||
@ -80,20 +83,26 @@ public:
|
||||
id identifies the GrCustomShader subclass. The remainder is based
|
||||
on the aspects of the GrCustomStage object's configuration that affect
|
||||
GLSL code generation. */
|
||||
virtual StageKey glStageKey(const GrCustomStage& stage) const SK_OVERRIDE {
|
||||
virtual StageKey glStageKey(const GrCustomStage& stage,
|
||||
const GrGLCaps& caps) const SK_OVERRIDE {
|
||||
GrAssert(kIllegalStageClassID != fStageClassID);
|
||||
StageKey stageID = GLProgramStage::GenKey(stage);
|
||||
StageKey stageID = GLProgramStage::GenKey(stage, caps);
|
||||
StageKey textureKey = GLProgramStage::GenTextureKey(stage, caps);
|
||||
#if GR_DEBUG
|
||||
static const StageKey kIllegalIDMask =
|
||||
(uint16_t) (~((1U << kProgramStageKeyBits) - 1));
|
||||
GrAssert(!(kIllegalIDMask & stageID));
|
||||
|
||||
static const StageKey kIllegalTextureKeyMask =
|
||||
(uint16_t) (~((1U << kTexturingStageKeyBits) - 1));
|
||||
GrAssert(!(kIllegalTextureKeyMask & textureKey));
|
||||
#endif
|
||||
return fStageClassID | stageID;
|
||||
return fStageClassID | (textureKey << kProgramStageKeyBits) | stageID;
|
||||
}
|
||||
|
||||
/** Returns a new instance of the appropriate *GL* implementation class
|
||||
for the given GrCustomStage; caller is responsible for deleting
|
||||
the object. */
|
||||
for the given GrCustomStage; caller is responsible for deleting
|
||||
the object. */
|
||||
virtual GLProgramStage* createGLInstance(
|
||||
const GrCustomStage& stage) const SK_OVERRIDE {
|
||||
return SkNEW_ARGS(GLProgramStage, (*this, stage));
|
||||
@ -113,7 +122,7 @@ public:
|
||||
|
||||
protected:
|
||||
GrTProgramStageFactory() {
|
||||
fStageClassID = GenID() << kProgramStageKeyBits;
|
||||
fStageClassID = GenID() << (kProgramStageKeyBits + kTexturingStageKeyBits) ;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -918,7 +918,7 @@ public:
|
||||
|
||||
virtual void emitLightFunc(const GrGLShaderBuilder*, SkString* funcs) = 0;
|
||||
|
||||
static inline StageKey GenKey(const GrCustomStage& s);
|
||||
static inline StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps);
|
||||
|
||||
virtual void setData(const GrGLUniformManager&,
|
||||
const GrCustomStage&,
|
||||
@ -1086,8 +1086,8 @@ vec3 interiorNormal(float m[9], float surfaceScale) {\n\
|
||||
code->appendf(")%s;\n", builder->fModulate.c_str());
|
||||
}
|
||||
|
||||
GrGLProgramStage::StageKey GrGLLightingEffect::GenKey(
|
||||
const GrCustomStage& s) {
|
||||
GrGLProgramStage::StageKey GrGLLightingEffect::GenKey(const GrCustomStage& s,
|
||||
const GrGLCaps& caps) {
|
||||
return static_cast<const GrLightingEffect&>(s).light()->type();
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@ public:
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const char* samplerName) SK_OVERRIDE;
|
||||
static StageKey GenKey(const GrCustomStage& s) { return 0; }
|
||||
static StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps) { return 0; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -487,7 +487,7 @@ public:
|
||||
const char* inputColor,
|
||||
const char* samplerName) SK_OVERRIDE;
|
||||
|
||||
static StageKey GenKey(const GrCustomStage& s) { return 0; }
|
||||
static StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps) { return 0; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -396,7 +396,7 @@ public:
|
||||
const char* inputColor,
|
||||
const char* samplerName) SK_OVERRIDE;
|
||||
|
||||
static StageKey GenKey(const GrCustomStage& s) { return 0; }
|
||||
static StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps) { return 0; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -340,7 +340,7 @@ public:
|
||||
const GrRenderTarget*,
|
||||
int stageNum) SK_OVERRIDE;
|
||||
|
||||
static StageKey GenKey(const GrCustomStage& s);
|
||||
static StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps);
|
||||
|
||||
protected:
|
||||
|
||||
@ -636,7 +636,7 @@ void GrGLConical2Gradient::setData(const GrGLUniformManager& uman,
|
||||
}
|
||||
}
|
||||
|
||||
GrCustomStage::StageKey GrGLConical2Gradient::GenKey(const GrCustomStage& s) {
|
||||
GrCustomStage::StageKey GrGLConical2Gradient::GenKey(const GrCustomStage& s, const GrGLCaps& caps) {
|
||||
return (static_cast<const GrConical2Gradient&>(s).isDegenerate());
|
||||
}
|
||||
|
||||
@ -669,4 +669,4 @@ GrCustomStage* SkTwoPointConicalGradient::asNewCustomStage(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -373,7 +373,7 @@ public:
|
||||
const GrRenderTarget*,
|
||||
int stageNum) SK_OVERRIDE;
|
||||
|
||||
static StageKey GenKey(const GrCustomStage& s);
|
||||
static StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps);
|
||||
|
||||
protected:
|
||||
|
||||
@ -608,7 +608,7 @@ void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman,
|
||||
}
|
||||
}
|
||||
|
||||
GrCustomStage::StageKey GrGLRadial2Gradient::GenKey(const GrCustomStage& s) {
|
||||
GrCustomStage::StageKey GrGLRadial2Gradient::GenKey(const GrCustomStage& s, const GrGLCaps& caps) {
|
||||
return (static_cast<const GrRadial2Gradient&>(s).isDegenerate());
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "GrContext.h"
|
||||
#include "GrCustomStage.h"
|
||||
#include "GrMemoryPool.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTLS.h"
|
||||
|
||||
SK_DEFINE_INST_COUNT(GrCustomStage)
|
||||
@ -31,6 +32,17 @@ private:
|
||||
int32_t GrProgramStageFactory::fCurrStageClassID =
|
||||
GrProgramStageFactory::kIllegalStageClassID;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
GrCustomStage::GrCustomStage() {
|
||||
|
||||
}
|
||||
@ -63,6 +75,10 @@ GrTexture* GrCustomStage::texture(unsigned int index) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const GrTextureAccess* GrCustomStage::textureAccess(unsigned int index) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * GrCustomStage::operator new(size_t size) {
|
||||
return GrCustomStage_Globals::GetTLS()->allocate(size);
|
||||
}
|
||||
@ -70,4 +86,3 @@ void * GrCustomStage::operator new(size_t size) {
|
||||
void GrCustomStage::operator delete(void* target) {
|
||||
GrCustomStage_Globals::GetTLS()->release(target);
|
||||
}
|
||||
|
||||
|
@ -30,49 +30,72 @@ public:
|
||||
const GrRenderTarget*,
|
||||
int stageNum) SK_OVERRIDE {}
|
||||
|
||||
static inline StageKey GenKey(const GrCustomStage&);
|
||||
static StageKey GenKey(const GrCustomStage&, const GrGLCaps&);
|
||||
|
||||
private:
|
||||
|
||||
const GrCustomStage& fCustomStage;
|
||||
|
||||
typedef GrGLProgramStage INHERITED;
|
||||
};
|
||||
|
||||
GrGLColorTableEffect::GrGLColorTableEffect(
|
||||
const GrProgramStageFactory& factory, const GrCustomStage& stage)
|
||||
: INHERITED(factory) {
|
||||
: INHERITED(factory)
|
||||
, fCustomStage(stage) {
|
||||
}
|
||||
|
||||
void GrGLColorTableEffect::emitFS(GrGLShaderBuilder* state,
|
||||
void GrGLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const char* samplerName) {
|
||||
static const float kColorScaleFactor = 255.0f / 256.0f;
|
||||
static const float kColorOffsetFactor = 1.0f / 512.0f;
|
||||
SkString* code = &state->fFSCode;
|
||||
SkString* code = &builder->fFSCode;
|
||||
code->appendf("\t\tvec4 coord = vec4(%s.rgb / %s.a, %s.a);\n",
|
||||
inputColor, inputColor, inputColor);
|
||||
code->appendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
|
||||
kColorScaleFactor,
|
||||
kColorOffsetFactor, kColorOffsetFactor, kColorOffsetFactor, kColorOffsetFactor);
|
||||
code->appendf("\t\t%s.a = texture2D(%s, vec2(coord.a, 0.125)).a;\n",
|
||||
outputColor, samplerName);
|
||||
code->appendf("\t\t%s.r = texture2D(%s, vec2(coord.r, 0.375)).a;\n",
|
||||
outputColor, samplerName);
|
||||
code->appendf("\t\t%s.g = texture2D(%s, vec2(coord.g, 0.625)).a;\n",
|
||||
outputColor, samplerName);
|
||||
code->appendf("\t\t%s.b = texture2D(%s, vec2(coord.b, 0.875)).a;\n",
|
||||
outputColor, samplerName);
|
||||
|
||||
const GrTextureAccess& access = *fCustomStage.textureAccess(0);
|
||||
code->appendf("\t\t%s.a = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
samplerName,
|
||||
"vec2(coord.a, 0.125)");
|
||||
|
||||
code->appendf("\t\t%s.r = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
samplerName,
|
||||
"vec2(coord.r, 0.375)");
|
||||
|
||||
code->appendf("\t\t%s.g = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
samplerName,
|
||||
"vec2(coord.g, 0.625)");
|
||||
|
||||
code->appendf("\t\t%s.b = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
samplerName,
|
||||
"vec2(coord.b, 0.875)");
|
||||
|
||||
code->appendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
|
||||
}
|
||||
|
||||
GrGLProgramStage::StageKey GrGLColorTableEffect::GenKey(
|
||||
const GrCustomStage& s) {
|
||||
GrGLProgramStage::StageKey GrGLColorTableEffect::GenKey(const GrCustomStage& s,
|
||||
const GrGLCaps& caps) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrColorTableEffect::GrColorTableEffect(GrTexture* texture)
|
||||
: INHERITED(texture) {
|
||||
: INHERITED(texture)
|
||||
, fTextureAccess(texture, SkString("a")) {
|
||||
}
|
||||
|
||||
GrColorTableEffect::~GrColorTableEffect() {
|
||||
@ -85,3 +108,10 @@ const GrProgramStageFactory& GrColorTableEffect::getFactory() const {
|
||||
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;
|
||||
}
|
||||
|
@ -29,10 +29,14 @@ 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;
|
||||
|
||||
typedef GrGLColorTableEffect GLProgramStage;
|
||||
|
||||
private:
|
||||
|
||||
GrTextureAccess fTextureAccess;
|
||||
|
||||
typedef GrSingleTextureEffect INHERITED;
|
||||
};
|
||||
#endif
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
const GrRenderTarget*,
|
||||
int stageNum) SK_OVERRIDE;
|
||||
|
||||
static inline StageKey GenKey(const GrCustomStage&);
|
||||
static inline StageKey GenKey(const GrCustomStage&, const GrGLCaps&);
|
||||
|
||||
private:
|
||||
int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); }
|
||||
@ -125,8 +125,8 @@ void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman,
|
||||
uman.set1fv(fKernelUni, 0, this->width(), conv.kernel());
|
||||
}
|
||||
|
||||
GrGLProgramStage::StageKey GrGLConvolutionEffect::GenKey(
|
||||
const GrCustomStage& s) {
|
||||
GrGLProgramStage::StageKey GrGLConvolutionEffect::GenKey(const GrCustomStage& s,
|
||||
const GrGLCaps& caps) {
|
||||
return static_cast<const GrConvolutionEffect&>(s).radius();
|
||||
}
|
||||
|
||||
@ -185,4 +185,3 @@ bool GrConvolutionEffect::isEqual(const GrCustomStage& sBase) const {
|
||||
this->direction() == s.direction() &&
|
||||
0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
const char* inputColor,
|
||||
const char* samplerName) SK_OVERRIDE;
|
||||
|
||||
static inline StageKey GenKey(const GrCustomStage& s);
|
||||
static inline StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps);
|
||||
|
||||
virtual void setData(const GrGLUniformManager&,
|
||||
const GrCustomStage&,
|
||||
@ -98,8 +98,8 @@ void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* builder,
|
||||
code->appendf("\t\t%s = value%s;\n", outputColor, builder->fModulate.c_str());
|
||||
}
|
||||
|
||||
GrGLProgramStage::StageKey GrGLMorphologyEffect::GenKey(
|
||||
const GrCustomStage& s) {
|
||||
GrGLProgramStage::StageKey GrGLMorphologyEffect::GenKey(const GrCustomStage& s,
|
||||
const GrGLCaps& caps) {
|
||||
const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(s);
|
||||
StageKey key = static_cast<StageKey>(m.radius());
|
||||
key |= (m.type() << 8);
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
builder->emitDefaultFetch(outputColor, samplerName);
|
||||
}
|
||||
|
||||
static inline StageKey GenKey(const GrCustomStage&) { return 0; }
|
||||
static inline StageKey GenKey(const GrCustomStage&, const GrGLCaps&) { return 0; }
|
||||
|
||||
private:
|
||||
|
||||
@ -56,5 +56,3 @@ GrTexture* GrSingleTextureEffect::texture(unsigned int index) const {
|
||||
const GrProgramStageFactory& GrSingleTextureEffect::getFactory() const {
|
||||
return GrTProgramStageFactory<GrSingleTextureEffect>::getInstance();
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
const GrRenderTarget*,
|
||||
int stageNum) SK_OVERRIDE;
|
||||
|
||||
static inline StageKey GenKey(const GrCustomStage&) { return 0; }
|
||||
static inline StageKey GenKey(const GrCustomStage&, const GrGLCaps&) { return 0; }
|
||||
|
||||
private:
|
||||
GrGLUniformManager::UniformHandle fNameUni;
|
||||
@ -107,5 +107,3 @@ bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
|
||||
const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
|
||||
return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,7 +164,7 @@ public:
|
||||
|
||||
/** Non-zero if user-supplied code will write the stage's
|
||||
contribution to the fragment shader. */
|
||||
uint16_t fCustomStageKey;
|
||||
GrProgramStageFactory::StageKey fCustomStageKey;
|
||||
|
||||
GR_STATIC_ASSERT((InConfigFlags)(uint8_t)kInConfigBitMask ==
|
||||
kInConfigBitMask);
|
||||
|
@ -27,3 +27,14 @@ void GrGLProgramStage::setData(const GrGLUniformManager&,
|
||||
int stageNum) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
@ -78,6 +78,8 @@ public:
|
||||
|
||||
const char* name() const { return fFactory.name(); }
|
||||
|
||||
static StageKey GenTextureKey(const GrCustomStage&, const GrGLCaps&);
|
||||
|
||||
protected:
|
||||
|
||||
const GrProgramStageFactory& fFactory;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "gl/GrGLShaderBuilder.h"
|
||||
#include "gl/GrGLProgram.h"
|
||||
#include "gl/GrGLUniformHandle.h"
|
||||
#include "GrTexture.h"
|
||||
|
||||
// number of each input/output type in a single allocation block
|
||||
static const int kVarsPerBlock = 8;
|
||||
@ -21,6 +22,50 @@ static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
|
||||
typedef GrGLUniformManager::UniformHandle UniformHandle;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkString build_sampler_string(GrGLShaderBuilder::SamplerMode samplerMode) {
|
||||
SkString sampler("texture2D");
|
||||
switch (samplerMode) {
|
||||
case GrGLShaderBuilder::kDefault_SamplerMode:
|
||||
break;
|
||||
case GrGLShaderBuilder::kProj_SamplerMode:
|
||||
sampler.append("Proj");
|
||||
break;
|
||||
case GrGLShaderBuilder::kExplicitDivide_SamplerMode:
|
||||
GrAssert(false); // Not Implemented
|
||||
break;
|
||||
}
|
||||
|
||||
return sampler;
|
||||
}
|
||||
|
||||
static bool texture_requires_alpha_to_red_swizzle(const GrGLCaps& caps,
|
||||
const GrTextureAccess& access) {
|
||||
return GrPixelConfigIsAlphaOnly(access.getTexture()->config()) && caps.textureRedSupport() &&
|
||||
access.referencesAlpha();
|
||||
}
|
||||
|
||||
static 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]);
|
||||
}
|
||||
}
|
||||
|
||||
return swizzleOut;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Architectural assumption: always 2-d input coords.
|
||||
// Likely to become non-constant and non-static, perhaps even
|
||||
// varying by stage, if we use 1D textures for gradients!
|
||||
@ -120,6 +165,34 @@ void GrGLShaderBuilder::emitDefaultFetch(const char* outColor,
|
||||
fFSCode.appendf("%s%s;\n", fSwizzle.c_str(), fModulate.c_str());
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::emitCustomTextureLookup(SamplerMode samplerMode,
|
||||
const GrTextureAccess& textureAccess,
|
||||
const char* samplerName,
|
||||
const char* coordName) {
|
||||
GrAssert(samplerName && coordName);
|
||||
SkString sampler = build_sampler_string(samplerMode);
|
||||
SkString swizzle = build_swizzle_string(textureAccess, fContext.caps());
|
||||
|
||||
fFSCode.appendf("%s( %s, %s)%s;\n", sampler.c_str(), samplerName,
|
||||
coordName, swizzle.c_str());
|
||||
}
|
||||
|
||||
GrCustomStage::StageKey GrGLShaderBuilder::KeyForTextureAccess(const GrTextureAccess& access,
|
||||
const GrGLCaps& caps) {
|
||||
GrCustomStage::StageKey key = 0;
|
||||
// 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)) {
|
||||
key = 1;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t visibility,
|
||||
GrSLType type,
|
||||
const char* name,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define GrGLShaderBuilder_DEFINED
|
||||
|
||||
#include "GrAllocator.h"
|
||||
#include "GrCustomStage.h"
|
||||
#include "gl/GrGLShaderVar.h"
|
||||
#include "gl/GrGLSL.h"
|
||||
#include "gl/GrGLUniformManager.h"
|
||||
@ -55,6 +56,22 @@ public:
|
||||
void emitDefaultFetch(const char* outColor,
|
||||
const char* samplerName);
|
||||
|
||||
/** Emits a texture lookup to the shader code with the form:
|
||||
texture2D{Proj}(samplerName, coordName).swizzle
|
||||
The routine selects the type of texturing based on samplerMode.
|
||||
The generated swizzle state is built based on the format of the texture and the requested
|
||||
swizzle access pattern. */
|
||||
void emitCustomTextureLookup(SamplerMode samplerMode,
|
||||
const GrTextureAccess& textureAccess,
|
||||
const char* samplerName,
|
||||
const char* coordName);
|
||||
|
||||
/** Generates a StageKey for the shader code based on the texture access parameters and the
|
||||
capabilities of the GL context. This is useful for keying the shader programs that may
|
||||
have multiple representations, based on the type/format of textures used. */
|
||||
static GrCustomStage::StageKey KeyForTextureAccess(const GrTextureAccess& access,
|
||||
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
|
||||
|
@ -596,12 +596,13 @@ namespace {
|
||||
|
||||
void setup_custom_stage(GrGLProgram::Desc::StageDesc* stage,
|
||||
const GrSamplerState& sampler,
|
||||
const GrGLCaps& caps,
|
||||
const GrCustomStage** customStages,
|
||||
GrGLProgram* program, int index) {
|
||||
const GrCustomStage* customStage = sampler.getCustomStage();
|
||||
if (customStage) {
|
||||
const GrProgramStageFactory& factory = customStage->getFactory();
|
||||
stage->fCustomStageKey = factory.glStageKey(*customStage);
|
||||
stage->fCustomStageKey = factory.glStageKey(*customStage, caps);
|
||||
customStages[index] = customStage;
|
||||
} else {
|
||||
stage->fCustomStageKey = 0;
|
||||
@ -746,7 +747,8 @@ void GrGpuGL::buildProgram(bool isPoints,
|
||||
}
|
||||
}
|
||||
|
||||
setup_custom_stage(&stage, sampler, customStages, fCurrentProgram.get(), s);
|
||||
setup_custom_stage(&stage, sampler, this->glCaps(), customStages,
|
||||
fCurrentProgram.get(), s);
|
||||
|
||||
} else {
|
||||
stage.fOptFlags = 0;
|
||||
|
@ -413,7 +413,7 @@ bool GrGpuGL::programUnitTest() {
|
||||
customStages[s].reset(create_random_effect(&stage, &random, getContext()));
|
||||
if (NULL != customStages[s]) {
|
||||
stage.fCustomStageKey =
|
||||
customStages[s]->getFactory().glStageKey(*customStages[s]);
|
||||
customStages[s]->getFactory().glStageKey(*customStages[s], this->glCaps());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user