| Index: src/gpu/gl/GrGpuGL.cpp
 | 
| diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
 | 
| index 4f4bb0f93f51c40af99e37a361f822e2267892cf..b4111950c1ab6276a744c7df69cfa3967efa534d 100644
 | 
| --- a/src/gpu/gl/GrGpuGL.cpp
 | 
| +++ b/src/gpu/gl/GrGpuGL.cpp
 | 
| @@ -356,6 +356,10 @@ void GrGpuGL::onResetContext(uint32_t resetBits) {
 | 
|          fHWStencilTestEnabled = kUnknown_TriState;
 | 
|      }
 | 
|  
 | 
| +    if (resetBits & kPathRendering_GrGLBackendState && this->glCaps().pathRenderingSupport()) {
 | 
| +        fHWPathStencilSettings.invalidate();
 | 
| +    }
 | 
| +
 | 
|      // Vertex
 | 
|      if (resetBits & kVertex_GrGLBackendState) {
 | 
|          fHWGeometryState.invalidate();
 | 
| @@ -1270,7 +1274,7 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
 | 
|  }
 | 
|  
 | 
|  GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) {
 | 
| -    SkASSERT(this->caps()->pathStencilingSupport());
 | 
| +    SkASSERT(this->caps()->pathRenderingSupport());
 | 
|      return SkNEW_ARGS(GrGLPath, (this, inPath));
 | 
|  }
 | 
|  
 | 
| @@ -1680,62 +1684,93 @@ const GrStencilSettings& even_odd_nv_path_stencil_settings() {
 | 
|          kOnes16, kOnes16, kOnes16);
 | 
|      return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
 | 
|  }
 | 
| +GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
 | 
| +    switch (op) {
 | 
| +        default:
 | 
| +            GrCrash("Unexpected path fill.");
 | 
| +            /* fallthrough */;
 | 
| +        case kIncClamp_StencilOp:
 | 
| +            return GR_GL_COUNT_UP;
 | 
| +        case kInvert_StencilOp:
 | 
| +            return GR_GL_INVERT;
 | 
| +    }
 | 
| +}
 | 
|  }
 | 
|  
 | 
