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 {
diff --git a/gpu/include/GrGLDefines.h b/gpu/include/GrGLDefines.h
index 29e56f3..2e22803 100644
--- a/gpu/include/GrGLDefines.h
+++ b/gpu/include/GrGLDefines.h
@@ -318,6 +318,8 @@
#define GR_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GR_GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GR_GL_CURRENT_PROGRAM 0x8B8D
+#define GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GR_GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
/* StencilFunction */
#define GR_GL_NEVER 0x0200