Batch up draws into triangle fans as large as possible when drawing convex
edge AA polys, so we minimize state changes and GL calls.  This requires
querying GL for the maximum number of fragment uniforms.  It also makes the
shader generator produce custom shaders for the number of relevant edges. 
This gives a ~5X speedup on the "Shapes" SampleApp.

Review URL:  http://codereview.appspot.com/4536070/



git-svn-id: http://skia.googlecode.com/svn/trunk@1380 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
index 985cca7..e89a273 100644
--- a/gpu/include/GrDrawTarget.h
+++ b/gpu/include/GrDrawTarget.h
@@ -54,6 +54,17 @@
         kMaxTexCoords = kNumStages
     };
 
+
+    /**
+     * The absolute maximum number of edges that may be specified for
+     * a single draw call when performing edge antialiasing.  This is used for
+     * the size of several static buffers, so implementations of getMaxEdges()
+     * (below) should clamp to this value.
+     */
+    enum {
+        kMaxEdges = 32
+    };
+
     /**
      *  Bitfield used to indicate which stages are in use.
      */
@@ -78,9 +89,6 @@
         kNoColorWrites_StateBit = 0x08, //<! If set it disables writing colors.
                                         //   Useful while performing stencil
                                         //   ops.
-        kEdgeAA_StateBit        = 0x10, //<! Perform edge anti-aliasing.
-                                        //   Requires the edges to be passed in
-                                        //   setEdgeAAData().
 
         // subclass may use additional bits internally
         kDummyStateBit,
@@ -128,6 +136,20 @@
         fCurrDrawState.fStencilSettings.setDisabled();
     }
 
+    class Edge {
+      public:
+        Edge() {}
+        Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
+        GrPoint intersect(const Edge& other) {
+            return GrPoint::Make(
+                (fY * other.fZ - other.fY * fZ) /
+                  (fX * other.fY - other.fX * fY),
+                (fX * other.fZ - other.fX * fZ) /
+                  (other.fX * fY - fX * other.fY));
+        }
+        float fX, fY, fZ;
+    };
+
 protected:
 
     struct DrState {
@@ -164,7 +186,8 @@
 
         GrStencilSettings       fStencilSettings;
         GrMatrix                fViewMatrix;
-        float                   fEdgeAAEdges[18];
+        Edge                    fEdgeAAEdges[kMaxEdges];
+        int                     fEdgeAANumEdges;
         bool operator ==(const DrState& s) const {
             return 0 == memcmp(this, &s, sizeof(DrState));
         }
@@ -536,7 +559,7 @@
      * @param edges       3 * 6 float values, representing the edge
      *                    equations in Ax + By + C form
      */
-     void setEdgeAAData(const float edges[18]);
+     void setEdgeAAData(const Edge* edges, int numEdges);
 
 private:
     static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
@@ -804,6 +827,15 @@
      */
     virtual void clear(const GrIRect* rect, GrColor color) = 0;
 
+    /**
+     * Returns the maximum number of edges that may be specified in a single
+     * draw call when performing edge antialiasing.  This is usually limited
+     * by the number of fragment uniforms which may be uploaded.  Must be a
+     * minimum of six, since a triangle's vertices each belong to two boundary
+     * edges which may be distinct.
+     */
+    virtual int getMaxEdges() const { return 6; }
+
     ///////////////////////////////////////////////////////////////////////////
 
     class AutoStateRestore : ::GrNoncopyable {