Remove default texture coords / texture matrix

Review URL: https://codereview.appspot.com/6775100

git-svn-id: http://skia.googlecode.com/svn/trunk@6293 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-11-05 16:36:02 +00:00
parent 4187a2fc71
commit dbe49f7354
24 changed files with 44 additions and 362 deletions

View File

@ -32,6 +32,7 @@ class GrBackendEffectFactory : public GrNoncopyable {
public: public:
typedef uint32_t EffectKey; typedef uint32_t EffectKey;
enum { enum {
kNoEffectKey = 0,
kEffectKeyBits = 12, kEffectKeyBits = 12,
/** /**
* Some aspects of the generated code may be determined by the particular textures that are * Some aspects of the generated code may be determined by the particular textures that are

View File

@ -47,7 +47,7 @@ public:
return false; return false;
} }
return fMatrix == other.fMatrix && fCoordChangeMatrix == other.fCoordChangeMatrix; return fCoordChangeMatrix == other.fCoordChangeMatrix;
} }
bool operator !=(const GrEffectStage& s) const { return !(*this == s); } bool operator !=(const GrEffectStage& s) const { return !(*this == s); }
@ -55,7 +55,6 @@ public:
GrEffectStage& operator =(const GrEffectStage& other) { GrEffectStage& operator =(const GrEffectStage& other) {
GrSafeAssign(fEffect, other.fEffect); GrSafeAssign(fEffect, other.fEffect);
if (NULL != fEffect) { if (NULL != fEffect) {
fMatrix = other.fMatrix;
fCoordChangeMatrix = other.fCoordChangeMatrix; fCoordChangeMatrix = other.fCoordChangeMatrix;
} }
return *this; return *this;
@ -100,20 +99,6 @@ public:
GR_DEBUGCODE(savedCoordChange.fEffect.reset(NULL);) GR_DEBUGCODE(savedCoordChange.fEffect.reset(NULL);)
} }
/**
* Gets the texture matrix. This is will be removed soon and be managed by GrEffect.
*/
const SkMatrix& getMatrix() const { return fMatrix; }
/**
* Gets the matrix to apply at draw time. This is the original texture matrix combined with
* any coord system changes. This will be removed when the matrix is managed by GrEffect.
*/
void getTotalMatrix(SkMatrix* matrix) const {
*matrix = fMatrix;
matrix->preConcat(fCoordChangeMatrix);
}
/** /**
* Gets the matrix representing all changes of coordinate system since the GrEffect was * Gets the matrix representing all changes of coordinate system since the GrEffect was
* installed in the stage. * installed in the stage.
@ -127,15 +112,6 @@ public:
const GrEffect* setEffect(const GrEffect* effect) { const GrEffect* setEffect(const GrEffect* effect) {
GrAssert(0 == fSavedCoordChangeCnt); GrAssert(0 == fSavedCoordChangeCnt);
GrSafeAssign(fEffect, effect); GrSafeAssign(fEffect, effect);
fMatrix.reset();
fCoordChangeMatrix.reset();
return effect;
}
const GrEffect* setEffect(const GrEffect* effect, const SkMatrix& matrix) {
GrAssert(0 == fSavedCoordChangeCnt);
GrSafeAssign(fEffect, effect);
fMatrix = matrix;
fCoordChangeMatrix.reset(); fCoordChangeMatrix.reset();
return effect; return effect;
} }
@ -144,7 +120,6 @@ public:
private: private:
SkMatrix fCoordChangeMatrix; SkMatrix fCoordChangeMatrix;
SkMatrix fMatrix; // TODO: remove this, store in GrEffect
const GrEffect* fEffect; const GrEffect* fEffect;
GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;) GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;)

View File

@ -14,6 +14,7 @@
#include "SkGrPixelRef.h" #include "SkGrPixelRef.h"
#include "gl/GrGLEffect.h" #include "gl/GrGLEffect.h"
#include "gl/GrGLEffectMatrix.h" #include "gl/GrGLEffectMatrix.h"
#include "effects/GrSingleTextureEffect.h"
#include "GrTBackendEffectFactory.h" #include "GrTBackendEffectFactory.h"
#endif #endif
@ -246,7 +247,6 @@ GrGLBlendEffect::GrGLBlendEffect(const GrBackendEffectFactory& factory,
const GrEffect& effect) const GrEffect& effect)
: INHERITED(factory), : INHERITED(factory),
fMode(static_cast<const GrBlendEffect&>(effect).mode()) { fMode(static_cast<const GrBlendEffect&>(effect).mode()) {
fRequiresTextureMatrix = false;
} }
GrGLBlendEffect::~GrGLBlendEffect() { GrGLBlendEffect::~GrGLBlendEffect() {

View File

@ -349,10 +349,7 @@ public:
const GrEffect& effect) const GrEffect& effect)
: INHERITED(factory) : INHERITED(factory)
, fMatrixHandle(GrGLUniformManager::kInvalidUniformHandle) , fMatrixHandle(GrGLUniformManager::kInvalidUniformHandle)
, fVectorHandle(GrGLUniformManager::kInvalidUniformHandle) { , fVectorHandle(GrGLUniformManager::kInvalidUniformHandle) {}
// no texture
fRequiresTextureMatrix = false;
}
virtual void emitCode(GrGLShaderBuilder* builder, virtual void emitCode(GrGLShaderBuilder* builder,
const GrEffectStage&, const GrEffectStage&,

View File

@ -1067,7 +1067,6 @@ GrGLLightingEffect::GrGLLightingEffect(const GrBackendEffectFactory& factory,
, fSurfaceScaleUni(kInvalidUniformHandle) { , fSurfaceScaleUni(kInvalidUniformHandle) {
const GrLightingEffect& m = static_cast<const GrLightingEffect&>(effect); const GrLightingEffect& m = static_cast<const GrLightingEffect&>(effect);
fLight = m.light()->createGLLight(); fLight = m.light()->createGLLight();
fRequiresTextureMatrix = false;
} }
GrGLLightingEffect::~GrGLLightingEffect() { GrGLLightingEffect::~GrGLLightingEffect() {

View File

@ -107,7 +107,6 @@ GrGLMagnifierEffect::GrGLMagnifierEffect(const GrBackendEffectFactory& factory,
, fOffsetVar(GrGLUniformManager::kInvalidUniformHandle) , fOffsetVar(GrGLUniformManager::kInvalidUniformHandle)
, fZoomVar(GrGLUniformManager::kInvalidUniformHandle) , fZoomVar(GrGLUniformManager::kInvalidUniformHandle)
, fInsetVar(GrGLUniformManager::kInvalidUniformHandle) { , fInsetVar(GrGLUniformManager::kInvalidUniformHandle) {
fRequiresTextureMatrix = false;
} }
void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder, void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,

View File

@ -15,6 +15,7 @@
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
#include "gl/GrGLEffect.h" #include "gl/GrGLEffect.h"
#include "gl/GrGLEffectMatrix.h" #include "gl/GrGLEffectMatrix.h"
#include "effects/GrSingleTextureEffect.h"
#include "GrTBackendEffectFactory.h" #include "GrTBackendEffectFactory.h"
#include "GrTexture.h" #include "GrTexture.h"
#include "SkMatrix.h" #include "SkMatrix.h"
@ -330,7 +331,6 @@ GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa
fKernelSize = m.kernelSize(); fKernelSize = m.kernelSize();
fTileMode = m.tileMode(); fTileMode = m.tileMode();
fConvolveAlpha = m.convolveAlpha(); fConvolveAlpha = m.convolveAlpha();
fRequiresTextureMatrix = false;
} }
static void appendTextureLookup(GrGLShaderBuilder* builder, static void appendTextureLookup(GrGLShaderBuilder* builder,

View File

@ -302,7 +302,6 @@ GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendEffectFactory& factory
const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(effect); const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(effect);
fRadius = m.radius(); fRadius = m.radius();
fType = m.type(); fType = m.type();
fRequiresTextureMatrix = false;
} }
void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder, void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,

View File

@ -270,8 +270,6 @@ private:
GLColorTableEffect::GLColorTableEffect( GLColorTableEffect::GLColorTableEffect(
const GrBackendEffectFactory& factory, const GrEffect& effect) const GrBackendEffectFactory& factory, const GrEffect& effect)
: INHERITED(factory) { : INHERITED(factory) {
// texture coords are computed from the incoming color.
fRequiresTextureMatrix = false;
} }
void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder, void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,

View File

@ -679,7 +679,6 @@ GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
: INHERITED(factory) : INHERITED(factory)
, fCachedYCoord(SK_ScalarMax) , fCachedYCoord(SK_ScalarMax)
, fFSYUni(GrGLUniformManager::kInvalidUniformHandle) { , fFSYUni(GrGLUniformManager::kInvalidUniformHandle) {
fRequiresTextureMatrix = false;
} }
GrGLGradientEffect::~GrGLGradientEffect() { } GrGLGradientEffect::~GrGLGradientEffect() { }

View File

@ -1456,10 +1456,8 @@ void apply_effect(GrContext* context,
GrContext::AutoRenderTarget art(context, dstTexture->asRenderTarget()); GrContext::AutoRenderTarget art(context, dstTexture->asRenderTarget());
GrContext::AutoClip acs(context, rect); GrContext::AutoClip acs(context, rect);
SkMatrix sampleM;
sampleM.setIDiv(srcTexture->width(), srcTexture->height());
GrPaint paint; GrPaint paint;
paint.colorStage(0)->setEffect(effect, sampleM); paint.colorStage(0)->setEffect(effect);
context->drawRect(paint, rect); context->drawRect(paint, rect);
} }

View File

@ -19,7 +19,6 @@ public:
const GrConfigConversionEffect& effect = static_cast<const GrConfigConversionEffect&>(s); const GrConfigConversionEffect& effect = static_cast<const GrConfigConversionEffect&>(s);
fSwapRedAndBlue = effect.swapsRedAndBlue(); fSwapRedAndBlue = effect.swapsRedAndBlue();
fPMConversion = effect.pmConversion(); fPMConversion = effect.pmConversion();
fRequiresTextureMatrix = false;
} }
virtual void emitCode(GrGLShaderBuilder* builder, virtual void emitCode(GrGLShaderBuilder* builder,
@ -261,7 +260,7 @@ bool GrConfigConversionEffect::InstallEffect(GrTexture* texture,
// If we returned a GrConfigConversionEffect that was equivalent to a GrSingleTextureEffect // If we returned a GrConfigConversionEffect that was equivalent to a GrSingleTextureEffect
// then we may pollute our texture cache with redundant shaders. So in the case that no // then we may pollute our texture cache with redundant shaders. So in the case that no
// conversions were requested we instead return a GrSingleTextureEffect. // conversions were requested we instead return a GrSingleTextureEffect.
stage->setEffect(SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix)), matrix)->unref(); stage->setEffect(SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix)))->unref();
return true; return true;
} else { } else {
if (kRGBA_8888_GrPixelConfig != texture->config() && if (kRGBA_8888_GrPixelConfig != texture->config() &&

View File

@ -51,7 +51,6 @@ GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& facto
const GrConvolutionEffect& c = const GrConvolutionEffect& c =
static_cast<const GrConvolutionEffect&>(effect); static_cast<const GrConvolutionEffect&>(effect);
fRadius = c.radius(); fRadius = c.radius();
fRequiresTextureMatrix = false;
} }
void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder, void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,

View File

@ -16,9 +16,7 @@
class GrGLSingleTextureEffect : public GrGLEffect { class GrGLSingleTextureEffect : public GrGLEffect {
public: public:
GrGLSingleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&) GrGLSingleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&)
: INHERITED (factory) { : INHERITED (factory) {}
fRequiresTextureMatrix = false;
}
virtual void emitCode(GrGLShaderBuilder* builder, virtual void emitCode(GrGLShaderBuilder* builder,
const GrEffectStage&, const GrEffectStage&,

View File

@ -39,7 +39,6 @@ GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& f
const GrEffect&) const GrEffect&)
: INHERITED(factory) : INHERITED(factory)
, fNameUni(GrGLUniformManager::kInvalidUniformHandle) { , fNameUni(GrGLUniformManager::kInvalidUniformHandle) {
fRequiresTextureMatrix = false;
fPrevDomain[0] = SK_FloatNaN; fPrevDomain[0] = SK_FloatNaN;
} }

View File

@ -10,8 +10,6 @@
GrGLEffect::GrGLEffect(const GrBackendEffectFactory& factory) GrGLEffect::GrGLEffect(const GrBackendEffectFactory& factory)
: fFactory(factory) { : fFactory(factory) {
fRequiresTextureMatrix = true;
} }
GrGLEffect::~GrGLEffect() { GrGLEffect::~GrGLEffect() {

View File

@ -9,7 +9,6 @@
#define GrGLEffect_DEFINED #define GrGLEffect_DEFINED
#include "GrBackendEffectFactory.h" #include "GrBackendEffectFactory.h"
#include "GrGLProgram.h"
#include "GrGLShaderBuilder.h" #include "GrGLShaderBuilder.h"
#include "GrGLShaderVar.h" #include "GrGLShaderVar.h"
#include "GrGLSL.h" #include "GrGLSL.h"
@ -35,6 +34,7 @@ public:
typedef GrBackendEffectFactory::EffectKey EffectKey; typedef GrBackendEffectFactory::EffectKey EffectKey;
enum { enum {
kNoEffectKey = GrBackendEffectFactory::kNoEffectKey,
// the number of bits in EffectKey available to GenKey // the number of bits in EffectKey available to GenKey
kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits, kEffectKeyBits = GrBackendEffectFactory::kEffectKeyBits,
}; };
@ -54,9 +54,10 @@ public:
@param key The key that was computed by GenKey() from the generating GrEffect. @param key The key that was computed by GenKey() from the generating GrEffect.
Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are
guaranteed to match the value produced by GenKey(); guaranteed to match the value produced by GenKey();
@param vertexCoords A vec2 of texture coordinates in the VS, which may be altered. This will @param vertexCoords A vec2 in the VS that holds the position in local coords. This is either
be removed soon and stages will be responsible for computing their own the pre-view-matrix vertex position or if explicit per-vertex texture
coords. coords are used with a stage then it is those coordinates. See
GrVertexLayout.
@param outputColor A predefined vec4 in the FS in which the stage should place its output @param outputColor A predefined vec4 in the FS in which the stage should place its output
color (or coverage). color (or coverage).
@param inputColor A vec4 that holds the input color to the stage in the FS. This may be @param inputColor A vec4 that holds the input color to the stage in the FS. This may be
@ -87,15 +88,7 @@ public:
static EffectKey GenTextureKey(const GrEffect&, const GrGLCaps&); static EffectKey GenTextureKey(const GrEffect&, const GrGLCaps&);
bool requiresTextureMatrix() const { return fRequiresTextureMatrix; }
protected: protected:
// HACK: This is a temporary field that allows GrGLEffect subclasses to opt into the new
// shader gen where a texture matrix is not automatically inserted. It defaults to true and is
// set to false in a subclass to opt into the new behavior.
bool fRequiresTextureMatrix;
const GrBackendEffectFactory& fFactory; const GrBackendEffectFactory& fFactory;
}; };

View File

@ -10,7 +10,6 @@
#include "GrAllocator.h" #include "GrAllocator.h"
#include "GrEffect.h" #include "GrEffect.h"
#include "GrGLEffect.h" #include "GrGLEffect.h"
#include "gl/GrGLShaderBuilder.h"
#include "GrGLShaderVar.h" #include "GrGLShaderVar.h"
#include "GrBackendEffectFactory.h" #include "GrBackendEffectFactory.h"
#include "SkTrace.h" #include "SkTrace.h"
@ -23,8 +22,6 @@ SK_DEFINE_INST_COUNT(GrGLProgram)
#define PRINT_SHADERS 0 #define PRINT_SHADERS 0
typedef GrGLProgram::Desc::StageDesc StageDesc;
#define COL_ATTR_NAME "aColor" #define COL_ATTR_NAME "aColor"
#define COV_ATTR_NAME "aCoverage" #define COV_ATTR_NAME "aCoverage"
#define EDGE_ATTR_NAME "aEdge" #define EDGE_ATTR_NAME "aEdge"
@ -80,9 +77,6 @@ GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
for (int s = 0; s < GrDrawState::kNumStages; ++s) { for (int s = 0; s < GrDrawState::kNumStages; ++s) {
fEffects[s] = NULL; fEffects[s] = NULL;
fTextureMatrices[s] = SkMatrix::InvalidMatrix();
// this is arbitrary, just initialize to something
fTextureOrigin[s] = GrSurface::kBottomLeft_Origin;
} }
this->genProgram(stages); this->genProgram(stages);
@ -602,7 +596,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
if (needComputedColor) { if (needComputedColor) {
SkString outColor; SkString outColor;
for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) {
if (fDesc.fStages[s].isEnabled()) { if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) {
// create var to hold stage result // create var to hold stage result
outColor = "color"; outColor = "color";
outColor.appendS32(s); outColor.appendS32(s);
@ -621,7 +615,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
builder.setCurrentStage(s); builder.setCurrentStage(s);
fEffects[s] = GenStageCode(*stages[s], fEffects[s] = GenStageCode(*stages[s],
fDesc.fStages[s], fDesc.fEffectKeys[s],
&fUniforms.fStages[s], &fUniforms.fStages[s],
inColor.size() ? inColor.c_str() : NULL, inColor.size() ? inColor.c_str() : NULL,
outColor.c_str(), outColor.c_str(),
@ -698,7 +692,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
SkString outCoverage; SkString outCoverage;
const int& startStage = fDesc.fFirstCoverageStage; const int& startStage = fDesc.fFirstCoverageStage;
for (int s = startStage; s < GrDrawState::kNumStages; ++s) { for (int s = startStage; s < GrDrawState::kNumStages; ++s) {
if (fDesc.fStages[s].isEnabled()) { if (fDesc.fEffectKeys[s]) {
// create var to hold stage output // create var to hold stage output
outCoverage = "coverage"; outCoverage = "coverage";
outCoverage.appendS32(s); outCoverage.appendS32(s);
@ -726,7 +720,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
} }
builder.setCurrentStage(s); builder.setCurrentStage(s);
fEffects[s] = GenStageCode(*stages[s], fEffects[s] = GenStageCode(*stages[s],
fDesc.fStages[s], fDesc.fEffectKeys[s],
&fUniforms.fStages[s], &fUniforms.fStages[s],
inCoverage.size() ? inCoverage.c_str() : NULL, inCoverage.size() ? inCoverage.c_str() : NULL,
outCoverage.c_str(), outCoverage.c_str(),
@ -897,7 +891,7 @@ void GrGLProgram::initSamplerUniforms() {
// TODO: Move this function to GrGLShaderBuilder // TODO: Move this function to GrGLShaderBuilder
GrGLEffect* GrGLProgram::GenStageCode(const GrEffectStage& stage, GrGLEffect* GrGLProgram::GenStageCode(const GrEffectStage& stage,
const StageDesc& desc, GrGLEffect::EffectKey key,
StageUniforms* uniforms, StageUniforms* uniforms,
const char* fsInColor, // NULL means no incoming color const char* fsInColor, // NULL means no incoming color
const char* fsOutColor, const char* fsOutColor,
@ -907,51 +901,7 @@ GrGLEffect* GrGLProgram::GenStageCode(const GrEffectStage& stage,
const GrEffect* effect = stage.getEffect(); const GrEffect* effect = stage.getEffect();
GrGLEffect* glEffect = effect->getFactory().createGLInstance(*effect); GrGLEffect* glEffect = effect->getFactory().createGLInstance(*effect);
/// Vertex Shader Stuff // setup texture samplers for GL effect
const char* vertexCoords;
// Has the effect not yet been updated to insert its own texture matrix if necessary.
if (glEffect->requiresTextureMatrix()) {
// Decide whether we need a matrix to transform texture coords and whether the varying needs
// a perspective coord.
const char* matName = NULL;
GrSLType texCoordVaryingType;
if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
texCoordVaryingType = kVec2f_GrSLType;
} else {
uniforms->fTextureMatrixUni = builder->addUniform(GrGLShaderBuilder::kVertex_ShaderType,
kMat33f_GrSLType, "TexM", &matName);
builder->getUniformVariable(uniforms->fTextureMatrixUni);
if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
texCoordVaryingType = kVec2f_GrSLType;
} else {
texCoordVaryingType = kVec3f_GrSLType;
}
}
const char *varyingVSName, *varyingFSName;
builder->addVarying(texCoordVaryingType,
"Stage",
&varyingVSName,
&varyingFSName);
builder->setupTextureAccess(varyingFSName, texCoordVaryingType);
if (!matName) {
GrAssert(kVec2f_GrSLType == texCoordVaryingType);
builder->fVSCode.appendf("\t%s = %s;\n", varyingVSName, vsInCoord);
} else {
// varying = texMatrix * texCoord
builder->fVSCode.appendf("\t%s = (%s * vec3(%s, 1))%s;\n",
varyingVSName, matName, vsInCoord,
vector_all_coords(GrSLTypeToVecLength(texCoordVaryingType)));
}
vertexCoords = varyingVSName;
} else {
vertexCoords = vsInCoord;
}
// setup texture samplers for gl effect
int numTextures = effect->numTextures(); int numTextures = effect->numTextures();
SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
textureSamplers.push_back_n(numTextures); textureSamplers.push_back_n(numTextures);
@ -965,8 +915,8 @@ GrGLEffect* GrGLProgram::GenStageCode(const GrEffectStage& stage,
builder->fFSCode.appendf("\t{ // %s \n", glEffect->name()); builder->fFSCode.appendf("\t{ // %s \n", glEffect->name());
glEffect->emitCode(builder, glEffect->emitCode(builder,
stage, stage,
desc.fEffectKey, key,
vertexCoords, vsInCoord,
fsOutColor, fsOutColor,
fsInColor, fsInColor,
textureSamplers); textureSamplers);

View File

@ -10,6 +10,7 @@
#define GrGLProgram_DEFINED #define GrGLProgram_DEFINED
#include "GrDrawState.h" #include "GrDrawState.h"
#include "GrGLEffect.h"
#include "GrGLContextInfo.h" #include "GrGLContextInfo.h"
#include "GrGLSL.h" #include "GrGLSL.h"
#include "GrGLTexture.h" #include "GrGLTexture.h"
@ -73,8 +74,7 @@ public:
void setData(const GrDrawState& drawState); void setData(const GrDrawState& drawState);
// Parameters that affect code generation // Parameters that affect code generation
// These structs should be kept compact; they are the input to an // This structs should be kept compact; it is input to an expensive hash key generator.
// expensive hash key generator.
struct Desc { struct Desc {
Desc() { Desc() {
// since we use this as part of a key we can't have any uninitialized // since we use this as part of a key we can't have any uninitialized
@ -87,30 +87,6 @@ public:
return reinterpret_cast<const uint32_t*>(this); return reinterpret_cast<const uint32_t*>(this);
} }
struct StageDesc {
enum OptFlagBits {
kNoPerspective_OptFlagBit = 1 << 0,
kIdentityMatrix_OptFlagBit = 1 << 1,
kIsEnabled_OptFlagBit = 1 << 7
};
uint8_t fOptFlags;
/** Non-zero if this stage has an effect */
GrBackendEffectFactory::EffectKey fEffectKey;
inline bool isEnabled() const {
return SkToBool(fOptFlags & kIsEnabled_OptFlagBit);
}
inline void setEnabled(bool newValue) {
if (newValue) {
fOptFlags |= kIsEnabled_OptFlagBit;
} else {
fOptFlags &= ~kIsEnabled_OptFlagBit;
}
}
};
// Specifies where the initial color comes from before the stages are applied. // Specifies where the initial color comes from before the stages are applied.
enum ColorInput { enum ColorInput {
kSolidWhite_ColorInput, kSolidWhite_ColorInput,
@ -137,7 +113,8 @@ public:
// stripped of bits that don't affect program generation // stripped of bits that don't affect program generation
GrVertexLayout fVertexLayout; GrVertexLayout fVertexLayout;
StageDesc fStages[GrDrawState::kNumStages]; /** Non-zero if this stage has an effect */
GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages];
// To enable experimental geometry shader code (not for use in // To enable experimental geometry shader code (not for use in
// production) // production)
@ -155,9 +132,6 @@ public:
}; };
GR_STATIC_ASSERT(!(sizeof(Desc) % 4)); GR_STATIC_ASSERT(!(sizeof(Desc) % 4));
// for code readability
typedef Desc::StageDesc StageDesc;
private: private:
struct StageUniforms; struct StageUniforms;
@ -175,7 +149,7 @@ private:
void genInputColor(GrGLShaderBuilder* builder, SkString* inColor); void genInputColor(GrGLShaderBuilder* builder, SkString* inColor);
static GrGLEffect* GenStageCode(const GrEffectStage& stage, static GrGLEffect* GenStageCode(const GrEffectStage& stage,
const StageDesc& desc, // TODO: Eliminate this GrGLEffect::EffectKey key,
StageUniforms* stageUniforms, // TODO: Eliminate this StageUniforms* stageUniforms, // TODO: Eliminate this
const char* fsInColor, // NULL means no incoming color const char* fsInColor, // NULL means no incoming color
const char* fsOutColor, const char* fsOutColor,
@ -207,11 +181,7 @@ private:
const char* adjustInColor(const SkString& inColor) const; const char* adjustInColor(const SkString& inColor) const;
struct StageUniforms { struct StageUniforms {
UniformHandle fTextureMatrixUni;
SkTArray<UniformHandle, true> fSamplerUniforms; SkTArray<UniformHandle, true> fSamplerUniforms;
StageUniforms() {
fTextureMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
}
}; };
struct Uniforms { struct Uniforms {
@ -249,9 +219,6 @@ private:
GrColor fCoverage; GrColor fCoverage;
GrColor fColorFilterColor; GrColor fColorFilterColor;
int fRTHeight; int fRTHeight;
/// When it is sent to GL, the texture matrix will be flipped if the texture origin requires.
SkMatrix fTextureMatrices[GrDrawState::kNumStages];
GrSurface::Origin fTextureOrigin[GrDrawState::kNumStages];
GrGLEffect* fEffects[GrDrawState::kNumStages]; GrGLEffect* fEffects[GrDrawState::kNumStages];

View File

@ -94,49 +94,19 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx, GrGLUniformMana
, fUniformManager(uniformManager) , fUniformManager(uniformManager)
, fCurrentStageIdx(kNonStageIdx) , fCurrentStageIdx(kNonStageIdx)
, fSetupFragPosition(false) , fSetupFragPosition(false)
, fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) {
, fTexCoordVaryingType(kVoid_GrSLType) {
fPositionVar = &fVSAttrs.push_back(); fPositionVar = &fVSAttrs.push_back();
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
} }
void GrGLShaderBuilder::setupTextureAccess(const char* varyingFSName, GrSLType varyingType) {
// FIXME: We don't know how the effect will manipulate the coords. So we give up on using
// projective texturing and always give the stage 2D coords. This will be fixed when effects
// are responsible for setting up their own tex coords / tex matrices.
switch (varyingType) {
case kVec2f_GrSLType:
fDefaultTexCoordsName = varyingFSName;
fTexCoordVaryingType = kVec2f_GrSLType;
break;
case kVec3f_GrSLType: {
fDefaultTexCoordsName = "inCoord";
GrAssert(kNonStageIdx != fCurrentStageIdx);
fDefaultTexCoordsName.appendS32(fCurrentStageIdx);
fTexCoordVaryingType = kVec3f_GrSLType;
fFSCode.appendf("\t%s %s = %s.xy / %s.z;\n",
GrGLShaderVar::TypeString(kVec2f_GrSLType),
fDefaultTexCoordsName.c_str(),
varyingFSName,
varyingFSName);
break;
}
default:
GrCrash("Tex coords must either be Vec2f or Vec3f");
}
}
void GrGLShaderBuilder::appendTextureLookup(SkString* out, void GrGLShaderBuilder::appendTextureLookup(SkString* out,
const GrGLShaderBuilder::TextureSampler& sampler, const GrGLShaderBuilder::TextureSampler& sampler,
const char* coordName, const char* coordName,
GrSLType varyingType) const { GrSLType varyingType) const {
GrAssert(NULL != sampler.textureAccess()); GrAssert(NULL != sampler.textureAccess());
GrAssert(NULL != coordName);
if (NULL == coordName) {
coordName = fDefaultTexCoordsName.c_str();
varyingType = kVec2f_GrSLType;
}
out->appendf("%s(%s, %s)", out->appendf("%s(%s, %s)",
sample_function_name(varyingType), sample_function_name(varyingType),
this->getUniformCStr(sampler.fSamplerUniform), this->getUniformCStr(sampler.fSamplerUniform),

View File

@ -77,18 +77,12 @@ public:
GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&); GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&);
/** Determines whether we should use texture2D() or texture2Dproj(), and if an explicit divide /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
is required for the sample coordinates, creates the new variable and emits the code to Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
initialize it. This should only be called by GrGLProgram.*/ order of the result depends on the GrTextureAccess associated with the TextureSampler. */
void setupTextureAccess(const char* varyingFSName, GrSLType varyingType);
/** Appends a texture sample with projection if necessary; if coordName is not
specified, uses fSampleCoords. coordType must either be Vec2f or Vec3f. The latter is
interpreted as projective texture coords. The vec length and swizzle order of the result
depends on the GrTextureAccess associated with the TextureSampler. */
void appendTextureLookup(SkString* out, void appendTextureLookup(SkString* out,
const TextureSampler&, const TextureSampler&,
const char* coordName = NULL, const char* coordName,
GrSLType coordType = kVec2f_GrSLType) const; GrSLType coordType = kVec2f_GrSLType) const;
/** Does the work of appendTextureLookup and modulates the result by modulation. The result is /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
@ -98,18 +92,9 @@ public:
void appendTextureLookupAndModulate(SkString* out, void appendTextureLookupAndModulate(SkString* out,
const char* modulation, const char* modulation,
const TextureSampler&, const TextureSampler&,
const char* coordName = NULL, const char* coordName,
GrSLType coordType = kVec2f_GrSLType) const; GrSLType coordType = kVec2f_GrSLType) const;
/** Gets the name of the default texture coords which are always kVec2f */
const char* defaultTexCoordsName() const { return fDefaultTexCoordsName.c_str(); }
/* Returns true if the texture matrix from which the default texture coords are computed has
perspective. */
bool defaultTextureMatrixIsPerspective() const {
return fTexCoordVaryingType == kVec3f_GrSLType;
}
/** Emits a helper function outside of main(). Currently ShaderType must be /** Emits a helper function outside of main(). Currently ShaderType must be
kFragment_ShaderType. */ kFragment_ShaderType. */
void emitFunction(ShaderType shader, void emitFunction(ShaderType shader,
@ -233,14 +218,6 @@ private:
GrGLUniformManager::UniformHandle fRTHeightUniform; GrGLUniformManager::UniformHandle fRTHeightUniform;
GrGLShaderVar* fPositionVar; GrGLShaderVar* fPositionVar;
/// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
//@{
GrSLType fTexCoordVaryingType; // the type, either Vec2f or Vec3f, of the coords passed
// as a varying from the VS to the FS.
SkString fDefaultTexCoordsName; // the name of the default 2D coords value.
//@}
}; };
#endif #endif

View File

@ -145,18 +145,10 @@ private:
const GrGLContextInfo& glContextInfo() const { return fGLContextInfo; } const GrGLContextInfo& glContextInfo() const { return fGLContextInfo; }
// adjusts texture matrix to account for orientation
static void AdjustTextureMatrix(const GrTexture* texture, SkMatrix* matrix);
// This helper determines if what optimizations can be applied to the matrix after any coord
// adjustments are applied. The return is a bitfield of GrGLProgram::StageDesc::OptFlags.
static int TextureMatrixOptFlags(const GrGLTexture* texture, const GrEffectStage& sampler);
static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
// for readability of function impls // for readability of function impls
typedef GrGLProgram::Desc ProgramDesc; typedef GrGLProgram::Desc ProgramDesc;
typedef ProgramDesc::StageDesc StageDesc;
class ProgramCache : public ::GrNoncopyable { class ProgramCache : public ::GrNoncopyable {
public: public:
@ -214,9 +206,6 @@ private:
const GrTextureParams& params, const GrTextureParams& params,
GrGLTexture* nextTexture); GrGLTexture* nextTexture);
// sets the texture matrix for the currently bound program
void flushTextureMatrix(int stageIdx);
// sets the color specified by GrDrawState::setColor() // sets the color specified by GrDrawState::setColor()
void flushColor(GrColor color); void flushColor(GrColor color);

View File

@ -159,85 +159,6 @@ void GrGpuGL::flushViewMatrix(DrawType type) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// helpers for texture matrices
void GrGpuGL::AdjustTextureMatrix(const GrTexture* texture, SkMatrix* matrix) {
GrAssert(NULL != texture);
GrAssert(NULL != matrix);
if (GrSurface::kBottomLeft_Origin == texture->origin()) {
SkMatrix invY;
invY.setAll(SK_Scalar1, 0, 0,
0, -SK_Scalar1, SK_Scalar1,
0, 0, SkMatrix::I()[8]);
matrix->postConcat(invY);
}
}
int GrGpuGL::TextureMatrixOptFlags(const GrGLTexture* texture,
const GrEffectStage& stage) {
GrAssert(NULL != texture);
SkMatrix matrix;
stage.getTotalMatrix(&matrix);
bool canBeIndentity = GrSurface::kTopLeft_Origin == texture->origin();
if (canBeIndentity && matrix.isIdentity()) {
return GrGLProgram::StageDesc::kIdentityMatrix_OptFlagBit;
} else if (!matrix.hasPerspective()) {
return GrGLProgram::StageDesc::kNoPerspective_OptFlagBit;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
void GrGpuGL::flushTextureMatrix(int s) {
const GrDrawState& drawState = this->getDrawState();
// FIXME: Still assuming only a single texture per effect
const GrEffect* effect = drawState.getStage(s).getEffect();
if (0 == effect->numTextures()) {
return;
}
const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect->texture(0));
if (NULL != texture) {
bool originChange = fCurrentProgram->fTextureOrigin[s] != texture->origin();
UniformHandle matrixUni = fCurrentProgram->fUniforms.fStages[s].fTextureMatrixUni;
const SkMatrix& hwMatrix = fCurrentProgram->fTextureMatrices[s];
SkMatrix samplerMatrix;
drawState.getStage(s).getTotalMatrix(&samplerMatrix);
if (kInvalidUniformHandle != matrixUni &&
(originChange || !hwMatrix.cheapEqualTo(samplerMatrix))) {
SkMatrix m = samplerMatrix;
AdjustTextureMatrix(texture, &m);
// ES doesn't allow you to pass true to the transpose param,
// so do our own transpose
GrGLfloat mt[] = {
SkScalarToFloat(m[SkMatrix::kMScaleX]),
SkScalarToFloat(m[SkMatrix::kMSkewY]),
SkScalarToFloat(m[SkMatrix::kMPersp0]),
SkScalarToFloat(m[SkMatrix::kMSkewX]),
SkScalarToFloat(m[SkMatrix::kMScaleY]),
SkScalarToFloat(m[SkMatrix::kMPersp1]),
SkScalarToFloat(m[SkMatrix::kMTransX]),
SkScalarToFloat(m[SkMatrix::kMTransY]),
SkScalarToFloat(m[SkMatrix::kMPersp2])
};
fCurrentProgram->fUniformManager.setMatrix3f(matrixUni, mt);
fCurrentProgram->fTextureMatrices[s] = samplerMatrix;
}
fCurrentProgram->fTextureOrigin[s] = texture->origin();
}
}
void GrGpuGL::flushColor(GrColor color) { void GrGpuGL::flushColor(GrColor color) {
const ProgramDesc& desc = fCurrentProgram->getDesc(); const ProgramDesc& desc = fCurrentProgram->getDesc();
const GrDrawState& drawState = this->getDrawState(); const GrDrawState& drawState = this->getDrawState();
@ -386,8 +307,6 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
for (int s = 0; s < GrDrawState::kNumStages; ++s) { for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (this->isStageEnabled(s)) { if (this->isStageEnabled(s)) {
this->flushBoundTextureAndParams(s); this->flushBoundTextureAndParams(s);
this->flushTextureMatrix(s);
} }
} }
} }
@ -640,40 +559,15 @@ void GrGpuGL::buildProgram(bool isPoints,
} }
for (int s = 0; s < GrDrawState::kNumStages; ++s) { for (int s = 0; s < GrDrawState::kNumStages; ++s) {
StageDesc& stageDesc = desc->fStages[s];
stageDesc.fOptFlags = 0; bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCoverage;
stageDesc.setEnabled(this->isStageEnabled(s)); if (!skip && drawState.isStageEnabled(s)) {
bool skip = s < drawState.getFirstCoverageStage() ? skipColor :
skipCoverage;
if (!skip && stageDesc.isEnabled()) {
lastEnabledStage = s; lastEnabledStage = s;
const GrEffectStage& stage = drawState.getStage(s);
// FIXME: Still assuming one texture per effect
const GrEffect* effect = drawState.getStage(s).getEffect(); const GrEffect* effect = drawState.getStage(s).getEffect();
if (effect->numTextures() > 0) {
const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect->texture(0));
SkMatrix samplerMatrix;
stage.getTotalMatrix(&samplerMatrix);
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
// for texture orientation.
stageDesc.fOptFlags |= TextureMatrixOptFlags(texture, stage);
}
} else {
// Set identity to do the minimal amount of extra work for the no texture case.
// This will go away when effects manage their own texture matrix.
stageDesc.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
}
const GrBackendEffectFactory& factory = effect->getFactory(); const GrBackendEffectFactory& factory = effect->getFactory();
stageDesc.fEffectKey = factory.glEffectKey(stage, this->glCaps()); desc->fEffectKeys[s] = factory.glEffectKey(drawState.getStage(s), this->glCaps());
} else { } else {
stageDesc.fOptFlags = 0; desc->fEffectKeys[s] = 0;
stageDesc.fEffectKey = 0;
} }
} }

View File

@ -31,8 +31,6 @@ bool random_bool(GrRandom* r) {
return r->nextF() > .5f; return r->nextF() > .5f;
} }
typedef GrGLProgram::StageDesc StageDesc;
const GrEffect* create_random_effect(GrRandom* random, const GrEffect* create_random_effect(GrRandom* random,
GrContext* context, GrContext* context,
GrTexture* dummyTextures[]) { GrTexture* dummyTextures[]) {
@ -59,13 +57,6 @@ bool GrGpuGL::programUnitTest() {
dummyDesc.fHeight = 22; dummyDesc.fHeight = 22;
SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0)); SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0));
// GrGLSLGeneration glslGeneration =
GrGetGLSLGeneration(this->glBinding(), this->glInterface());
static const int STAGE_OPTS[] = {
0,
StageDesc::kNoPerspective_OptFlagBit,
};
static const int NUM_TESTS = 512; static const int NUM_TESTS = 512;
GrRandom random; GrRandom random;
@ -118,7 +109,6 @@ bool GrGpuGL::programUnitTest() {
GrEffectStage stages[GrDrawState::kNumStages]; GrEffectStage stages[GrDrawState::kNumStages];
for (int s = 0; s < GrDrawState::kNumStages; ++s) { for (int s = 0; s < GrDrawState::kNumStages; ++s) {
StageDesc& stageDesc = pdesc.fStages[s];
// enable the stage? // enable the stage?
if (random_bool(&random)) { if (random_bool(&random)) {
// use separate tex coords? // use separate tex coords?
@ -126,24 +116,18 @@ bool GrGpuGL::programUnitTest() {
int t = random_int(&random, GrDrawState::kMaxTexCoords); int t = random_int(&random, GrDrawState::kMaxTexCoords);
pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t); pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t);
} }
stageDesc.setEnabled(true); // use text-formatted verts?
} if (random_bool(&random)) {
// use text-formatted verts? pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
if (random_bool(&random)) { }
pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
}
stageDesc.fEffectKey = 0;
stageDesc.fOptFlags |= STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))];
if (stageDesc.isEnabled()) {
GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()}; GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
SkAutoTUnref<const GrEffect> effect(create_random_effect(&random, SkAutoTUnref<const GrEffect> effect(create_random_effect(&random,
getContext(), getContext(),
dummyTextures)); dummyTextures));
stages[s].setEffect(effect.get()); stages[s].setEffect(effect.get());
if (NULL != stages[s].getEffect()) { if (NULL != stages[s].getEffect()) {
stageDesc.fEffectKey = pdesc.fEffectKeys[s] =
stages[s].getEffect()->getFactory().glEffectKey(stages[s], this->glCaps()); stages[s].getEffect()->getFactory().glEffectKey(stages[s], this->glCaps());
} }
} }