Make all remaining effects use GrGLEffectMatrix

R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6817079

git-svn-id: http://skia.googlecode.com/svn/trunk@6286 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index c5f6a3b..6831f2b 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -89,6 +89,9 @@
      *  If effect is non-NULL, a new GrEffect instance is stored
      *  in it.  The caller assumes ownership of the stage, and it is up to the
      *  caller to unref it.
+     *
+     *  The effect can assume its vertexCoords space maps 1-to-1 with texels
+     *  in the texture.
      */
     virtual bool asNewEffect(GrEffect** effect, GrTexture*) const;
 
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 0aa90ef..c90f8f3 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -16,6 +16,7 @@
 #if SK_SUPPORT_GPU
 #include "effects/GrSingleTextureEffect.h"
 #include "gl/GrGLEffect.h"
+#include "gl/GrGLEffectMatrix.h"
 #include "GrEffect.h"
 #include "GrTBackendEffectFactory.h"
 
@@ -969,9 +970,10 @@
 private:
     typedef GrGLEffect INHERITED;
 
-    UniformHandle   fImageIncrementUni;
-    UniformHandle   fSurfaceScaleUni;
-    GrGLLight*      fLight;
+    UniformHandle       fImageIncrementUni;
+    UniformHandle       fSurfaceScaleUni;
+    GrGLLight*          fLight;
+    GrGLEffectMatrix    fEffectMatrix;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1008,7 +1010,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 GrLightingEffect::GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale)
-    : GrSingleTextureEffect(texture)
+    : INHERITED(texture, MakeDivByTextureWHMatrix(texture))
     , fLight(light)
     , fSurfaceScale(surfaceScale) {
     fLight->ref();
@@ -1065,6 +1067,7 @@
     , fSurfaceScaleUni(kInvalidUniformHandle) {
     const GrLightingEffect& m = static_cast<const GrLightingEffect&>(effect);
     fLight = m.light()->createGLLight();
+    fRequiresTextureMatrix = false;
 }
 
 GrGLLightingEffect::~GrGLLightingEffect() {
@@ -1073,11 +1076,14 @@
 
 void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
                                   const GrEffectStage&,
-                                  EffectKey,
+                                  EffectKey key,
                                   const char* vertexCoords,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TextureSamplerArray& samplers) {
+    const char* coords;
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+
     fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                               kVec2f_GrSLType,
                                              "ImageIncrement");
@@ -1139,7 +1145,7 @@
                           interiorNormalBody.c_str(),
                           &interiorNormalName);
 
-    code->appendf("\t\tvec2 coord = %s;\n", builder->defaultTexCoordsName());
+    code->appendf("\t\tvec2 coord = %s;\n", coords);
     code->appendf("\t\tfloat m[9];\n");
 
     const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
@@ -1169,7 +1175,13 @@
 
 GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrEffectStage& s,
                                                  const GrGLCaps& caps) {
-    return static_cast<const GrLightingEffect&>(*s.getEffect()).light()->type();
+    const GrLightingEffect& effect = static_cast<const GrLightingEffect&>(*s.getEffect());
+    EffectKey key = static_cast<const GrLightingEffect&>(*s.getEffect()).light()->type();
+    key <<= GrGLEffectMatrix::kKeyBits;
+    EffectKey matrixKey = GrGLEffectMatrix::GenKey(effect.getMatrix(),
+                                                   s.getCoordChangeMatrix(),
+                                                   effect.texture(0));
+    return key | matrixKey;
 }
 
 void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
@@ -1179,6 +1191,10 @@
     uman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height());
     uman.set1f(fSurfaceScaleUni, effect.surfaceScale());
     fLight->setData(uman, effect.light());
+    fEffectMatrix.setData(uman,
+                          effect.getMatrix(),
+                          stage.getCoordChangeMatrix(),
+                          effect.texture(0));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1186,7 +1202,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrBackendEffectFactory& factory,
-                                            const GrEffect& effect)
+                                                     const GrEffect& effect)
     : INHERITED(factory, effect)
     , fKDUni(kInvalidUniformHandle) {
 }
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 1097273..73a50be 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -16,6 +16,7 @@
 #if SK_SUPPORT_GPU
 #include "effects/GrSingleTextureEffect.h"
 #include "gl/GrGLEffect.h"
+#include "gl/GrGLEffectMatrix.h"
 #include "gl/GrGLSL.h"
 #include "gl/GrGLTexture.h"
 #include "GrTBackendEffectFactory.h"
@@ -32,7 +33,7 @@
                       float yZoom,
                       float xInset,
                       float yInset)
-        : GrSingleTextureEffect(texture)
+        : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture))
         , fXOffset(xOffset)
         , fYOffset(yOffset)
         , fXZoom(xZoom)
@@ -91,9 +92,11 @@
 
 private:
 
