| Index: src/gpu/GrClipMaskManager.cpp | 
| diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp | 
| index 3168424cf8715a998b0f0aec94655d9021143b43..70c65ed70585c8b30a5e12e9b49237f26b14bbc1 100644 | 
| --- a/src/gpu/GrClipMaskManager.cpp | 
| +++ b/src/gpu/GrClipMaskManager.cpp | 
| @@ -8,7 +8,7 @@ | 
| #include "GrClipMaskManager.h" | 
| #include "GrCaps.h" | 
| #include "GrDrawingManager.h" | 
| -#include "GrDrawContext.h" | 
| +#include "GrDrawContextPriv.h" | 
| #include "GrDrawTarget.h" | 
| #include "GrGpuResourcePriv.h" | 
| #include "GrPaint.h" | 
| @@ -159,7 +159,8 @@ GrResourceProvider* GrClipMaskManager::resourceProvider() { | 
| * will be used on any element. If so, it returns true to indicate that the | 
| * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 
| */ | 
| -bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, | 
| +bool GrClipMaskManager::UseSWOnlyPath(GrContext* context, | 
| +                                      const GrPipelineBuilder& pipelineBuilder, | 
| const GrRenderTarget* rt, | 
| const SkVector& clipToMaskOffset, | 
| const GrReducedClip::ElementList& elements) { | 
| @@ -179,7 +180,7 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, | 
| bool needsStencil = invert || | 
| SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op; | 
|  | 
| -        if (PathNeedsSWRenderer(this->getContext(), pipelineBuilder.getStencil().isDisabled(), | 
| +        if (PathNeedsSWRenderer(context, pipelineBuilder.getStencil().isDisabled(), | 
| rt, translate, element, nullptr, needsStencil)) { | 
| return true; | 
| } | 
| @@ -316,6 +317,42 @@ static void add_rect_to_clip(const GrClip& clip, const SkRect& devRect, GrClip* | 
| } | 
| } | 
|  | 
| +bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilder, | 
| +                                         GrPipelineBuilder::AutoRestoreStencil* ars, | 
| +                                         const SkIRect& clipScissor, | 
| +                                         const SkRect* devBounds, | 
| +                                         GrAppliedClip* out) { | 
| +    if (kRespectClip_StencilClipMode == fClipMode) { | 
| +        fClipMode = kIgnoreClip_StencilClipMode; | 
| +    } | 
| + | 
| +    GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 
| + | 
| +    SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); | 
| +    SkIRect devBoundsScissor; | 
| +    const SkIRect* scissor = &clipScissor; | 
| +    bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds; | 
| +    if (doDevBoundsClip) { | 
| +        devBounds->roundOut(&devBoundsScissor); | 
| +        if (devBoundsScissor.intersect(clipScissor)) { | 
| +            scissor = &devBoundsScissor; | 
| +        } | 
| +    } | 
| + | 
| +    if (scissor->contains(clipSpaceRTIBounds)) { | 
| +        // This counts as wide open | 
| +        this->setPipelineBuilderStencil(pipelineBuilder, ars); | 
| +        return true; | 
| +    } | 
| + | 
| +    if (clipSpaceRTIBounds.intersect(*scissor)) { | 
| +        out->fScissorState.set(clipSpaceRTIBounds); | 
| +        this->setPipelineBuilderStencil(pipelineBuilder, ars); | 
| +        return true; | 
| +    } | 
| +    return false; | 
| +} | 
| + | 
| //////////////////////////////////////////////////////////////////////////////// | 
| // sort out what kind of clip mask needs to be created: alpha, stencil, | 
| // scissor, or entirely software | 
| @@ -439,21 +476,23 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, | 
| SkIntToScalar(-clipSpaceIBounds.fTop) | 
| }; | 
|  | 
| -        if (this->useSWOnlyPath(pipelineBuilder, rt, clipToMaskOffset, elements)) { | 
| +        if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOffset, elements)) { | 
| // The clip geometry is complex enough that it will be more efficient to create it | 
| // entirely in software | 
| -            result.reset(this->createSoftwareClipMask(genID, | 
| -                                                      initialState, | 
| -                                                      elements, | 
| -                                                      clipToMaskOffset, | 
| -                                                      clipSpaceIBounds)); | 
| +            result.reset(CreateSoftwareClipMask(this->getContext(), | 
| +                                                genID, | 
| +                                                initialState, | 
| +                                                elements, | 
| +                                                clipToMaskOffset, | 
| +                                                clipSpaceIBounds)); | 
| } else { | 
| -            result.reset(this->createAlphaClipMask(genID, | 
| -                                                   initialState, | 
| -                                                   elements, | 
| -                                                   clipToMaskOffset, | 
| -                                                   clipSpaceIBounds)); | 
| -            // If createAlphaClipMask fails it means useSWOnlyPath has a bug | 
| +            result.reset(CreateAlphaClipMask(this->getContext(), | 
| +                                             genID, | 
| +                                             initialState, | 
| +                                             elements, | 
| +                                             clipToMaskOffset, | 
| +                                             clipSpaceIBounds)); | 
| +            // If createAlphaClipMask fails it means UseSWOnlyPath has a bug | 
| SkASSERT(result); | 
| } | 
|  | 
| @@ -488,93 +527,67 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, | 
| return true; | 
| } | 
|  | 
| -namespace { | 
| -//////////////////////////////////////////////////////////////////////////////// | 
| -// Set a coverage drawing XPF on the pipelineBuilder for the given op and invertCoverage mode | 
| -void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, | 
| -                              GrPipelineBuilder* pipelineBuilder) { | 
| -    SkASSERT(op <= SkRegion::kLastOp); | 
| -    pipelineBuilder->setCoverageSetOpXPFactory(op, invertCoverage); | 
| -} | 
| -} | 
| +static bool stencil_element(GrDrawContext* dc, | 
| +                            const SkIRect* scissorRect, | 
| +                            const GrStencilSettings& ss, | 
| +                            const SkMatrix& viewMatrix, | 
| +                            const SkClipStack::Element* element) { | 
|  | 
| -//////////////////////////////////////////////////////////////////////////////// | 
| -bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder, | 
| -                                    const SkMatrix& viewMatrix, | 
| -                                    GrTexture* target, | 
| -                                    const SkClipStack::Element* element, | 
| -                                    GrPathRenderer* pr) { | 
| +    // TODO: Draw rrects directly here. | 
| +    switch (element->getType()) { | 
| +        case Element::kEmpty_Type: | 
| +            SkDEBUGFAIL("Should never get here with an empty element."); | 
| +            break; | 
| +        case Element::kRect_Type: | 
| +            return dc->drawContextPriv().drawAndStencilRect(scissorRect, ss, | 
| +                                                            element->getOp(), | 
| +                                                            element->isInverseFilled(), | 
| +                                                            element->isAA(), | 
| +                                                            viewMatrix, element->getRect()); | 
| +            break; | 
| +        default: { | 
| +            SkPath path; | 
| +            element->asPath(&path); | 
| +            if (path.isInverseFillType()) { | 
| +                path.toggleInverseFillType(); | 
| +            } | 
| + | 
| +            return dc->drawContextPriv().drawAndStencilPath(scissorRect, ss, | 
| +                                                            element->getOp(), | 
| +                                                            element->isInverseFilled(), | 
| +                                                            element->isAA(), viewMatrix, path); | 
| +            break; | 
| +        } | 
| +    } | 
|  | 
| -    GrRenderTarget* rt = target->asRenderTarget(); | 
| -    pipelineBuilder->setRenderTarget(rt); | 
| +    return false; | 
| +} | 
|  | 
| -    // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP | 
| -    // which ignores color. | 
| -    GrColor color = GrColor_WHITE; | 
| +static void draw_element(GrDrawContext* dc, | 
| +                         const GrClip& clip, // TODO: can this just always be WideOpen? | 
| +                         const GrPaint &paint, | 
| +                         const SkMatrix& viewMatrix, | 
| +                         const SkClipStack::Element* element) { | 
|  | 
| // TODO: Draw rrects directly here. | 
| switch (element->getType()) { | 
| case Element::kEmpty_Type: | 
| SkDEBUGFAIL("Should never get here with an empty element."); | 
| break; | 
| -        case Element::kRect_Type: { | 
| -            // TODO: Do rects directly to the accumulator using a aa-rect GrProcessor that covers | 
| -            // the entire mask bounds and writes 0 outside the rect. | 
| -            if (element->isAA()) { | 
| -                SkRect devRect = element->getRect(); | 
| -                viewMatrix.mapRect(&devRect); | 
| - | 
| -                SkAutoTUnref<GrDrawBatch> batch( | 
| -                        GrRectBatchFactory::CreateAAFill(color, viewMatrix, element->getRect(), | 
| -                                                         devRect)); | 
| - | 
| -                fDrawTarget->drawBatch(*pipelineBuilder, batch); | 
| -            } else { | 
| -                draw_non_aa_rect(fDrawTarget, *pipelineBuilder, color, viewMatrix, | 
| -                                 element->getRect()); | 
| -            } | 
| -            return true; | 
| -        } | 
| +        case Element::kRect_Type: | 
| +            dc->drawRect(clip, paint, viewMatrix, element->getRect()); | 
| +            break; | 
| default: { | 
| SkPath path; | 
| element->asPath(&path); | 
| if (path.isInverseFillType()) { | 
| path.toggleInverseFillType(); | 
| } | 
| -            GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 
| -            if (nullptr == pr) { | 
| -                GrPathRendererChain::DrawType type; | 
| -                type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : | 
| -                                         GrPathRendererChain::kColor_DrawType; | 
|  | 
| -                GrPathRenderer::CanDrawPathArgs canDrawArgs; | 
| -                canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps(); | 
| -                canDrawArgs.fViewMatrix = &viewMatrix; | 
| -                canDrawArgs.fPath = &path; | 
| -                canDrawArgs.fStroke = &stroke; | 
| -                canDrawArgs.fAntiAlias = element->isAA();; | 
| -                canDrawArgs.fIsStencilDisabled = pipelineBuilder->getStencil().isDisabled(); | 
| -                canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); | 
| - | 
| -                pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false, type); | 
| -            } | 
| -            if (nullptr == pr) { | 
| -                return false; | 
| -            } | 
| -            GrPathRenderer::DrawPathArgs args; | 
| -            args.fTarget = fDrawTarget; | 
| -            args.fResourceProvider = this->getContext()->resourceProvider(); | 
| -            args.fPipelineBuilder = pipelineBuilder; | 
| -            args.fColor = color; | 
| -            args.fViewMatrix = &viewMatrix; | 
| -            args.fPath = &path; | 
| -            args.fStroke = &stroke; | 
| -            args.fAntiAlias = element->isAA(); | 
| -            pr->drawPath(args); | 
| +            dc->drawPath(clip, paint, viewMatrix, path, GrStrokeInfo::FillInfo()); | 
| break; | 
| } | 
| } | 
| -    return true; | 
| } | 
|  | 
| //////////////////////////////////////////////////////////////////////////////// | 
| @@ -588,32 +601,13 @@ static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey | 
| builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); | 
| } | 
|  | 
| -GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUniqueKey& key, | 
| -                                               bool renderTarget) { | 
| -    GrSurfaceDesc desc; | 
| -    desc.fWidth = width; | 
| -    desc.fHeight = height; | 
| -    desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags; | 
| -    if (!renderTarget || this->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { | 
| -        desc.fConfig = kAlpha_8_GrPixelConfig; | 
| -    } else { | 
| -        desc.fConfig = kRGBA_8888_GrPixelConfig; | 
| -    } | 
| - | 
| -    GrTexture* texture = this->resourceProvider()->createApproxTexture(desc, 0); | 
| -    if (!texture) { | 
| -        return nullptr; | 
| -    } | 
| -    texture->resourcePriv().setUniqueKey(key); | 
| -    return texture; | 
| -} | 
| - | 
| -GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 
| +GrTexture* GrClipMaskManager::CreateAlphaClipMask(GrContext* context, | 
| +                                                  int32_t elementsGenID, | 
| GrReducedClip::InitialState initialState, | 
| const GrReducedClip::ElementList& elements, | 
| const SkVector& clipToMaskOffset, | 
| const SkIRect& clipSpaceIBounds) { | 
| -    GrResourceProvider* resourceProvider = this->resourceProvider(); | 
| +    GrResourceProvider* resourceProvider = context->resourceProvider(); | 
| GrUniqueKey key; | 
| GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); | 
| if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) { | 
| @@ -621,15 +615,27 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 
| } | 
|  | 
| // There's no texture in the cache. Let's try to allocate it then. | 
| -    SkAutoTUnref<GrTexture> texture(this->createCachedMask( | 
| -        clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); | 
| +    GrSurfaceDesc desc; | 
| +    desc.fWidth = clipSpaceIBounds.width(); | 
| +    desc.fHeight = clipSpaceIBounds.height(); | 
| +    desc.fFlags = kRenderTarget_GrSurfaceFlag; | 
| +    if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { | 
| +        desc.fConfig = kAlpha_8_GrPixelConfig; | 
| +    } else { | 
| +        desc.fConfig = kRGBA_8888_GrPixelConfig; | 
| +    } | 
| + | 
| +    SkAutoTUnref<GrTexture> texture(resourceProvider->createApproxTexture(desc, 0)); | 
| if (!texture) { | 
| return nullptr; | 
| } | 
|  | 
| -    // Set the matrix so that rendered clip elements are transformed to mask space from clip | 
| -    // space. | 
| -    const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY); | 
| +    texture->resourcePriv().setUniqueKey(key); | 
| + | 
| +    SkAutoTUnref<GrDrawContext> dc(context->drawContext(texture->asRenderTarget())); | 
| +    if (!dc) { | 
| +        return nullptr; | 
| +    } | 
|  | 
| // The texture may be larger than necessary, this rect represents the part of the texture | 
| // we populate with a rasterization of the clip. | 
| @@ -637,16 +643,18 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 
|  | 
| // The scratch texture that we are drawing into can be substantially larger than the mask. Only | 
| // clear the part that we care about. | 
| -    fDrawTarget->clear(&maskSpaceIBounds, | 
| -                       GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, | 
| -                       true, | 
| -                       texture->asRenderTarget()); | 
| +    dc->clear(&maskSpaceIBounds, | 
| +              GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, | 
| +              true); | 
|  | 
| -    // When we use the stencil in the below loop it is important to have this clip installed. | 
| +    // Set the matrix so that rendered clip elements are transformed to mask space from clip | 
| +    // space. | 
| +    const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY); | 
| + | 
| +    // It is important that we use maskSpaceIBounds as the stencil rect in the below loop. | 
| // The second pass that zeros the stencil buffer renders the rect maskSpaceIBounds so the first | 
| // pass must not set values outside of this bounds or stencil values outside the rect won't be | 
| // cleared. | 
| -    const GrClip clip(maskSpaceIBounds); | 
|  | 
| // walk through each clip element and perform its set op | 
| for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) { | 
| @@ -654,68 +662,54 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 
| SkRegion::Op op = element->getOp(); | 
| bool invert = element->isInverseFilled(); | 
| if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { | 
| - | 
| -            GrPathRenderer* pr = GetPathRenderer(this->getContext(), | 
| +#ifdef SK_DEBUG | 
| +            GrPathRenderer* pr = GetPathRenderer(context, | 
| texture, translate, element); | 
| if (Element::kRect_Type != element->getType() && !pr) { | 
| -                // useSWOnlyPath should now filter out all cases where gpu-side mask merging would | 
| -                // be performed (i.e., pr would be NULL for a non-rect path). See https://bug.skia.org/4519 | 
| -                // for rationale and details. | 
| +                // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would | 
| +                // be performed (i.e., pr would be NULL for a non-rect path). | 
| +                // See https://bug.skia.org/4519 for rationale and details. | 
| SkASSERT(0); | 
| -                continue; | 
| } | 
| - | 
| -            { | 
| -                GrPipelineBuilder pipelineBuilder; | 
| - | 
| -                pipelineBuilder.setClip(clip); | 
| -                pipelineBuilder.setRenderTarget(texture->asRenderTarget()); | 
| -                SkASSERT(pipelineBuilder.getStencil().isDisabled()); | 
| - | 
| -                // draw directly into the result with the stencil set to make the pixels affected | 
| -                // by the clip shape be non-zero. | 
| -                GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | 
| -                                             kReplace_StencilOp, | 
| -                                             kReplace_StencilOp, | 
| -                                             kAlways_StencilFunc, | 
| -                                             0xffff, | 
| -                                             0xffff, | 
| -                                             0xffff); | 
| -                pipelineBuilder.setStencil(kStencilInElement); | 
| -                set_coverage_drawing_xpf(op, invert, &pipelineBuilder); | 
| - | 
| -                if (!this->drawElement(&pipelineBuilder, translate, texture, element, pr)) { | 
| -                    texture->resourcePriv().removeUniqueKey(); | 
| -                    return nullptr; | 
| -                } | 
| +#endif | 
| + | 
| +            // draw directly into the result with the stencil set to make the pixels affected | 
| +            // by the clip shape be non-zero. | 
| +            GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | 
| +                                         kReplace_StencilOp, | 
| +                                         kReplace_StencilOp, | 
| +                                         kAlways_StencilFunc, | 
| +                                         0xffff, | 
| +                                         0xffff, | 
| +                                         0xffff) | 
| +            if (!stencil_element(dc, &maskSpaceIBounds, kStencilInElement, | 
| +                                 translate, element)) { | 
| +                texture->resourcePriv().removeUniqueKey(); | 
| +                return nullptr; | 
| } | 
|  | 
| -            { | 
| -                GrPipelineBuilder backgroundPipelineBuilder; | 
| -                backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarget()); | 
| - | 
| -                set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder); | 
| -                // Draw to the exterior pixels (those with a zero stencil value). | 
| -                GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 
| -                                             kZero_StencilOp, | 
| -                                             kZero_StencilOp, | 
| -                                             kEqual_StencilFunc, | 
| -                                             0xffff, | 
| -                                             0x0000, | 
| -                                             0xffff); | 
| -                backgroundPipelineBuilder.setStencil(kDrawOutsideElement); | 
| - | 
| -                // The color passed in here does not matter since the coverageSetOpXP won't read it. | 
| -                draw_non_aa_rect(fDrawTarget, backgroundPipelineBuilder, GrColor_WHITE, translate, | 
| -                                 SkRect::Make(clipSpaceIBounds)); | 
| +            // Draw to the exterior pixels (those with a zero stencil value). | 
| +            GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 
| +                                         kZero_StencilOp, | 
| +                                         kZero_StencilOp, | 
| +                                         kEqual_StencilFunc, | 
| +                                         0xffff, | 
| +                                         0x0000, | 
| +                                         0xffff); | 
| +            if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDrawOutsideElement, | 
| +                                                          op, !invert, false, | 
| +                                                          translate, | 
| +                                                          SkRect::Make(clipSpaceIBounds))) { | 
| +                texture->resourcePriv().removeUniqueKey(); | 
| +                return nullptr; | 
| } | 
| } else { | 
| -            GrPipelineBuilder pipelineBuilder; | 
| - | 
| // all the remaining ops can just be directly draw into the accumulation buffer | 
| -            set_coverage_drawing_xpf(op, false, &pipelineBuilder); | 
| -            // The color passed in here does not matter since the coverageSetOpXP won't read it. | 
| -            this->drawElement(&pipelineBuilder, translate, texture, element); | 
| +            GrPaint paint; | 
| +            paint.setAntiAlias(element->isAA()); | 
| +            paint.setCoverageSetOpXPFactory(op, false); | 
| + | 
| +            draw_element(dc, GrClip::WideOpen(), paint, translate, element); | 
| } | 
| } | 
|  | 
| @@ -1081,14 +1075,15 @@ void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 
| } | 
|  | 
| //////////////////////////////////////////////////////////////////////////////// | 
| -GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 
| +GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context, | 
| +                                                     int32_t elementsGenID, | 
| GrReducedClip::InitialState initialState, | 
| const GrReducedClip::ElementList& elements, | 
| const SkVector& clipToMaskOffset, | 
| const SkIRect& clipSpaceIBounds) { | 
| GrUniqueKey key; | 
| GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); | 
| -    GrResourceProvider* resourceProvider = this->resourceProvider(); | 
| +    GrResourceProvider* resourceProvider = context->resourceProvider(); | 
| if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) { | 
| return texture; | 
| } | 
| @@ -1097,7 +1092,7 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 
| // the top left corner of the resulting rect to the top left of the texture. | 
| SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpaceIBounds.height()); | 
|  | 
| -    GrSWMaskHelper helper(this->getContext()); | 
| +    GrSWMaskHelper helper(context); | 
|  | 
| // Set the matrix so that rendered clip elements are transformed to mask space from clip | 
| // space. | 
| @@ -1141,11 +1136,17 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 
| } | 
|  | 
| // Allocate clip mask texture | 
| -    GrTexture* result = this->createCachedMask(clipSpaceIBounds.width(), clipSpaceIBounds.height(), | 
| -                                               key, false); | 
| -    if (nullptr == result) { | 
| +    GrSurfaceDesc desc; | 
| +    desc.fWidth = clipSpaceIBounds.width(); | 
| +    desc.fHeight = clipSpaceIBounds.height(); | 
| +    desc.fConfig = kAlpha_8_GrPixelConfig; | 
| + | 
| +    GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0); | 
| +    if (!result) { | 
| return nullptr; | 
| } | 
| +    result->resourcePriv().setUniqueKey(key); | 
| + | 
| helper.toTexture(result); | 
|  | 
| return result; | 
|  |