Move texture domains onto a GrCustomStage, off of GrSamplerState.

This will require gyp changes to roll into Chrome.

http://codereview.appspot.com/6405050/



git-svn-id: http://skia.googlecode.com/svn/trunk@4641 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
new file mode 100644
index 0000000..e639df8
--- /dev/null
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTextureDomainEffect.h"
+#include "gl/GrGLProgramStage.h"
+#include "GrProgramStageFactory.h"
+
+class GrGLTextureDomainEffect : public GrGLProgramStage {
+public:
+    GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
+                            const GrCustomStage& stage);
+
+    virtual void setupVariables(GrGLShaderBuilder* state,
+                                int stage) SK_OVERRIDE;
+    virtual void emitVS(GrGLShaderBuilder* state,
+                        const char* vertexCoords) SK_OVERRIDE { }
+    virtual void emitFS(GrGLShaderBuilder* state,
+                        const char* outputColor,
+                        const char* inputColor,
+                        const char* samplerName) SK_OVERRIDE;
+
+    virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
+
+    virtual void setData(const GrGLInterface*,
+                         const GrCustomStage&,
+                         const GrRenderTarget*,
+                         int stageNum) SK_OVERRIDE;
+
+    static inline StageKey GenKey(const GrCustomStage&) { return 0; }
+
+private:
+    const GrGLShaderVar* fNameVar;
+    int                  fNameLocation;
+
+    typedef GrGLProgramStage INHERITED;
+};
+
+GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
+                                                 const GrCustomStage& stage)
+    : GrGLProgramStage(factory)
+    , fNameVar(NULL)
+    , fNameLocation(0) {
+}
+
+void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* state,
+                                             int stage) {
+    fNameVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+                                  kVec4f_GrSLType, "uTexDom", stage);
+    fNameLocation = kUseUniform;
+};
+
+void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* state,
+                                     const char* outputColor,
+                                     const char* inputColor,
+                                     const char* samplerName) {
+    SkString coordVar("clampCoord");
+    state->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
+                           GrGLShaderVar::TypeString(GrSLFloatVectorType(state->fCoordDims)),
+                           coordVar.c_str(),
+                           state->fSampleCoords.c_str(),
+                           fNameVar->getName().c_str(),
+                           fNameVar->getName().c_str());
+    state->fSampleCoords = coordVar;
+
+    state->emitDefaultFetch(outputColor, samplerName);
+}
+
+void GrGLTextureDomainEffect::initUniforms(const GrGLInterface* gl, int programID) {
+    GR_GL_CALL_RET(gl, fNameLocation,
+                   GetUniformLocation(programID, fNameVar->getName().c_str()));
+    GrAssert(kUnusedUniform != fNameLocation);
+}
+
+void GrGLTextureDomainEffect::setData(const GrGLInterface* gl,
+                         const GrCustomStage& data,
+                         const GrRenderTarget*,
+                         int stageNum) {
+    const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
+    const GrRect& domain = effect.domain();
+
+    float values[4] = {
+        GrScalarToFloat(domain.left()),
+        GrScalarToFloat(domain.top()),
+        GrScalarToFloat(domain.right()),
+        GrScalarToFloat(domain.bottom())
+    };
+    // vertical flip if necessary
+    const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
+    if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
+        values[1] = 1.0f - values[1];
+        values[3] = 1.0f - values[3];
+        // The top and bottom were just flipped, so correct the ordering
+        // of elements so that values = (l, t, r, b).
+        SkTSwap(values[1], values[3]);
+    }
+
+    GR_GL_CALL(gl, Uniform4fv(fNameLocation, 1, values));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain)
+    : GrSingleTextureEffect(texture)
+    , fTextureDomain(domain) {
+
+}
+
+GrTextureDomainEffect::~GrTextureDomainEffect() {
+
+}
+
+const GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
+    return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
+}
+
+bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
+    const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
+    return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
+}
+
+