Implement filling a path with nv_path_rendering cover

Implement filling a path with nv_path_rendering cover functionality.

The nv_path_rendering cover can be used if the fill is non-inverted
and the draw operation does not require use of vertex shaders.

Moves code for the inverted fill from GrStencilAndCoverPathRenderer
down to GrGpuGL.

R=bsalomon@google.com, markkilgard@gmail.com, cdalton@nvidia.com

Author: kkinnunen@nvidia.com

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

git-svn-id: http://skia.googlecode.com/svn/trunk@11667 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 8c8fbfc..dbbdf16 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -385,6 +385,7 @@
 }
 
 GrInOrderDrawBuffer::StencilPath::StencilPath() : fStroke(SkStrokeRec::kFill_InitStyle) {}
+GrInOrderDrawBuffer::FillPath::FillPath() : fStroke(SkStrokeRec::kFill_InitStyle) {}
 
 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStrokeRec& stroke,
                                         SkPath::FillType fill) {
@@ -402,6 +403,25 @@
     sp->fStroke = stroke;
 }
 
+void GrInOrderDrawBuffer::onFillPath(const GrPath* path, const SkStrokeRec& stroke,
+                                     SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) {
+    if (this->needsNewClip()) {
+        this->recordClip();
+    }
+    // TODO: Only compare the subset of GrDrawState relevant to path covering?
+    if (this->needsNewState()) {
+        this->recordState();
+    }
+    FillPath* cp = this->recordFillPath();
+    cp->fPath.reset(path);
+    path->ref();
+    cp->fFill = fill;
+    cp->fStroke = stroke;
+    if (NULL != dstCopy) {
+        cp->fDstCopy = *dstCopy;
+    }
+}
+
 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, GrRenderTarget* renderTarget) {
     SkIRect r;
     if (NULL == renderTarget) {
@@ -436,6 +456,7 @@
     fCmds.reset();
     fDraws.reset();
     fStencilPaths.reset();
+    fFillPaths.reset();
     fStates.reset();
     fClears.reset();
     fVertexPool.reset();
@@ -480,6 +501,7 @@
     int currClear       = 0;
     int currDraw        = 0;
     int currStencilPath = 0;
+    int currFillPath    = 0;
     int currCopySurface = 0;
 
     for (int c = 0; c < numCmds; ++c) {
@@ -501,6 +523,13 @@
                 ++currStencilPath;
                 break;
             }
+            case kFillPath_Cmd: {
+                const FillPath& cp = fFillPaths[currFillPath];
+                fDstGpu->executeFillPath(cp.fPath.get(), cp.fStroke, cp.fFill,
+                                         NULL != cp.fDstCopy.texture() ? &cp.fDstCopy : NULL);
+                ++currFillPath;
+                break;
+            }
             case kSetState_Cmd:
                 fStates[currState].restoreTo(&playbackState);
                 ++currState;
@@ -810,6 +839,11 @@
     return &fStencilPaths.push_back();
 }
 
+GrInOrderDrawBuffer::FillPath* GrInOrderDrawBuffer::recordFillPath() {
+    fCmds.push_back(kFillPath_Cmd);
+    return &fFillPaths.push_back();
+}
+
 GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
     fCmds.push_back(kClear_Cmd);
     return &fClears.push_back();