Adds local coords to GrEffect system.

Effects can ask the builder for local coords which may or may not be distinct from positions.

GrEffectStage tracks changes to relationship between pos and local coords.

GrGLEffectMatrix and GrSingleTextureEffect can use either pos or textures as intput coords

GrSimpleTextureEffect now allows for an explicit texture coords attribute.
Review URL: https://codereview.chromium.org/12531015

git-svn-id: http://skia.googlecode.com/svn/trunk@8264 2bbb7eff-a529-9590-31e7-b0007b416f81
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];