Attempt to reland 8264-5 with warning-as-error fixes.
git-svn-id: http://skia.googlecode.com/svn/trunk@8272 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLEffect.cpp b/src/gpu/gl/GrGLEffect.cpp
index 478d03d..e21ab1d 100644
--- a/src/gpu/gl/GrGLEffect.cpp
+++ b/src/gpu/gl/GrGLEffect.cpp
@@ -7,6 +7,7 @@
#include "GrGLSL.h"
#include "GrGLEffect.h"
+#include "GrDrawEffect.h"
GrGLEffect::GrGLEffect(const GrBackendEffectFactory& factory)
: fFactory(factory) {
@@ -17,14 +18,15 @@
///////////////////////////////////////////////////////////////////////////////
-void GrGLEffect::setData(const GrGLUniformManager&, const GrEffectStage&) {
+void GrGLEffect::setData(const GrGLUniformManager&, const GrDrawEffect&) {
}
-GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffectRef* effect,
+GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrDrawEffect& drawEffect,
const GrGLCaps& caps) {
EffectKey key = 0;
- for (int index = 0; index < (*effect)->numTextures(); ++index) {
- const GrTextureAccess& access = (*effect)->textureAccess(index);
+ int numTextures = (*drawEffect.effect())->numTextures();
+ for (int index = 0; index < numTextures; ++index) {
+ const GrTextureAccess& access = (*drawEffect.effect())->textureAccess(index);
EffectKey value = GrGLShaderBuilder::KeyForTextureAccess(access, caps) << index;
GrAssert(0 == (value & key)); // keys for each access ought not to overlap
key |= value;
@@ -32,12 +34,12 @@
return key;
}
-GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrEffectStage& stage) {
+GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrDrawEffect& drawEffect) {
EffectKey key = 0;
- int numAttributes = stage.getVertexAttribIndexCount();
+ int numAttributes = drawEffect.getVertexAttribIndexCount();
GrAssert(numAttributes <= 2);
- const int* attributeIndices = stage.getVertexAttribIndices();
+ const int* attributeIndices = drawEffect.getVertexAttribIndices();
for (int index = 0; index < numAttributes; ++index) {
EffectKey value = attributeIndices[index] << 3*index;
GrAssert(0 == (value & key)); // keys for each attribute ought not to overlap
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
index 869fbda..5df2281 100644
--- a/src/gpu/gl/GrGLEffect.h
+++ b/src/gpu/gl/GrGLEffect.h
@@ -12,7 +12,6 @@
#include "GrGLShaderBuilder.h"
#include "GrGLShaderVar.h"
#include "GrGLSL.h"
-#include "GrEffectStage.h"
class GrGLTexture;
@@ -21,13 +20,20 @@
include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the
GLSL code that implements a GrEffect and for uploading uniforms at draw time. They also
must have a function:
- static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&)
+ static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&)
that is used to implement a program cache. When two GrEffects produce the same key this means
that their GrGLEffects would emit the same GLSL code.
+ The GrGLEffect subclass must also have a constructor of the form:
+ EffectSubclass::EffectSubclass(const GrBackendEffectFactory&, const GrDrawEffect&)
+ The effect held by the GrDrawEffect is guaranteed to be of the type that generated the
+ GrGLEffect subclass instance.
+
These objects are created by the factory object returned by the GrEffect::getFactory().
*/
+class GrDrawEffect;
+
class GrGLEffect {
public:
@@ -50,14 +56,10 @@
stages.
@param builder Interface used to emit code in the shaders.
- @param stage The effect stage that generated this program stage.
+ @param drawEffect A wrapper on the effect that generated this program stage.
@param key The key that was computed by GenKey() from the generating GrEffect.
Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are
guaranteed to match the value produced by GenKey();
- @param vertexCoords A vec2 in the VS that holds the position in local coords. This is either
- the pre-view-matrix vertex position or if explicit per-vertex texture
- 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
color (or coverage).
@param inputColor A vec4 that holds the input color to the stage in the FS. This may be
@@ -70,9 +72,8 @@
reads in the generated code.
*/
virtual void emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage& stage,
+ const GrDrawEffect& drawEffect,
EffectKey key,
- const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) = 0;
@@ -81,34 +82,15 @@
key; this function reads data from a stage and uploads any uniform variables required
by the shaders created in emitCode(). The GrEffect installed in the GrEffectStage is
guaranteed to be of the same type that created this GrGLEffect and to have an identical
- EffectKey as the one that created this GrGLEffect. */
- virtual void setData(const GrGLUniformManager&, const GrEffectStage&);
+ EffectKey as the one that created this GrGLEffect. Effects that use local coords have
+ to consider whether the GrEffectStage's coord change matrix should be used. When explicit
+ local coordinates are used it can be ignored. */
+ virtual void setData(const GrGLUniformManager&, const GrDrawEffect&);
const char* name() const { return fFactory.name(); }
- static EffectKey GenTextureKey(const GrEffectRef*, const GrGLCaps&);
- static EffectKey GenAttribKey(const GrEffectStage& stage);
-
- /**
- * GrGLEffect subclasses get passed a GrEffectStage in their emitCode and setData functions.
- * The GrGLEffect usually needs to cast the stage's effect to the GrEffect subclass that
- * generated the GrGLEffect. This helper does just that.
- */
- template <typename T>
- static const T& GetEffectFromStage(const GrEffectStage& effectStage) {
- GrAssert(NULL != effectStage.getEffect());
- return CastEffect<T>(*effectStage.getEffect());
- }
-
- /**
- * Extracts the GrEffect from a GrEffectRef and down-casts to a GrEffect subclass. Usually used
- * in a GrGLEffect subclass's constructor (which takes const GrEffectRef&).
- */
- template <typename T>
- static const T& CastEffect(const GrEffectRef& effectRef) {
- GrAssert(NULL != effectRef.get());
- return *static_cast<const T*>(effectRef.get());
- }
+ static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
+ static EffectKey GenAttribKey(const GrDrawEffect& stage);
protected:
const GrBackendEffectFactory& fFactory;
diff --git a/src/gpu/gl/GrGLEffectMatrix.cpp b/src/gpu/gl/GrGLEffectMatrix.cpp
index c37098e..e2e8807 100644
--- a/src/gpu/gl/GrGLEffectMatrix.cpp
+++ b/src/gpu/gl/GrGLEffectMatrix.cpp
@@ -6,58 +6,67 @@
*/
#include "GrGLEffectMatrix.h"
+#include "GrDrawEffect.h"
#include "GrTexture.h"
GrGLEffect::EffectKey GrGLEffectMatrix::GenKey(const SkMatrix& effectMatrix,
- const SkMatrix& coordChangeMatrix,
+ const GrDrawEffect& drawEffect,
+ CoordsType coordsType,
const GrTexture* texture) {
+ EffectKey key = 0;
SkMatrix::TypeMask type0 = effectMatrix.getType();
- SkMatrix::TypeMask type1 = coordChangeMatrix.getType();
+ SkMatrix::TypeMask type1;
+ if (GrEffect::kLocal_CoordsType == coordsType) {
+ type1 = drawEffect.getCoordChangeMatrix().getType();
+ } else {
+ if (drawEffect.programHasExplicitLocalCoords()) {
+ // We only make the key indicate that device coords are referenced when the local coords
+ // are not actually determined by positions.
+ key |= kPositionCoords_Flag;
+ }
+ type1 = SkMatrix::kIdentity_Mask;
+ }
- static const int kNonTransMask = SkMatrix::kAffine_Mask |
- SkMatrix::kScale_Mask |
- SkMatrix::kPerspective_Mask;
int combinedTypes = type0 | type1;
bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture->origin();
if (SkMatrix::kPerspective_Mask & combinedTypes) {
- return kGeneral_Key;
- } else if ((kNonTransMask & combinedTypes) || reverseY) {
- return kNoPersp_Key;
- } else if (kTrans_Key & combinedTypes) {
- return kTrans_Key;
+ key |= kGeneral_MatrixType;
+ } else if (((SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask) & combinedTypes) || reverseY) {
+ key |= kNoPersp_MatrixType;
+ } else if (SkMatrix::kTranslate_Mask & combinedTypes) {
+ key |= kTrans_MatrixType;
} else {
- GrAssert(effectMatrix.isIdentity() && coordChangeMatrix.isIdentity());
- return kIdentity_Key;
+ key |= kIdentity_MatrixType;
}
+ return key;
}
GrSLType GrGLEffectMatrix::emitCode(GrGLShaderBuilder* builder,
EffectKey key,
- const char* vertexCoords,
const char** fsCoordName,
const char** vsCoordName,
const char* suffix) {
GrSLType varyingType;
const char* uniName;
key &= kKeyMask;
- switch (key) {
- case kIdentity_Key:
+ switch (key & kMatrixTypeKeyMask) {
+ case kIdentity_MatrixType:
fUniType = kVoid_GrSLType;
varyingType = kVec2f_GrSLType;
break;
- case kTrans_Key:
+ case kTrans_MatrixType:
fUniType = kVec2f_GrSLType;
uniName = "StageTranslate";
varyingType = kVec2f_GrSLType;
break;
- case kNoPersp_Key:
+ case kNoPersp_MatrixType:
fUniType = kMat33f_GrSLType;
uniName = "StageMatrix";
varyingType = kVec2f_GrSLType;
break;
- case kGeneral_Key:
+ case kGeneral_MatrixType:
fUniType = kMat33f_GrSLType;
uniName = "StageMatrix";
varyingType = kVec3f_GrSLType;
@@ -89,24 +98,39 @@
const char* fsVaryingName;
builder->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
- // varying = matrix * vertex-coords (logically)
+ const GrGLShaderVar* coords;
+ switch (fCoordsType) {
+ case GrEffect::kLocal_CoordsType:
+ GrAssert(!(kPositionCoords_Flag & key));
+ coords = &builder->localCoordsAttribute();
+ break;
+ case GrEffect::kPosition_CoordsType:
+ GrAssert((kPositionCoords_Flag & key) || !builder->hasExplicitLocalCoords());
+ coords = &builder->positionAttribute();
+ break;
+ default:
+ coords = NULL; // prevents warning
+ GrCrash("Unexpected coords type.");
+ }
+ // varying = matrix * coords (logically)
switch (fUniType) {
case kVoid_GrSLType:
GrAssert(kVec2f_GrSLType == varyingType);
- builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, vertexCoords);
+ builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, coords->c_str());
break;
case kVec2f_GrSLType:
GrAssert(kVec2f_GrSLType == varyingType);
- builder->vsCodeAppendf("\t%s = %s + %s;\n", vsVaryingName, uniName, vertexCoords);
+ builder->vsCodeAppendf("\t%s = %s + %s;\n",
+ vsVaryingName, uniName, coords->c_str());
break;
case kMat33f_GrSLType: {
GrAssert(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
if (kVec2f_GrSLType == varyingType) {
builder->vsCodeAppendf("\t%s = (%s * vec3(%s, 1)).xy;\n",
- vsVaryingName, uniName, vertexCoords);
+ vsVaryingName, uniName, coords->c_str());
} else {
builder->vsCodeAppendf("\t%s = %s * vec3(%s, 1);\n",
- vsVaryingName, uniName, vertexCoords);
+ vsVaryingName, uniName, coords->c_str());
}
break;
}
@@ -128,7 +152,6 @@
*/
void GrGLEffectMatrix::emitCodeMakeFSCoords2D(GrGLShaderBuilder* builder,
EffectKey key,
- const char* vertexCoords,
const char** fsCoordName,
const char** vsVaryingName,
GrSLType* vsVaryingType,
@@ -137,7 +160,6 @@
GrSLType varyingType = this->emitCode(builder,
key,
- vertexCoords,
&fsVaryingName,
vsVaryingName,
suffix);
@@ -164,11 +186,14 @@
}
void GrGLEffectMatrix::setData(const GrGLUniformManager& uniformManager,
- const SkMatrix& matrix,
- const SkMatrix& coordChangeMatrix,
- const GrTexture* texture) {
+ const SkMatrix& matrix,
+ const GrDrawEffect& drawEffect,
+ const GrTexture* texture) {
GrAssert((GrGLUniformManager::kInvalidUniformHandle == fUni) ==
- (kVoid_GrSLType == fUniType));
+ (kVoid_GrSLType == fUniType));
+ const SkMatrix& coordChangeMatrix = GrEffect::kLocal_CoordsType == fCoordsType ?
+ drawEffect.getCoordChangeMatrix() :
+ SkMatrix::I();
switch (fUniType) {
case kVoid_GrSLType:
GrAssert(matrix.isIdentity());
@@ -178,8 +203,8 @@
case kVec2f_GrSLType: {
GrAssert(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
- SkScalar tx = matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX];
- SkScalar ty = matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY];
+ SkScalar tx = matrix[SkMatrix::kMTransX] + (coordChangeMatrix)[SkMatrix::kMTransX];
+ SkScalar ty = matrix[SkMatrix::kMTransY] + (coordChangeMatrix)[SkMatrix::kMTransY];
if (fPrevMatrix.get(SkMatrix::kMTransX) != tx ||
fPrevMatrix.get(SkMatrix::kMTransY) != ty) {
uniformManager.set2f(fUni, tx, ty);
diff --git a/src/gpu/gl/GrGLEffectMatrix.h b/src/gpu/gl/GrGLEffectMatrix.h
index 1a11656..fc4b783 100644
--- a/src/gpu/gl/GrGLEffectMatrix.h
+++ b/src/gpu/gl/GrGLEffectMatrix.h
@@ -14,34 +14,68 @@
class GrTexture;
/**
- * This is a helper to implement a texture matrix in a GrGLEffect.
+ * This is a helper to implement a matrix in a GrGLEffect that operates on incoming coords in the
+ * vertex shader and writes them to an attribute to be used in the fragment shader. When the input
+ * coords in the vertex shader are local coordinates this class accounts for the coord change matrix
+ * communicated via GrDrawEffect. The input coords may also be positions and in this case the coord
+ * change matrix is ignored. The GrGLEffectMatrix will emit different code based on the type of
+ * matrix and thus must contribute to the effect's key.
+ *
+ * This class cannot be used to apply a matrix to coordinates that come in the form of custom vertex
+ * attributes.
*/
class GrGLEffectMatrix {
+private:
+ // We specialize the generated code for each of these matrix types.
+ enum MatrixTypes {
+ kIdentity_MatrixType = 0,
+ kTrans_MatrixType = 1,
+ kNoPersp_MatrixType = 2,
+ kGeneral_MatrixType = 3,
+ };
+ // The key for is made up of a matrix type and a bit that indicates the source of the input
+ // coords.
+ enum {
+ kMatrixTypeKeyBits = 2,
+ kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
+ kPositionCoords_Flag = (1 << kMatrixTypeKeyBits),
+ kKeyBitsPrivate = kMatrixTypeKeyBits + 1,
+ };
+
public:
+
+ typedef GrEffect::CoordsType CoordsType;
+
typedef GrGLEffect::EffectKey EffectKey;
+
/**
* The matrix uses kKeyBits of the effect's EffectKey. A GrGLEffect may place these bits at an
* arbitrary shift in its final key. However, when GrGLEffectMatrix::emitCode*() code is called
* the relevant bits must be in the lower kKeyBits of the key parameter.
*/
enum {
- kKeyBits = 2,
+ kKeyBits = kKeyBitsPrivate,
kKeyMask = (1 << kKeyBits) - 1,
};
- GrGLEffectMatrix() : fUni(GrGLUniformManager::kInvalidUniformHandle) {
+ GrGLEffectMatrix(CoordsType coordsType)
+ : fUni(GrGLUniformManager::kInvalidUniformHandle)
+ , fCoordsType(coordsType) {
+ GrAssert(GrEffect::kLocal_CoordsType == coordsType ||
+ GrEffect::kPosition_CoordsType == coordsType);
fPrevMatrix = SkMatrix::InvalidMatrix();
}
/**
* Generates the key for the portion of the code emitted by this class's emitCode() function.
* Pass a texture to make GrGLEffectMatrix automatically adjust for the texture's origin. Pass
- * NULL when not using the EffectMatrix for a texture lookups, or if the GrGLEffect subclass
- * wants to handle origin adjustments in some other manner. coordChangeMatrix is the matrix
- * from GrEffectStage.
+ * NULL when not using the EffectMatrix for a texture lookup, or if the GrGLEffect subclass
+ * wants to handle origin adjustments in some other manner. The coords type param must match the
+ * param that would be used to initialize GrGLEffectMatrix for the generating GrEffect.
*/
static EffectKey GenKey(const SkMatrix& effectMatrix,
- const SkMatrix& coordChangeMatrix,
+ const GrDrawEffect&,
+ CoordsType,
const GrTexture*);
/**
@@ -55,7 +89,6 @@
*/
GrSLType emitCode(GrGLShaderBuilder*,
EffectKey,
- const char* vertexCoords,
const char** fsCoordName, /* optional */
const char** vsCoordName = NULL,
const char* suffix = NULL);
@@ -66,31 +99,23 @@
*/
void emitCodeMakeFSCoords2D(GrGLShaderBuilder*,
EffectKey,
- const char* vertexCoords,
const char** fsCoordName, /* optional */
const char** vsVaryingName = NULL,
GrSLType* vsVaryingType = NULL,
const char* suffix = NULL);
/**
- * Call from a GrGLEffect's subclass to update the texture matrix. The matrix,
- * coordChangeMatrix, and texture params should match those used with GenKey.
+ * Call from a GrGLEffect's subclass to update the texture matrix. The effectMatrix and texture
+ * params should match those used with GenKey.
*/
void setData(const GrGLUniformManager& uniformManager,
const SkMatrix& effectMatrix,
- const SkMatrix& coordChangeMatrix,
+ const GrDrawEffect& drawEffect,
const GrTexture*);
-private:
- enum {
- kIdentity_Key = 0,
- kTrans_Key = 1,
- kNoPersp_Key = 2,
- kGeneral_Key = 3,
- };
-
GrGLUniformManager::UniformHandle fUni;
GrSLType fUniType;
SkMatrix fPrevMatrix;
+ CoordsType fCoordsType;
};
#endif
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 7d6420e..21729cd 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -9,6 +9,7 @@
#include "GrAllocator.h"
#include "GrEffect.h"
+#include "GrDrawEffect.h"
#include "GrGLEffect.h"
#include "GrGpuGL.h"
#include "GrGLShaderVar.h"
@@ -26,7 +27,6 @@
SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
"Print the source code for all shaders generated.");
-#define TEX_ATTR_NAME "aTexCoord"
#define COL_ATTR_NAME "aColor"
#define COV_ATTR_NAME "aCoverage"
#define EDGE_ATTR_NAME "aEdge"
@@ -134,7 +134,10 @@
lastEnabledStage = s;
const GrEffectRef& effect = *drawState.getStage(s).getEffect();
const GrBackendEffectFactory& factory = effect->getFactory();
- desc->fEffectKeys[s] = factory.glEffectKey(drawState.getStage(s), gpu->glCaps());
+ bool explicitLocalCoords = (drawState.getAttribBindings() &
+ GrDrawState::kLocalCoords_AttribBindingsBit);
+ GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords);
+ desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
} else {
desc->fEffectKeys[s] = 0;
}
@@ -207,8 +210,8 @@
if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
desc->fEdgeAttributeIndex = drawState.getAttribIndex(GrDrawState::kEdge_AttribIndex);
}
- if (GrDrawState::AttributesBindExplicitTexCoords(desc->fAttribBindings)) {
- desc->fTexCoordAttributeIndex = drawState.getAttribIndex(GrDrawState::kTexCoord_AttribIndex);
+ if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+ desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState::kLocalCoords_AttribIndex);
}
#if GR_DEBUG
@@ -227,10 +230,10 @@
if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
GrAssert(desc->fEdgeAttributeIndex < GrDrawState::kVertexAttribCnt);
GrAssert(kAttribLayouts[vertexAttribs[desc->fEdgeAttributeIndex].fType].fCount == 4);
- }
- if (GrDrawState::AttributesBindExplicitTexCoords(desc->fAttribBindings)) {
- GrAssert(desc->fTexCoordAttributeIndex < GrDrawState::kVertexAttribCnt);
- GrAssert(kAttribLayouts[vertexAttribs[desc->fTexCoordAttributeIndex].fType].fCount == 2);
+ }
+ if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+ GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt);
+ GrAssert(kAttribLayouts[vertexAttribs[desc->fLocalCoordsAttributeIndex].fType].fCount == 2);
}
#endif
}
@@ -679,8 +682,10 @@
bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
GrAssert(0 == fProgramID);
- GrGLShaderBuilder builder(fContext.info(), fUniformManager);
const GrAttribBindings& attribBindings = fDesc.fAttribBindings;
+ bool hasExplicitLocalCoords =
+ SkToBool(attribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
+ GrGLShaderBuilder builder(fContext.info(), fUniformManager, hasExplicitLocalCoords);
#if GR_GL_EXPERIMENTAL_GS
builder.fUsesGS = fDesc.fExperimentalGS;
@@ -760,11 +765,6 @@
builder.vsCodeAppend("\tgl_PointSize = 1.0;\n");
}
- // add texture coordinates that are used to the list of vertex attr decls
- if (GrDrawState::AttributesBindExplicitTexCoords(attribBindings)) {
- builder.addAttribute(kVec2f_GrSLType, TEX_ATTR_NAME);
- }
-
///////////////////////////////////////////////////////////////////////////
// compute the final color
@@ -779,21 +779,11 @@
outColor.appendS32(s);
builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
- const char* inCoords;
- // figure out what our input coords are
- if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
- inCoords = builder.positionAttribute().c_str();
- } else {
- // must have input tex coordinates if stage is enabled.
- inCoords = TEX_ATTR_NAME;
- }
-
builder.setCurrentStage(s);
fEffects[s] = builder.createAndEmitGLEffect(*stages[s],
fDesc.fEffectKeys[s],
inColor.size() ? inColor.c_str() : NULL,
outColor.c_str(),
- inCoords,
&fUniformHandles.fSamplerUnis[s]);
builder.setNonStage();
inColor = outColor;
@@ -871,16 +861,6 @@
outCoverage.appendS32(s);
builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str());
- const char* inCoords;
- // figure out what our input coords are
- if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)) {
- inCoords = builder.positionAttribute().c_str();
- } else {
- // must have input tex coordinates if stage is
- // enabled.
- inCoords = TEX_ATTR_NAME;
- }
-
// stages don't know how to deal with a scalar input. (Maybe they should. We
// could pass a GrGLShaderVar)
if (inCoverageIsScalar) {
@@ -894,7 +874,6 @@
fDesc.fEffectKeys[s],
inCoverage.size() ? inCoverage.c_str() : NULL,
outCoverage.c_str(),
- inCoords,
&fUniformHandles.fSamplerUnis[s]);
builder.setNonStage();
inCoverage = outCoverage;
@@ -1008,8 +987,10 @@
if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
GL_CALL(BindAttribLocation(fProgramID, fDesc.fEdgeAttributeIndex, EDGE_ATTR_NAME));
}
- if (GrDrawState::AttributesBindExplicitTexCoords(fDesc.fAttribBindings)) {
- GL_CALL(BindAttribLocation(fProgramID, fDesc.fTexCoordAttributeIndex, TEX_ATTR_NAME));
+ if (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
+ GL_CALL(BindAttribLocation(fProgramID,
+ fDesc.fLocalCoordsAttributeIndex,
+ builder.localCoordsAttribute().c_str()));
}
const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end();
@@ -1088,7 +1069,11 @@
if (NULL != fEffects[s]) {
const GrEffectStage& stage = drawState.getStage(s);
GrAssert(NULL != stage.getEffect());
- fEffects[s]->setData(fUniformManager, stage);
+
+ bool explicitLocalCoords =
+ (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
+ GrDrawEffect drawEffect(stage, explicitLocalCoords);
+ fEffects[s]->setData(fUniformManager, drawEffect);
int numSamplers = fUniformHandles.fSamplerUnis[s].count();
for (int u = 0; u < numSamplers; ++u) {
UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index cde918b..9fd01fd 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -192,7 +192,7 @@
int8_t fColorAttributeIndex;
int8_t fCoverageAttributeIndex;
int8_t fEdgeAttributeIndex;
- int8_t fTexCoordAttributeIndex;
+ int8_t fLocalCoordsAttributeIndex;
friend class GrGLProgram;
};
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index b3b09cc..1179626 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -8,6 +8,7 @@
#include "gl/GrGLShaderBuilder.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLUniformHandle.h"
+#include "GrDrawEffect.h"
#include "GrTexture.h"
// number of each input/output type in a single allocation block
@@ -82,7 +83,8 @@
//const int GrGLShaderBuilder::fCoordDims = 2;
GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
- GrGLUniformManager& uniformManager)
+ GrGLUniformManager& uniformManager,
+ bool explicitLocalCoords)
: fUniforms(kVarsPerBlock)
, fVSAttrs(kVarsPerBlock)
, fVSOutputs(kVarsPerBlock)
@@ -99,6 +101,14 @@
fPositionVar = &fVSAttrs.push_back();
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
+ if (explicitLocalCoords) {
+ fLocalCoordsVar = &fVSAttrs.push_back();
+ fLocalCoordsVar->set(kVec2f_GrSLType,
+ GrGLShaderVar::kAttribute_TypeModifier,
+ "aLocalCoords");
+ } else {
+ fLocalCoordsVar = fPositionVar;
+ }
}
void GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_list args) {
@@ -494,7 +504,6 @@
GrGLEffect::EffectKey key,
const char* fsInColor,
const char* fsOutColor,
- const char* vsInCoord,
SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
GrAssert(NULL != stage.getEffect());
@@ -506,6 +515,7 @@
textureSamplers[i].init(this, &effect->textureAccess(i), i);
samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
}
+ GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords());
int numAttributes = stage.getVertexAttribIndexCount();
const int* attributeIndices = stage.getVertexAttribIndices();
@@ -519,15 +529,15 @@
}
}
- GrGLEffect* glEffect = effect->getFactory().createGLInstance(effect);
+ GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
// Enclose custom code in a block to avoid namespace conflicts
this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
this->fFSCode.appendf("\t{ // %s \n", glEffect->name());
+
glEffect->emitCode(this,
- stage,
+ drawEffect,
key,
- vsInCoord,
fsOutColor,
fsInColor,
textureSamplers);
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index 524a885..9d64143 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -17,6 +17,7 @@
#include <stdarg.h>
class GrGLContextInfo;
+class GrEffectStage;
/**
Contains all the incremental state of a shader as it is being built,as well as helpers to
@@ -80,7 +81,7 @@
kFragment_ShaderType = 0x4,
};
- GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&);
+ GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, bool explicitLocalCoords);
/**
* Called by GrGLEffects to add code to one of the shaders.
@@ -205,6 +206,16 @@
*/
const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
+ /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
+ as positionAttribute() or it may not be. It depends upon whether the rendering code
+ specified explicit local coords or not in the GrDrawState. */
+ const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
+
+ /**
+ * Are explicit local coordinates provided as input to the vertex shader.
+ */
+ bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
+
/**
* Interfaces used by GrGLProgram.
* TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
@@ -223,7 +234,6 @@
GrBackendEffectFactory::EffectKey key,
const char* fsInColor, // NULL means no incoming color
const char* fsOutColor,
- const char* vsInCoord,
SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles);
GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
@@ -290,6 +300,8 @@
SkSTArray<10, AttributePair, true> fEffectAttributes;
GrGLShaderVar* fPositionVar;
+ GrGLShaderVar* fLocalCoordsVar;
+
};
#endif