-    UniformHandle  fOffsetVar;
-    UniformHandle  fZoomVar;
-    UniformHandle  fInsetVar;
+    UniformHandle       fOffsetVar;
+    UniformHandle       fZoomVar;
+    UniformHandle       fInsetVar;
+
+    GrGLEffectMatrix    fEffectMatrix;
 
     typedef GrGLEffect INHERITED;
 };
@@ -104,15 +107,18 @@
     , fOffsetVar(GrGLUniformManager::kInvalidUniformHandle)
     , fZoomVar(GrGLUniformManager::kInvalidUniformHandle)
     , fInsetVar(GrGLUniformManager::kInvalidUniformHandle) {
+    fRequiresTextureMatrix = false;
 }
 
 void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
                                    const GrEffectStage&,
-                                   EffectKey,
+                                   EffectKey key,
                                    const char* vertexCoords,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TextureSamplerArray& samplers) {
+    const char* coords;
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
     fOffsetVar = builder->addUniform(
         GrGLShaderBuilder::kFragment_ShaderType |
         GrGLShaderBuilder::kVertex_ShaderType,
@@ -128,10 +134,10 @@
 
     SkString* code = &builder->fFSCode;
 
-    code->appendf("\t\tvec2 coord = %s;\n", builder->defaultTexCoordsName());
+    code->appendf("\t\tvec2 coord = %s;\n", coords);
     code->appendf("\t\tvec2 zoom_coord = %s + %s / %s;\n",
                   builder->getUniformCStr(fOffsetVar),
-                  builder->defaultTexCoordsName(),
+                  coords,
                   builder->getUniformCStr(fZoomVar));
 
     code->appendf("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
@@ -165,10 +171,14 @@
     uman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
     uman.set2f(fZoomVar, zoom.x_zoom(), zoom.y_zoom());
     uman.set2f(fInsetVar, zoom.x_inset(), zoom.y_inset());
+    fEffectMatrix.setData(uman, zoom.getMatrix(), stage.getCoordChangeMatrix(), zoom.texture(0));
 }
 
-GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrEffectStage&, const GrGLCaps&) {
-    return 0;
+GrGLEffect::EffectKey GrGLMagnifierEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) {
+    const GrMagnifierEffect& zoom = static_cast<const GrMagnifierEffect&>(*stage.getEffect());
+    return GrGLEffectMatrix::GenKey(zoom.getMatrix(),
+                                    stage.getCoordChangeMatrix(),
+                                    zoom.texture(0));
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index f8d1c09..9f00160 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -14,7 +14,11 @@
 
 #if SK_SUPPORT_GPU
 #include "gl/GrGLEffect.h"
+#include "gl/GrGLEffectMatrix.h"
 #include "GrTBackendEffectFactory.h"
+#include "GrTexture.h"
+#include "SkMatrix.h"
+
 #endif
 
 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(const SkISize& kernelSize, const SkScalar* kernel, SkScalar gain, SkScalar bias, const SkIPoint& target, TileMode tileMode, bool convolveAlpha, SkImageFilter* input)
@@ -299,21 +303,23 @@
 private:
     typedef GrGLUniformManager::UniformHandle        UniformHandle;
     typedef SkMatrixConvolutionImageFilter::TileMode TileMode;
-    SkISize        fKernelSize;
-    TileMode       fTileMode;
-    bool           fConvolveAlpha;
+    SkISize             fKernelSize;
+    TileMode            fTileMode;
+    bool                fConvolveAlpha;
 
-    UniformHandle  fKernelUni;
-    UniformHandle  fImageIncrementUni;
-    UniformHandle  fTargetUni;
-    UniformHandle  fGainUni;
-    UniformHandle  fBiasUni;
+    UniformHandle       fKernelUni;
+    UniformHandle       fImageIncrementUni;
+    UniformHandle       fTargetUni;
+    UniformHandle       fGainUni;
+    UniformHandle       fBiasUni;
+
+    GrGLEffectMatrix    fEffectMatrix;
 
     typedef GrGLEffect INHERITED;
 };
 
 GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
-                                           const GrEffect& effect)
+                                                         const GrEffect& effect)
     : INHERITED(factory)
     , fKernelUni(GrGLUniformManager::kInvalidUniformHandle)
     , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle)
@@ -324,6 +330,7 @@
     fKernelSize = m.kernelSize();
     fTileMode = m.tileMode();
     fConvolveAlpha = m.convolveAlpha();
+    fRequiresTextureMatrix = false;
 }
 
 static void appendTextureLookup(GrGLShaderBuilder* builder,
@@ -350,12 +357,13 @@
 
 void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
                                            const GrEffectStage&,
-                                           EffectKey,
+                                           EffectKey key,
                                            const char* vertexCoords,
                                            const char* outputColor,
                                            const char* inputColor,
                                            const TextureSamplerArray& samplers) {
-
+    const char* coords;
+    fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
     fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                              kVec2f_GrSLType, "ImageIncrement");
     fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