| -void GrGpuGL::setStencilPathSettings(const GrPath&,
 | 
| -                                     SkPath::FillType fill,
 | 
| -                                     GrStencilSettings* settings) {
 | 
| +const GrStencilSettings& GrGpuGL::getPathStencilSettingsForFillType(SkPath::FillType fill) {
 | 
|      switch (fill) {
 | 
| -        case SkPath::kEvenOdd_FillType:
 | 
| -            *settings = even_odd_nv_path_stencil_settings();
 | 
| -            return;
 | 
| -        case SkPath::kWinding_FillType:
 | 
| -            *settings = winding_nv_path_stencil_settings();
 | 
| -            return;
 | 
|          default:
 | 
|              GrCrash("Unexpected path fill.");
 | 
| +            /* fallthrough */;
 | 
| +        case SkPath::kWinding_FillType:
 | 
| +        case SkPath::kInverseWinding_FillType:
 | 
| +            return winding_nv_path_stencil_settings();
 | 
| +        case SkPath::kEvenOdd_FillType:
 | 
| +        case SkPath::kInverseEvenOdd_FillType:
 | 
| +            return even_odd_nv_path_stencil_settings();
 | 
|      }
 | 
|  }
 | 
|  
 | 
|  void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) {
 | 
| -    SkASSERT(this->caps()->pathStencilingSupport());
 | 
| +    SkASSERT(this->caps()->pathRenderingSupport());
 | 
|  
 | 
|      GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
 | 
|      GrDrawState* drawState = this->drawState();
 | 
|      SkASSERT(NULL != drawState->getRenderTarget());
 | 
| -    if (NULL == drawState->getRenderTarget()->getStencilBuffer()) {
 | 
| -        return;
 | 
| -    }
 | 
| +    SkASSERT(NULL != drawState->getRenderTarget()->getStencilBuffer());
 | 
|  
 | 
|      // Decide how to manipulate the stencil buffer based on the fill rule.
 | 
| -    // Also, assert that the stencil settings we set in setStencilPathSettings
 | 
| -    // are present.
 | 
| -    SkASSERT(!fStencilSettings.isTwoSided());
 | 
| -    GrGLenum fillMode;
 | 
| -    switch (fill) {
 | 
| -        case SkPath::kWinding_FillType:
 | 
| -            fillMode = GR_GL_COUNT_UP;
 | 
| -            SkASSERT(kIncClamp_StencilOp ==
 | 
| -                     fStencilSettings.passOp(GrStencilSettings::kFront_Face));
 | 
| -            SkASSERT(kIncClamp_StencilOp ==
 | 
| -                     fStencilSettings.failOp(GrStencilSettings::kFront_Face));
 | 
| -            break;
 | 
| -        case SkPath::kEvenOdd_FillType:
 | 
| -            fillMode = GR_GL_INVERT;
 | 
| -            SkASSERT(kInvert_StencilOp ==
 | 
| -                     fStencilSettings.passOp(GrStencilSettings::kFront_Face));
 | 
| -            SkASSERT(kInvert_StencilOp ==
 | 
| -                fStencilSettings.failOp(GrStencilSettings::kFront_Face));
 | 
| -            break;
 | 
| -        default:
 | 
| -            // Only the above two fill rules are allowed.
 | 
| -            GrCrash("Unexpected path fill.");
 | 
| -            return; // suppress unused var warning.
 | 
| -    }
 | 
| -    GrGLint writeMask = fStencilSettings.writeMask(GrStencilSettings::kFront_Face);
 | 
| +    SkASSERT(!fPathStencilSettings.isTwoSided());
 | 
| +
 | 
| +    GrGLenum fillMode =
 | 
| +        gr_stencil_op_to_gl_path_rendering_fill_mode(fPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
 | 
| +    GrGLint writeMask = fPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
 | 
|      GL_CALL(StencilFillPath(id, fillMode, writeMask));
 | 
|  }
 | 
|  
 | 
| +void GrGpuGL::onGpuFillPath(const GrPath* path, SkPath::FillType fill) {
 | 
| +    SkASSERT(this->caps()->pathRenderingSupport());
 | 
| +
 | 
| +    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
 | 
| +    GrDrawState* drawState = this->drawState();
 | 
| +    SkASSERT(NULL != drawState->getRenderTarget());
 | 
| +    SkASSERT(NULL != drawState->getRenderTarget()->getStencilBuffer());
 | 
| +
 | 
| +    SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill);
 | 
| +    SkASSERT(!fPathStencilSettings.isTwoSided());
 | 
| +    GrGLenum fillMode =
 | 
| +        gr_stencil_op_to_gl_path_rendering_fill_mode(fPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
 | 
| +    GrGLint writeMask = fPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
 | 
| +    GL_CALL(StencilFillPath(id, fillMode, writeMask));
 | 
| +
 | 
| +    if (!fCurrentProgram->hasVertexShader() && nonInvertedFill == fill) {
 | 
| +        GL_CALL(CoverFillPath(id, GR_GL_BOUNDING_BOX));
 | 
| +    } else {
 | 
| +        GrDrawState::AutoViewMatrixRestore avmr;
 | 
| +        SkRect bounds;
 | 
| +        if (nonInvertedFill == fill) {
 | 
| +            bounds = path->getBounds();
 | 
| +        } else {
 | 
| +            bounds = SkRect::MakeLTRB(0, 0,
 | 
| +                                      SkIntToScalar(drawState->getRenderTarget()->width()),
 | 
| +                                      SkIntToScalar(drawState->getRenderTarget()->height()));
 | 
| +            SkMatrix vmi;
 | 
| +            // mapRect through persp matrix may not be correct
 | 
| +            if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
 | 
| +                vmi.mapRect(&bounds);
 | 
| +                // theoretically could set bloat = 0, instead leave it because of matrix inversion
 | 
| +                // precision.
 | 
| +                SkScalar bloat = drawState->getViewMatrix().getMaxStretch() * SK_ScalarHalf;
 | 
| +                bounds.outset(bloat, bloat);
 | 
| +            } else {
 | 
| +                avmr.setIdentity(drawState);
 | 
| +            }
 | 
| +        }
 | 
| +
 | 
| +        this->drawSimpleRect(bounds, NULL);
 | 
| +    }
 | 
| +}
 | 
| +
 | 
|  void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
 | 
|      GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
 | 
|      if (rt->needsResolve()) {
 | 
| @@ -1857,16 +1892,21 @@ void set_gl_stencil(const GrGLInterface* gl,
 | 
|  }
 | 
|  
 | 
|  void GrGpuGL::flushStencil(DrawType type) {
 | 
| -    if (kStencilPath_DrawType == type) {
 | 
| -        SkASSERT(!fStencilSettings.isTwoSided());
 | 
| +    if ((kStencilPath_DrawType == type || kFillPath_DrawType == type) &&
 | 
| +        fHWPathStencilSettings != fPathStencilSettings) {
 | 
| +
 | 
|          // Just the func, ref, and mask is set here. The op and write mask are params to the call
 | 
|          // that draws the path to the SB (glStencilFillPath)
 | 
|          GrGLenum func =
 | 
| -            gr_to_gl_stencil_func(fStencilSettings.func(GrStencilSettings::kFront_Face));
 | 
| +            gr_to_gl_stencil_func(fPathStencilSettings.func(GrStencilSettings::kFront_Face));
 | 
|          GL_CALL(PathStencilFunc(func,
 | 
| -                                fStencilSettings.funcRef(GrStencilSettings::kFront_Face),
 | 
| -                                fStencilSettings.funcMask(GrStencilSettings::kFront_Face)));
 | 
| -    } else if (fHWStencilSettings != fStencilSettings) {
 | 
| +                                fPathStencilSettings.funcRef(GrStencilSettings::kFront_Face),
 | 
| +                                fPathStencilSettings.funcMask(GrStencilSettings::kFront_Face)));
 | 
| +
 | 
| +        fHWPathStencilSettings = fPathStencilSettings;
 | 
| +    }
 | 
| +
 | 
| +    if (kStencilPath_DrawType != type && fHWStencilSettings != fStencilSettings) {
 | 
|          if (fStencilSettings.isDisabled()) {
 | 
|              if (kNo_TriState != fHWStencilTestEnabled) {
 | 
|                  GL_CALL(Disable(GR_GL_STENCIL_TEST));
 | 
| 
 |