Initial support for GL_NV_path_renering. Experimental, there are still some issues to resolve, set gyp variable skia_nv_path_rendering=1 or build flag GR_GL_USE_NV_PATH_RENDERING to enable.

http://codereview.appspot.com/6349049/



git-svn-id: http://skia.googlecode.com/svn/trunk@4390 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 26be361..18a25e6 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -8,12 +8,13 @@
 
 
 #include "GrInOrderDrawBuffer.h"
+#include "GrBufferAllocPool.h"
+#include "GrGpu.h"
+#include "GrIndexBuffer.h"
+#include "GrPath.h"
 #include "GrRenderTarget.h"
 #include "GrTexture.h"
-#include "GrBufferAllocPool.h"
-#include "GrIndexBuffer.h"
 #include "GrVertexBuffer.h"
-#include "GrGpu.h"
 
 GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
                                          GrVertexBufferAllocPool* vertexPool,
@@ -426,8 +427,18 @@
     draw->fIndexBuffer = NULL;
 }
 
-void GrInOrderDrawBuffer::onStencilPath(const GrPath&, GrPathFill) {
-    GrCrash("Not implemented yet. Should not get here.");
+void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
+    if (this->needsNewClip()) {
+        this->recordClip();
+    }
+    // Only compare the subset of GrDrawState relevant to path stenciling?
+    if (this->needsNewState()) {
+        this->recordState();
+    }
+    StencilPath* sp = this->recordStencilPath();
+    sp->fPath.reset(path);
+    path->ref();
+    sp->fFill = fill;
 }
 
 void GrInOrderDrawBuffer::clear(const GrIRect* rect, 
@@ -463,6 +474,7 @@
     }
     fCmds.reset();
     fDraws.reset();
+    fStencilPaths.reset();
     fStates.reset();
     fClears.reset();
     fVertexPool.reset();
@@ -502,10 +514,11 @@
     GrDrawState* prevDrawState = target->drawState();
     prevDrawState->ref();
 
-    int currState = 0;
-    int currClip  = 0;
-    int currClear = 0;
-    int currDraw  = 0;
+    int currState       = 0;
+    int currClip        = 0;
+    int currClear       = 0;
+    int currDraw        = 0;
+    int currStencilPath = 0;
 
     for (int c = 0; c < numCmds; ++c) {
         switch (fCmds[c]) {
@@ -530,6 +543,12 @@
                 ++currDraw;
                 break;
             }
+            case kStencilPath_Cmd: {
+                const StencilPath& sp = fStencilPaths[currStencilPath];
+                target->stencilPath(sp.fPath.get(), sp.fFill);
+                ++currStencilPath;
+                break;
+            }
             case kSetState_Cmd:
                 target->setDrawState(&fStates[currState]);
                 ++currState;
@@ -810,6 +829,11 @@
     return &fDraws.push_back();
 }
 
+GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
+    fCmds.push_back(kStencilPath_Cmd);
+    return &fStencilPaths.push_back();
+}
+
 GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
     fCmds.push_back(kClear_Cmd);
     return &fClears.push_back();