@@ -378,8 +386,7 @@
     int kHeight = fKernelSize.height();
 
     code->appendf("\t\tvec4 sum = vec4(0, 0, 0, 0);\n");
-    code->appendf("\t\tvec2 coord = %s - %s * %s;\n",
-                  builder->defaultTexCoordsName(), target, imgInc);
+    code->appendf("\t\tvec2 coord = %s - %s * %s;\n", coords, target, imgInc);
     code->appendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight);
     code->appendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth);
     code->appendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth);
@@ -398,7 +405,7 @@
         code->appendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n", outputColor, outputColor, outputColor);
     } else {
         code->appendf("\t\tvec4 c = ");
-        appendTextureLookup(builder, samplers[0], builder->defaultTexCoordsName(), fTileMode);
+        appendTextureLookup(builder, samplers[0], coords, fTileMode);
         code->appendf(";\n");
         code->appendf("\t\t%s.a = c.a;\n", outputColor);
         code->appendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias);
@@ -424,7 +431,11 @@
     EffectKey key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
     key |= m.tileMode() << 7;
     key |= m.convolveAlpha() ? 1 << 9 : 0;
-    return key;
+    key << GrGLEffectMatrix::kKeyBits;
+    EffectKey matrixKey = GrGLEffectMatrix::GenKey(m.getMatrix(),
+                                                   s.getCoordChangeMatrix(),
+                                                   m.texture(0));
+    return key | matrixKey;
 }
 
 void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
@@ -443,6 +454,10 @@
     uman.set1fv(fKernelUni, 0, fKernelSize.width() * fKernelSize.height(), effect.kernel());
     uman.set1f(fGainUni, effect.gain());
     uman.set1f(fBiasUni, effect.bias());
+    fEffectMatrix.setData(uman,
+                          effect.getMatrix(),
+                          stage.getCoordChangeMatrix(),
+                          effect.texture(0));
 }
 
 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
@@ -453,7 +468,7 @@
                                                      const SkIPoint& target,
                                                      TileMode tileMode,
                                                      bool convolveAlpha)
-  : INHERITED(texture),
+  : INHERITED(texture, MakeDivByTextureWHMatrix(texture)),
     fKernelSize(kernelSize),
     fGain(SkScalarToFloat(gain)),
     fBias(SkScalarToFloat(bias) / 255.0f),
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index f176cdd..1712733 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -9,7 +9,6 @@
 #define Gr1DKernelEffect_DEFINED
 
 #include "GrSingleTextureEffect.h"
-#include "GrTexture.h"
 #include "SkMatrix.h"
 
 /**
@@ -21,15 +20,6 @@
  * two times the radius.
  */
 
-namespace {
-inline SkMatrix make_texture_matrix(GrTexture* tex) {
-    GrAssert(NULL != tex);
-    SkMatrix mat;
-    mat.setIDiv(tex->width(), tex->height());
-    return mat;
-}
-}
-
 class Gr1DKernelEffect : public GrSingleTextureEffect {
 
 public:
@@ -41,7 +31,7 @@
     Gr1DKernelEffect(GrTexture* texture,
                      Direction direction,
                      int radius)
-        : GrSingleTextureEffect(texture, make_texture_matrix(texture))
+        : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture))
         , fDirection(direction)
         , fRadius(radius) {}
 
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
index e598f2f..709d3dc 100644
--- a/src/gpu/effects/GrSingleTextureEffect.h
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -10,16 +10,18 @@
 
 #include "GrEffect.h"
 #include "SkMatrix.h"
+#include "GrTexture.h"
 
 class GrGLSingleTextureEffect;
 
 /**
- * An effect that merely blits a single texture; commonly used as a base class.
+ * An effect that draws a single texture with a texture matrix; commonly used as a base class. The
+ * output color is the texture color is modulated against the input color.
  */
 class GrSingleTextureEffect : public GrEffect {
 
 public:
-    /** These three constructors assume an identity matrix */
+    /** These three constructors assume an identity matrix. TODO: Remove these.*/
     GrSingleTextureEffect(GrTexture* texture); /* unfiltered, clamp mode */
     GrSingleTextureEffect(GrTexture* texture, bool bilerp); /* clamp mode */
     GrSingleTextureEffect(GrTexture* texture, const GrTextureParams&);
@@ -45,6 +47,14 @@
         const GrSingleTextureEffect& ste = static_cast<const GrSingleTextureEffect&>(effect);
         return INHERITED::isEqual(effect) && fMatrix.cheapEqualTo(ste.getMatrix());
     }
+
+    static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
+        GrAssert(NULL != texture);
+        SkMatrix mat;
+        mat.setIDiv(texture->width(), texture->height());
+        return mat;
+    }
+
 private:
     GR_DECLARE_EFFECT_TEST;