Clip in grdrawtarget

NOTREECHECKS=true
BUG=skia:

Review URL: https://codereview.chromium.org/685883003
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 08a62a5..89300f7 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -451,6 +451,14 @@
                                int indexCount,
                                const SkRect* devBounds) {
     if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
+        // Setup clip
+        GrClipMaskManager::ScissorState scissorState;
+        GrDrawState::AutoRestoreEffects are;
+        GrDrawState::AutoRestoreStencil ars;
+        if (!this->setupClip(devBounds, &are, &ars, &scissorState)) {
+            return;
+        }
+
         DrawInfo info;
         info.fPrimitiveType = type;
         info.fStartVertex   = startVertex;
@@ -469,7 +477,7 @@
         if (!this->setupDstReadIfNecessary(&info)) {
             return;
         }
-        this->onDraw(info);
+        this->onDraw(info, scissorState);
     }
 }
 
@@ -478,6 +486,14 @@
                                   int vertexCount,
                                   const SkRect* devBounds) {
     if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
+        // Setup clip
+        GrClipMaskManager::ScissorState scissorState;
+        GrDrawState::AutoRestoreEffects are;
+        GrDrawState::AutoRestoreStencil ars;
+        if (!this->setupClip(devBounds, &are, &ars, &scissorState)) {
+            return;
+        }
+
         DrawInfo info;
         info.fPrimitiveType = type;
         info.fStartVertex   = startVertex;
@@ -492,19 +508,67 @@
         if (devBounds) {
             info.setDevBounds(*devBounds);
         }
+
         // TODO: We should continue with incorrect blending.
         if (!this->setupDstReadIfNecessary(&info)) {
             return;
         }
-        this->onDraw(info);
+        this->onDraw(info, scissorState);
     }
 }
 
+static const GrStencilSettings& winding_path_stencil_settings() {
+    GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
+        kIncClamp_StencilOp,
+        kIncClamp_StencilOp,
+        kAlwaysIfInClip_StencilFunc,
+        0xFFFF, 0xFFFF, 0xFFFF);
+    return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
+}
+
+static const GrStencilSettings& even_odd_path_stencil_settings() {
+    GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
+        kInvert_StencilOp,
+        kInvert_StencilOp,
+        kAlwaysIfInClip_StencilFunc,
+        0xFFFF, 0xFFFF, 0xFFFF);
+    return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
+}
+
+void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType fill,
+                                                     GrStencilSettings* outStencilSettings) {
+
+    switch (fill) {
+        default:
+            SkFAIL("Unexpected path fill.");
+        case GrPathRendering::kWinding_FillType:
+            *outStencilSettings = winding_path_stencil_settings();
+            break;
+        case GrPathRendering::kEvenOdd_FillType:
+            *outStencilSettings = even_odd_path_stencil_settings();
+            break;
+    }
+    this->clipMaskManager()->adjustPathStencilParams(outStencilSettings);
+}
+
 void GrDrawTarget::stencilPath(const GrPath* path, GrPathRendering::FillType fill) {
     // TODO: extract portions of checkDraw that are relevant to path stenciling.
     SkASSERT(path);
     SkASSERT(this->caps()->pathRenderingSupport());
-    this->onStencilPath(path, fill);
+
+    // Setup clip
+    GrClipMaskManager::ScissorState scissorState;
+    GrDrawState::AutoRestoreEffects are;
+    GrDrawState::AutoRestoreStencil ars;
+    if (!this->setupClip(NULL, &are, &ars, &scissorState)) {
+        return;
+    }
+
+    // set stencil settings for path
+    GrStencilSettings stencilSettings;
+    this->getPathStencilSettingsForFilltype(fill, &stencilSettings);
+
+    this->onStencilPath(path, scissorState, stencilSettings);
 }
 
 void GrDrawTarget::drawPath(const GrPath* path, GrPathRendering::FillType fill) {
@@ -516,12 +580,24 @@
     SkMatrix viewM = this->drawState()->getViewMatrix();
     viewM.mapRect(&devBounds);
 
+    // Setup clip
+    GrClipMaskManager::ScissorState scissorState;
+    GrDrawState::AutoRestoreEffects are;
+    GrDrawState::AutoRestoreStencil ars;
+    if (!this->setupClip(&devBounds, &are, &ars, &scissorState)) {
+       return;
+    }
+
+    // set stencil settings for path
+    GrStencilSettings stencilSettings;
+    this->getPathStencilSettingsForFilltype(fill, &stencilSettings);
+
     GrDeviceCoordTexture dstCopy;
     if (!this->setupDstReadIfNecessary(&dstCopy, &devBounds)) {
         return;
     }
 
-    this->onDrawPath(path, fill, dstCopy.texture() ? &dstCopy : NULL);
+    this->onDrawPath(path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
 }
 
 void GrDrawTarget::drawPaths(const GrPathRange* pathRange,
@@ -533,6 +609,19 @@
     SkASSERT(indices);
     SkASSERT(transforms);
 
+    // Setup clip
+    GrClipMaskManager::ScissorState scissorState;
+    GrDrawState::AutoRestoreEffects are;
+    GrDrawState::AutoRestoreStencil ars;
+
+    if (!this->setupClip(NULL, &are, &ars, &scissorState)) {
+        return;
+    }
+
+    // set stencil settings for path
+    GrStencilSettings stencilSettings;
+    this->getPathStencilSettingsForFilltype(fill, &stencilSettings);
+
     // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
     // instead for it to just copy the entire dst. Realistically this is a moot
     // point, because any context that supports NV_path_rendering will also
@@ -542,8 +631,8 @@
         return;
     }
 
-    this->onDrawPaths(pathRange, indices, count, transforms, transformsType, fill,
-                      dstCopy.texture() ? &dstCopy : NULL);
+    this->onDrawPaths(pathRange, indices, count, transforms, transformsType, scissorState,
+                      stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
 }
 
 void GrDrawTarget::clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
@@ -628,6 +717,14 @@
         return;
     }
 
+    // Setup clip
+    GrClipMaskManager::ScissorState scissorState;
+    GrDrawState::AutoRestoreEffects are;
+    GrDrawState::AutoRestoreStencil ars;
+    if (!this->setupClip(devBounds, &are, &ars, &scissorState)) {
+        return;
+    }
+
     DrawInfo info;
     info.fPrimitiveType = type;
     info.fStartIndex = 0;
@@ -654,7 +751,7 @@
                             info.fStartIndex,
                             info.fVertexCount,
                             info.fIndexCount)) {
-            this->onDraw(info);
+            this->onDraw(info, scissorState);
         }
         info.fStartVertex += info.fVertexCount;
         instanceCount -= info.fInstanceCount;
@@ -1141,3 +1238,15 @@
     return id;
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool GrClipTarget::setupClip(const SkRect* devBounds,
+                             GrDrawState::AutoRestoreEffects* are,
+                             GrDrawState::AutoRestoreStencil* ars,
+                             GrClipMaskManager::ScissorState* scissorState) {
+    return fClipMaskManager.setupClipping(this->getClip(),
+                                          devBounds,
+                                          are,
+                                          ars,
+                                          scissorState);
+}