Add GrEllipseEdgeEffect.

Adds the effect that replaces the old oval rendering code. Also hooks in code to set attribute names and indices for effects.

Author: jvanverth@google.com

Review URL: https://chromiumcodereview.appspot.com/12462008

git-svn-id: http://skia.googlecode.com/svn/trunk@8092 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkTArray.h b/include/core/SkTArray.h
index 89f4c9d..45808d4 100644
--- a/include/core/SkTArray.h
+++ b/include/core/SkTArray.h
@@ -280,6 +280,23 @@
         return fItemArray[fCount - i - 1];
     }
 
+    bool operator==(const SkTArray<T, MEM_COPY>& right) const {
+        int leftCount = this->count();
+        if (leftCount != right.count()) {
+            return false;
+        }
+        for (int index = 0; index < leftCount; ++index) {
+            if (fItemArray[index] != right.fItemArray[index]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool operator!=(const SkTArray<T, MEM_COPY>& right) const {
+        return !(*this == right);
+    }
+
 protected:
     /**
      * Creates an empty array that will use the passed storage block until it
diff --git a/include/gpu/GrBackendEffectFactory.h b/include/gpu/GrBackendEffectFactory.h
index a291387..f5e638f 100644
--- a/include/gpu/GrBackendEffectFactory.h
+++ b/include/gpu/GrBackendEffectFactory.h
@@ -40,7 +40,8 @@
          * GrGLEffects' control. So there is a dedicated part of the key which is combined
          * automatically with the bits produced by GrGLEffect::GenKey().
          */
-        kTextureKeyBits = 6
+        kTextureKeyBits = 6,
+        kAttribKeyBits = 4
     };
 
     virtual EffectKey glEffectKey(const GrEffectStage&, const GrGLCaps&) const = 0;
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index 7b7cd33..2792476 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -14,6 +14,7 @@
 #include "GrRefCnt.h"
 #include "GrTexture.h"
 #include "GrTextureAccess.h"
+#include "GrTypesPriv.h"
 
 class GrBackendEffectFactory;
 class GrContext;
@@ -136,6 +137,14 @@
     /** Shortcut for textureAccess(index).texture(); */
     GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
 
+
+    int numVertexAttribs() const { return fVertexAttribTypes.count(); }
+
+    GrSLType vertexAttribType(int index) const { return fVertexAttribTypes[index]; }
+
+    static const int kMaxVertexAttribs = 2;
+
+
     /** Useful for effects that want to insert a texture matrix that is implied by the texture
         dimensions */
     static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
@@ -168,12 +177,19 @@
 
 protected:
     /**
-     * Subclasses call this from their constructor to register GrTextureAcceses. The effect subclass
-     * manages the lifetime of the accesses (this function only stores a pointer). This must only be
-     * called from the constructor because GrEffects are supposed to be immutable.
+     * Subclasses call this from their constructor to register GrTextureAccesses. The effect 
+     * subclass manages the lifetime of the accesses (this function only stores a pointer). This 
+     * must only be called from the constructor because GrEffects are immutable.
      */
     void addTextureAccess(const GrTextureAccess* textureAccess);
 
+    /**
+     * Subclasses call this from their constructor to register vertex attributes (at most 
+     * kMaxVertexAttribs). This must only be called from the constructor because GrEffects are 
+     * immutable.
+     */
+    void addVertexAttrib(GrSLType type);
+
     GrEffect() : fEffectRef(NULL) {};
 
     /** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for
@@ -246,8 +262,9 @@
                                 // from deferred state, to call isEqual on naked GrEffects, and
                                 // to inc/dec deferred ref counts.
 
-    SkSTArray<4, const GrTextureAccess*, true>  fTextureAccesses;
-    GrEffectRef*                                fEffectRef;
+    SkSTArray<4, const GrTextureAccess*, true>   fTextureAccesses;
+    SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes;
+    GrEffectRef*                                 fEffectRef;
 
     typedef GrRefCnt INHERITED;
 };
diff --git a/include/gpu/GrEffectStage.h b/include/gpu/GrEffectStage.h
index 05bc313..05bf40c 100644
--- a/include/gpu/GrEffectStage.h
+++ b/include/gpu/GrEffectStage.h
@@ -116,6 +116,7 @@
                 stage.fEffectRef->get()->incDeferredRefCounts();
                 fEffect = stage.fEffectRef->get();
                 fCoordChangeMatrix = stage.fCoordChangeMatrix;
+                fVertexAttribIndices = stage.fVertexAttribIndices;
             }
             SkDEBUGCODE(fInitialized = true;)
         }
@@ -126,6 +127,7 @@
             if (NULL != fEffect) {
                 stage->fEffectRef = GrEffect::CreateEffectRef(fEffect);
                 stage->fCoordChangeMatrix = fCoordChangeMatrix;
+                stage->fVertexAttribIndices = fVertexAttribIndices;
             } else {
                 stage->fEffectRef = NULL;
             }
@@ -139,16 +141,21 @@
                 return false;
             }
 
-            if (!(*stage.getEffect())->isEqual(*fEffect)) {
+            if (fVertexAttribIndices != stage.fVertexAttribIndices) {
                 return false;
             }
 
+            if (!(*stage.getEffect())->isEqual(*fEffect)) {	
+                return false;	
+            }
+
             return fCoordChangeMatrix == stage.fCoordChangeMatrix;
         }
 
     private:
         const GrEffect*               fEffect;
         SkMatrix                      fCoordChangeMatrix;
+        SkSTArray<GrEffect::kMaxVertexAttribs, int, true> fVertexAttribIndices;
         SkDEBUGCODE(bool fInitialized;)
     };
 
@@ -162,18 +169,28 @@
         GrSafeSetNull(fEffectRef);
     }
 
-    const GrEffectRef* setEffect(const GrEffectRef* EffectRef) {
+    const GrEffectRef* setEffect(const GrEffectRef* EffectRef, const int* attribIndices = NULL) {
         GrAssert(0 == fSavedCoordChangeCnt);
         GrSafeAssign(fEffectRef, EffectRef);
         fCoordChangeMatrix.reset();
+
+        fVertexAttribIndices.reset();
+        int numVertexAttribs = (EffectRef == NULL) ? 0 : EffectRef->get()->numVertexAttribs();
+        GrAssert(numVertexAttribs == 0 || attribIndices != NULL);
+        fVertexAttribIndices.push_back_n(numVertexAttribs, attribIndices);
+
         return EffectRef;
     }
 
     const GrEffectRef* getEffect() const { return fEffectRef; }
 
+    const int* getVertexAttribIndices() const { return fVertexAttribIndices.begin(); }
+    int getVertexAttribIndexCount() const { return fVertexAttribIndices.count(); }
+
 private:
-    SkMatrix            fCoordChangeMatrix;
-    const GrEffectRef*  fEffectRef;
+    SkMatrix                fCoordChangeMatrix;
+    const GrEffectRef*      fEffectRef;
+    SkSTArray<2, int, true> fVertexAttribIndices;
 
     GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;)
 };
diff --git a/include/gpu/GrTBackendEffectFactory.h b/include/gpu/GrTBackendEffectFactory.h
index 7ea7e39..72b2aea 100644
--- a/include/gpu/GrTBackendEffectFactory.h
+++ b/include/gpu/GrTBackendEffectFactory.h
@@ -35,14 +35,19 @@
         GrAssert(kIllegalEffectClassID != fEffectClassID);
         EffectKey effectKey = GLEffect::GenKey(stage, caps);
         EffectKey textureKey = GLEffect::GenTextureKey(stage.getEffect(), caps);
+        EffectKey attribKey = GLEffect::GenAttribKey(stage);
 #if GR_DEBUG
         static const EffectKey kIllegalIDMask = (uint16_t) (~((1U << kEffectKeyBits) - 1));
         GrAssert(!(kIllegalIDMask & effectKey));
 
         static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1));
         GrAssert(!(kIllegalTextureKeyMask & textureKey));
+
+        static const EffectKey kIllegalAttribKeyMask = (uint16_t) (~((1U << kAttribKeyBits) - 1));
+        GrAssert(!(kIllegalAttribKeyMask & textureKey));
 #endif
-        return fEffectClassID | (textureKey << kEffectKeyBits) | effectKey;
+        return fEffectClassID | (attribKey << (kEffectKeyBits+kTextureKeyBits)) | 
+               (textureKey << kEffectKeyBits) | effectKey;
     }
 
     /** Returns a new instance of the appropriate *GL* implementation class
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
new file mode 100644
index 0000000..fea80f8
--- /dev/null
+++ b/include/gpu/GrTypesPriv.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTypesPriv_DEFINED
+#define GrTypesPriv_DEFINED
+
+/**
+ * Types of shader-language-specific boxed variables we can create.
+ * (Currently only GrGLShaderVars, but should be applicable to other shader
+ * languages.)
+ */
+enum GrSLType {
+    kVoid_GrSLType,
+    kFloat_GrSLType,
+    kVec2f_GrSLType,
+    kVec3f_GrSLType,
+    kVec4f_GrSLType,
+    kMat33f_GrSLType,
+    kMat44f_GrSLType,
+    kSampler2D_GrSLType
+};
+
+#endif