Use vertexless shaders when NVpr is available

Adds support for vertexless shaders and enables them when
NV_path_rendering is available. This takes a
GrGLFragmentOnlyShaderBuilder class, a GrGLTexGenEffectArray class,
support for setting TexGen and the projection matrix in GrGpuGL, and
code for setting the GL fixed function state where necessary.

R=bsalomon@google.com, kkinnunen@nvidia.com

Author: cdalton@nvidia.com

Review URL: https://codereview.chromium.org/25846002

git-svn-id: http://skia.googlecode.com/svn/trunk@11620 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 8a3444e..92eed8d 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -210,28 +210,6 @@
 
 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
 
-void GrGpuGL::flushPathStencilMatrix() {
-    const SkMatrix& viewMatrix = this->getDrawState().getViewMatrix();
-    const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
-    SkISize size;
-    size.set(rt->width(), rt->height());
-    const SkMatrix& vm = this->getDrawState().getViewMatrix();
-
-    if (fHWProjectionMatrixState.fRenderTargetOrigin != rt->origin() ||
-        !fHWProjectionMatrixState.fViewMatrix.cheapEqualTo(viewMatrix) ||
-        fHWProjectionMatrixState.fRenderTargetSize!= size) {
-
-        fHWProjectionMatrixState.fViewMatrix = vm;
-        fHWProjectionMatrixState.fRenderTargetSize = size;
-        fHWProjectionMatrixState.fRenderTargetOrigin = rt->origin();
-
-        GrGLfloat projectionMatrix[4 * 4];
-        fHWProjectionMatrixState.getGLMatrix<4>(projectionMatrix);
-        GL_CALL(MatrixMode(GR_GL_PROJECTION));
-        GL_CALL(LoadMatrixf(projectionMatrix));
-    }
-}
-
 bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
     const GrDrawState& drawState = this->getDrawState();
 
@@ -239,7 +217,10 @@
     SkASSERT(NULL != drawState.getRenderTarget());
 
     if (kStencilPath_DrawType == type) {
-        this->flushPathStencilMatrix();
+        const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
+        SkISize size;
+        size.set(rt->width(), rt->height());
+        this->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
     } else {
         this->flushMiscFixedFunctionState();
 
@@ -360,24 +341,40 @@
     GrGLAttribArrayState* attribState =
         fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
 
-    uint32_t usedAttribArraysMask = 0;
-    const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
-    int vertexAttribCount = this->getDrawState().getVertexAttribCount();
-    for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
-         ++vertexAttribIndex, ++vertexAttrib) {
+    if (!fCurrentProgram->hasVertexShader()) {
+        int posIdx = this->getDrawState().positionAttributeIndex();
+        const GrVertexAttrib* vertexArray = this->getDrawState().getVertexAttribs() + posIdx;
+        GrVertexAttribType vertexArrayType = vertexArray->fType;
+        SkASSERT(!GrGLAttribTypeToLayout(vertexArrayType).fNormalized);
+        SkASSERT(GrGLAttribTypeToLayout(vertexArrayType).fCount == 2);
+        attribState->setFixedFunctionVertexArray(this,
+                                                 vbuf,
+                                                 2,
+                                                 GrGLAttribTypeToLayout(vertexArrayType).fType,
+                                                 stride,
+                                                 reinterpret_cast<GrGLvoid*>(
+                                                 vertexOffsetInBytes + vertexArray->fOffset));
+        attribState->disableUnusedArrays(this, 0, true);
+    } else {
+        uint32_t usedAttribArraysMask = 0;
+        const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
+        int vertexAttribCount = this->getDrawState().getVertexAttribCount();
+        for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
+             ++vertexAttribIndex, ++vertexAttrib) {
 
-        usedAttribArraysMask |= (1 << vertexAttribIndex);
-        GrVertexAttribType attribType = vertexAttrib->fType;
-        attribState->set(this,
-                         vertexAttribIndex,
-                         vbuf,
-                         GrGLAttribTypeToLayout(attribType).fCount,
-                         GrGLAttribTypeToLayout(attribType).fType,
-                         GrGLAttribTypeToLayout(attribType).fNormalized,
-                         stride,
-                         reinterpret_cast<GrGLvoid*>(
-                         vertexOffsetInBytes + vertexAttrib->fOffset));
+            usedAttribArraysMask |= (1 << vertexAttribIndex);
+            GrVertexAttribType attribType = vertexAttrib->fType;
+            attribState->set(this,
+                             vertexAttribIndex,
+                             vbuf,
+                             GrGLAttribTypeToLayout(attribType).fCount,
+                             GrGLAttribTypeToLayout(attribType).fType,
+                             GrGLAttribTypeToLayout(attribType).fNormalized,
+                             stride,
+                             reinterpret_cast<GrGLvoid*>(
+                             vertexOffsetInBytes + vertexAttrib->fOffset));
+        }
+
+        attribState->disableUnusedArrays(this, usedAttribArraysMask, false);
     }
-
-    attribState->disableUnusedArrays(this, usedAttribArraysMask, false);
 }