/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/GrSurfaceDrawContext.h"

#include "include/core/SkDrawable.h"
#include "include/core/SkVertices.h"
#include "include/gpu/GrBackendSemaphore.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/private/GrImageContext.h"
#include "include/private/SkShadowFlags.h"
#include "include/private/SkVx.h"
#include "include/utils/SkShadowUtils.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkDrawProcs.h"
#include "src/core/SkDrawShadowInfo.h"
#include "src/core/SkGlyphRunPainter.h"
#include "src/core/SkLatticeIter.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRRectPriv.h"
#include "src/gpu/GrAppliedClip.h"
#include "src/gpu/GrAttachment.h"
#include "src/gpu/GrBlurUtils.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrClip.h"
#include "src/gpu/GrColor.h"
#include "src/gpu/GrDataUtils.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrDrawingManager.h"
#include "src/gpu/GrGpuResourcePriv.h"
#include "src/gpu/GrImageContextPriv.h"
#include "src/gpu/GrImageInfo.h"
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrResourceProvider.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/GrStyle.h"
#include "src/gpu/GrTracing.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrBicubicEffect.h"
#include "src/gpu/effects/GrBlendFragmentProcessor.h"
#include "src/gpu/effects/GrDisableColorXP.h"
#include "src/gpu/effects/GrRRectEffect.h"
#include "src/gpu/effects/GrTextureEffect.h"
#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/geometry/GrQuadUtils.h"
#include "src/gpu/geometry/GrStyledShape.h"
#include "src/gpu/ops/GrAtlasTextOp.h"
#include "src/gpu/ops/GrClearOp.h"
#include "src/gpu/ops/GrDrawAtlasOp.h"
#include "src/gpu/ops/GrDrawOp.h"
#include "src/gpu/ops/GrDrawVerticesOp.h"
#include "src/gpu/ops/GrDrawableOp.h"
#include "src/gpu/ops/GrFillRRectOp.h"
#include "src/gpu/ops/GrFillRectOp.h"
#include "src/gpu/ops/GrLatticeOp.h"
#include "src/gpu/ops/GrOp.h"
#include "src/gpu/ops/GrOvalOpFactory.h"
#include "src/gpu/ops/GrRegionOp.h"
#include "src/gpu/ops/GrShadowRRectOp.h"
#include "src/gpu/ops/GrStrokeRectOp.h"
#include "src/gpu/ops/GrTextureOp.h"
#include "src/gpu/tessellate/GrTessellationPathRenderer.h"
#include "src/gpu/text/GrSDFTControl.h"
#include "src/gpu/text/GrTextBlobCache.h"

#if SK_GPU_V1
#include "src/gpu/GrPathRenderer.h"
#endif

#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this->drawingManager()->getContext())
#define ASSERT_SINGLE_OWNER        GR_ASSERT_SINGLE_OWNER(this->singleOwner())
#define RETURN_IF_ABANDONED        if (fContext->abandoned()) { return; }
#define RETURN_FALSE_IF_ABANDONED  if (fContext->abandoned()) { return false; }

//////////////////////////////////////////////////////////////////////////////

using DoSimplify = GrStyledShape::DoSimplify;

class AutoCheckFlush {
public:
    AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
        SkASSERT(fDrawingManager);
    }
    ~AutoCheckFlush() { fDrawingManager->flushIfNecessary(); }

private:
    GrDrawingManager* fDrawingManager;
};

std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::Make(GrRecordingContext* rContext,
                                                                 GrColorType colorType,
                                                                 sk_sp<GrSurfaceProxy> proxy,
                                                                 sk_sp<SkColorSpace> colorSpace,
                                                                 GrSurfaceOrigin origin,
                                                                 const SkSurfaceProps& surfaceProps,
                                                                 bool flushTimeOpsTask) {
    if (!rContext || !proxy) {
        return nullptr;
    }

    const GrBackendFormat& format = proxy->backendFormat();
    GrSwizzle readSwizzle, writeSwizzle;
    if (colorType != GrColorType::kUnknown) {
        readSwizzle = rContext->priv().caps()->getReadSwizzle(format, colorType);
        writeSwizzle = rContext->priv().caps()->getWriteSwizzle(format, colorType);
    }

    GrSurfaceProxyView readView (           proxy, origin,  readSwizzle);
    GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);

    return std::make_unique<GrSurfaceDrawContext>(rContext,
                                                  std::move(readView),
                                                  std::move(writeView),
                                                  colorType,
                                                  std::move(colorSpace),
                                                  surfaceProps,
                                                  flushTimeOpsTask);
}

std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::Make(
        GrRecordingContext* context,
        sk_sp<SkColorSpace> colorSpace,
        SkBackingFit fit,
        SkISize dimensions,
        const GrBackendFormat& format,
        int sampleCnt,
        GrMipmapped mipMapped,
        GrProtected isProtected,
        GrSwizzle readSwizzle,
        GrSwizzle writeSwizzle,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted,
        const SkSurfaceProps& surfaceProps) {
    // It is probably not necessary to check if the context is abandoned here since uses of the
    // GrSurfaceDrawContext which need the context will mostly likely fail later on without an
    // issue. However having this hear adds some reassurance in case there is a path doesn't handle
    // an abandoned context correctly. It also lets us early out of some extra work.
    if (context->abandoned()) {
        return nullptr;
    }

    sk_sp<GrTextureProxy> proxy = context->priv().proxyProvider()->createProxy(
            format,
            dimensions,
            GrRenderable::kYes,
            sampleCnt,
            mipMapped,
            fit,
            budgeted,
            isProtected);
    if (!proxy) {
        return nullptr;
    }

    GrSurfaceProxyView readView (           proxy, origin,  readSwizzle);
    GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);

    auto rtc = std::make_unique<GrSurfaceDrawContext>(context,
                                                      std::move(readView),
                                                      std::move(writeView),
                                                      GrColorType::kUnknown,
                                                      std::move(colorSpace),
                                                      surfaceProps);
    rtc->discard();
    return rtc;
}

std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::Make(
        GrRecordingContext* rContext,
        GrColorType colorType,
        sk_sp<SkColorSpace> colorSpace,
        SkBackingFit fit,
        SkISize dimensions,
        const SkSurfaceProps& surfaceProps,
        int sampleCnt,
        GrMipmapped mipMapped,
        GrProtected isProtected,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {
    auto format = rContext->priv().caps()->getDefaultBackendFormat(colorType, GrRenderable::kYes);
    if (!format.isValid()) {
        return nullptr;
    }
    sk_sp<GrTextureProxy> proxy = rContext->priv().proxyProvider()->createProxy(format,
                                                                                dimensions,
                                                                                GrRenderable::kYes,
                                                                                sampleCnt,
                                                                                mipMapped,
                                                                                fit,
                                                                                budgeted,
                                                                                isProtected);
    if (!proxy) {
        return nullptr;
    }

    return GrSurfaceDrawContext::Make(rContext,
                                      colorType,
                                      std::move(proxy),
                                      std::move(colorSpace),
                                      origin,
                                      surfaceProps);
}

std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::MakeWithFallback(
        GrRecordingContext* rContext,
        GrColorType colorType,
        sk_sp<SkColorSpace> colorSpace,
        SkBackingFit fit,
        SkISize dimensions,
        const SkSurfaceProps& surfaceProps,
        int sampleCnt,
        GrMipmapped mipMapped,
        GrProtected isProtected,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {
    const GrCaps* caps = rContext->priv().caps();
    auto [ct, format] = caps->getFallbackColorTypeAndFormat(colorType, sampleCnt);
    if (ct == GrColorType::kUnknown) {
        return nullptr;
    }
    return GrSurfaceDrawContext::Make(rContext, ct, colorSpace, fit, dimensions, surfaceProps,
                                      sampleCnt, mipMapped, isProtected, origin, budgeted);
}

std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::MakeFromBackendTexture(
        GrRecordingContext* context,
        GrColorType colorType,
        sk_sp<SkColorSpace> colorSpace,
        const GrBackendTexture& tex,
        int sampleCnt,
        GrSurfaceOrigin origin,
        const SkSurfaceProps& surfaceProps,
        sk_sp<GrRefCntedCallback> releaseHelper) {
    SkASSERT(sampleCnt > 0);
    sk_sp<GrTextureProxy> proxy(context->priv().proxyProvider()->wrapRenderableBackendTexture(
            tex, sampleCnt, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
            std::move(releaseHelper)));
    if (!proxy) {
        return nullptr;
    }

    return GrSurfaceDrawContext::Make(context, colorType, std::move(proxy), std::move(colorSpace),
                                      origin, surfaceProps);
}

// In MDB mode the reffing of the 'getLastOpsTask' call's result allows in-progress
// GrOpsTask to be picked up and added to by SurfaceDrawContexts lower in the call
// stack. When this occurs with a closed GrOpsTask, a new one will be allocated
// when the surfaceDrawContext attempts to use it (via getOpsTask).
GrSurfaceDrawContext::GrSurfaceDrawContext(GrRecordingContext* context,
                                           GrSurfaceProxyView readView,
                                           GrSurfaceProxyView writeView,
                                           GrColorType colorType,
                                           sk_sp<SkColorSpace> colorSpace,
                                           const SkSurfaceProps& surfaceProps,
                                           bool flushTimeOpsTask)
        : GrSurfaceFillContext(context,
                               std::move(readView),
                               std::move(writeView),
                               {colorType, kPremul_SkAlphaType, std::move(colorSpace)},
                               flushTimeOpsTask)
        , fSurfaceProps(surfaceProps)
        , fCanUseDynamicMSAA(
                (fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag) &&
                context->priv().caps()->supportsDynamicMSAA(this->asRenderTargetProxy()))
        , fGlyphPainter(*this) {
    SkDEBUGCODE(this->validate();)
}

GrSurfaceDrawContext::~GrSurfaceDrawContext() {
    ASSERT_SINGLE_OWNER
}

void GrSurfaceDrawContext::willReplaceOpsTask(GrOpsTask* prevTask, GrOpsTask* nextTask) {
    if (prevTask && fNeedsStencil) {
        // Store the stencil values in memory upon completion of fOpsTask.
        prevTask->setMustPreserveStencil();
        // Reload the stencil buffer content at the beginning of newOpsTask.
        // FIXME: Could the topo sort insert a task between these two that modifies the stencil
        // values?
        nextTask->setInitialStencilContent(GrOpsTask::StencilContent::kPreserved);
    }
#if GR_GPU_STATS && GR_TEST_UTILS
    if (fCanUseDynamicMSAA) {
        fContext->priv().dmsaaStats().fNumRenderPasses++;
    }
#endif
}

inline GrAAType GrSurfaceDrawContext::chooseAAType(GrAA aa) {
    if (fCanUseDynamicMSAA) {
        // Always trigger DMSAA when it's available. The coverage ops that know how to handle both
        // single and multisample targets without popping will do so without calling chooseAAType.
        return GrAAType::kMSAA;
    }
    if (GrAA::kNo == aa) {
        // On some devices we cannot disable MSAA if it is enabled so we make the AA type reflect
        // that.
        if (this->numSamples() > 1 && !this->caps()->multisampleDisableSupport()) {
            return GrAAType::kMSAA;
        }
        return GrAAType::kNone;
    }
    return (this->numSamples() > 1) ? GrAAType::kMSAA : GrAAType::kCoverage;
}

void GrSurfaceDrawContext::drawGlyphRunListNoCache(const GrClip* clip,
                                                   const SkMatrixProvider& viewMatrix,
                                                   const SkGlyphRunList& glyphRunList,
                                                   const SkPaint& paint) {
    GrSDFTControl control =
            fContext->priv().getSDFTControl(fSurfaceProps.isUseDeviceIndependentFonts());
    const SkPoint drawOrigin = glyphRunList.origin();
    SkMatrix drawMatrix = viewMatrix.localToDevice();
    drawMatrix.preTranslate(drawOrigin.x(), drawOrigin.y());
    GrSubRunAllocator* const alloc = this->subRunAlloc();

    for (auto& glyphRun : glyphRunList) {
        GrSubRunNoCachePainter painter{this, alloc, clip, viewMatrix, glyphRunList, paint};

        // Make and add the text ops.
        fGlyphPainter.processGlyphRun(glyphRun,
                                      drawMatrix,
                                      paint,
                                      control,
                                      &painter);
    }
}

void GrSurfaceDrawContext::drawGlyphRunListWithCache(const GrClip* clip,
                                                     const SkMatrixProvider& viewMatrix,
                                                     const SkGlyphRunList& glyphRunList,
                                                     const SkPaint& paint) {
    SkMatrix drawMatrix(viewMatrix.localToDevice());
    drawMatrix.preTranslate(glyphRunList.origin().x(), glyphRunList.origin().y());

    GrSDFTControl control =
            this->recordingContext()->priv().getSDFTControl(
                    this->surfaceProps().isUseDeviceIndependentFonts());

    auto [canCache, key] = GrTextBlob::Key::Make(glyphRunList,
                                                 paint,
                                                 fSurfaceProps,
                                                 this->colorInfo(),
                                                 drawMatrix,
                                                 control);

    sk_sp<GrTextBlob> blob;
    GrTextBlobCache* textBlobCache = fContext->priv().getTextBlobCache();
    if (canCache) {
        blob = textBlobCache->find(key);
    }

    if (blob == nullptr || !blob->canReuse(paint, drawMatrix)) {
        if (blob != nullptr) {
            // We have to remake the blob because changes may invalidate our masks.
            // TODO we could probably get away with reuse most of the time if the pointer is unique,
            //      but we'd have to clear the SubRun information
            textBlobCache->remove(blob.get());
        }

        blob = GrTextBlob::Make(glyphRunList, paint, drawMatrix, control, &fGlyphPainter);

        if (canCache) {
            blob->addKey(key);
            // The blob may already have been created on a different thread. Use the first one
            // that was there.
            blob = textBlobCache->addOrReturnExisting(glyphRunList, blob);
        }
    }

    for (const GrSubRun& subRun : blob->subRunList()) {
        subRun.draw(clip, viewMatrix, glyphRunList, paint, this);
    }
}

// choose to use the GrTextBlob cache or not.
bool gGrDrawTextNoCache = false;
void GrSurfaceDrawContext::drawGlyphRunList(const GrClip* clip,
                                            const SkMatrixProvider& viewMatrix,
                                            const SkGlyphRunList& glyphRunList,
                                            const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawGlyphRunList", fContext);

    // Drawing text can cause us to do inline uploads. This is not supported for wrapped vulkan
    // secondary command buffers because it would require stopping and starting a render pass which
    // we don't have access to.
    if (this->wrapsVkSecondaryCB()) {
        return;
    }

    if (gGrDrawTextNoCache || glyphRunList.blob() == nullptr) {
        // If the glyphRunList does not have an associated text blob, then it was created by one of
        // the direct draw APIs (drawGlyphs, etc.). There is no need to create a GrTextBlob just
        // build the sub run directly and place it in the op.
        this->drawGlyphRunListNoCache(clip, viewMatrix, glyphRunList, paint);
    } else {
        this->drawGlyphRunListWithCache(clip, viewMatrix, glyphRunList, paint);
    }
}

void GrSurfaceDrawContext::drawPaint(const GrClip* clip,
                                     GrPaint&& paint,
                                     const SkMatrix& viewMatrix) {
    // Start with the render target, since that is the maximum content we could possibly fill.
    // drawFilledQuad() will automatically restrict it to clip bounds for us if possible.
    if (!paint.numTotalFragmentProcessors()) {
        // The paint is trivial so we won't need to use local coordinates, so skip calculating the
        // inverse view matrix.
        SkRect r = this->asSurfaceProxy()->getBoundsRect();
        this->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), r, r);
    } else {
        // Use the inverse view matrix to arrive at appropriate local coordinates for the paint.
        SkMatrix localMatrix;
        if (!viewMatrix.invert(&localMatrix)) {
            return;
        }
        SkIRect bounds = SkIRect::MakeSize(this->asSurfaceProxy()->dimensions());
        this->fillPixelsWithLocalMatrix(clip, std::move(paint), bounds, localMatrix);
    }
}

enum class GrSurfaceDrawContext::QuadOptimization {
    // The rect to draw doesn't intersect clip or render target, so no draw op should be added
    kDiscarded,
    // The rect to draw was converted to some other op and appended to the oplist, so no additional
    // op is necessary. Currently this can convert it to a clear op or a rrect op. Only valid if
    // a constColor is provided.
    kSubmitted,
    // The clip was folded into the device quad, with updated edge flags and local coords, and
    // caller is responsible for adding an appropriate op.
    kClipApplied,
    // No change to clip, but quad updated to better fit clip/render target, and caller is
    // responsible for adding an appropriate op.
    kCropped
};

GrSurfaceDrawContext::QuadOptimization GrSurfaceDrawContext::attemptQuadOptimization(
        const GrClip* clip, const GrUserStencilSettings* stencilSettings, GrAA* aa, DrawQuad* quad,
        GrPaint* paint) {
    // Optimization requirements:
    // 1. kDiscard applies when clip bounds and quad bounds do not intersect
    // 2a. kSubmitted applies when constColor and final geom is pixel aligned rect;
    //       pixel aligned rect requires rect clip and (rect quad or quad covers clip) OR
    // 2b. kSubmitted applies when constColor and rrect clip and quad covers clip
    // 4. kClipApplied applies when rect clip and (rect quad or quad covers clip)
    // 5. kCropped in all other scenarios (although a crop may be a no-op)
    const SkPMColor4f* constColor = nullptr;
    SkPMColor4f paintColor;
    if (!stencilSettings && paint && !paint->hasCoverageFragmentProcessor() &&
        paint->isConstantBlendedColor(&paintColor)) {
        // Only consider clears/rrects when it's easy to guarantee 100% fill with single color
        constColor = &paintColor;
    }

    // Save the old AA flags since CropToRect will modify 'quad' and if kCropped is returned, it's
    // better to just keep the old flags instead of introducing mixed edge flags.
    GrQuadAAFlags oldFlags = quad->fEdgeFlags;

    // Use the logical size of the render target, which allows for "fullscreen" clears even if
    // the render target has an approximate backing fit
    SkRect rtRect = this->asSurfaceProxy()->getBoundsRect();

    SkRect drawBounds = quad->fDevice.bounds();
    if (!quad->fDevice.isFinite() || drawBounds.isEmpty() ||
        GrClip::IsOutsideClip(rtRect, drawBounds)) {
        return QuadOptimization::kDiscarded;
    } else if (GrQuadUtils::WillUseHairline(quad->fDevice, GrAAType::kCoverage, quad->fEdgeFlags)) {
        // Don't try to apply the clip early if we know rendering will use hairline methods, as this
        // has an effect on the op bounds not otherwise taken into account in this function.
        return QuadOptimization::kCropped;
    }

    auto conservativeCrop = [&]() {
        static constexpr int kLargeDrawLimit = 15000;
        // Crop the quad to the render target. This doesn't change the visual results of drawing but
        // is meant to help numerical stability for excessively large draws.
        if (drawBounds.width() > kLargeDrawLimit || drawBounds.height() > kLargeDrawLimit) {
            GrQuadUtils::CropToRect(rtRect, *aa, quad, /* compute local */ !constColor);
        }
    };

    bool simpleColor = !stencilSettings && constColor;
    GrClip::PreClipResult result = clip ? clip->preApply(drawBounds, *aa)
                                        : GrClip::PreClipResult(GrClip::Effect::kUnclipped);
    switch(result.fEffect) {
        case GrClip::Effect::kClippedOut:
            return QuadOptimization::kDiscarded;
        case GrClip::Effect::kUnclipped:
            if (!simpleColor) {
                conservativeCrop();
                return QuadOptimization::kClipApplied;
            } else {
                // Update result to store the render target bounds in order and then fall
                // through to attempt the draw->native clear optimization
                result = GrClip::PreClipResult(SkRRect::MakeRect(rtRect), *aa);
            }
            break;
        case GrClip::Effect::kClipped:
            if (!result.fIsRRect || (stencilSettings && result.fAA != *aa) ||
                (!result.fRRect.isRect() && !simpleColor)) {
                // The clip and draw state are too complicated to try and reduce
                conservativeCrop();
                return QuadOptimization::kCropped;
            } // Else fall through to attempt to combine the draw and clip geometry together
            break;
        default:
            SkUNREACHABLE;
    }

    // If we reached here, we know we're an axis-aligned clip that is either a rect or a round rect,
    // so we can potentially combine it with the draw geometry so that no clipping is needed.
    SkASSERT(result.fEffect == GrClip::Effect::kClipped && result.fIsRRect);
    SkRect clippedBounds = result.fRRect.getBounds();
    clippedBounds.intersect(rtRect);
    if (!drawBounds.intersect(clippedBounds)) {
        // Our fractional bounds aren't actually inside the clip. GrClip::preApply() can sometimes
        // think in terms of rounded-out bounds. Discard the draw.
        return QuadOptimization::kDiscarded;
    }
    // Guard against the clipped draw turning into a hairline draw after intersection
    if (drawBounds.width() < 1.f || drawBounds.height() < 1.f) {
        return QuadOptimization::kCropped;
    }

    if (result.fRRect.isRect()) {
        // No rounded corners, so we might be able to become a native clear or we might be able to
        // modify geometry and edge flags to represent intersected shape of clip and draw.
        if (GrQuadUtils::CropToRect(clippedBounds, result.fAA, quad,
                                    /*compute local*/ !constColor)) {
            if (simpleColor && quad->fDevice.quadType() == GrQuad::Type::kAxisAligned) {
                // Clear optimization is possible
                drawBounds = quad->fDevice.bounds();
                if (drawBounds.contains(rtRect)) {
                    // Fullscreen clear
                    this->clear(*constColor);
                    return QuadOptimization::kSubmitted;
                } else if (GrClip::IsPixelAligned(drawBounds) &&
                           drawBounds.width() > 256 && drawBounds.height() > 256) {
                    // Scissor + clear (round shouldn't do anything since we are pixel aligned)
                    SkIRect scissorRect;
                    drawBounds.round(&scissorRect);
                    this->clear(scissorRect, *constColor);
                    return QuadOptimization::kSubmitted;
                }
            }

            // else the draw and clip were combined so just update the AA to reflect combination
            if (*aa == GrAA::kNo && result.fAA == GrAA::kYes &&
                quad->fEdgeFlags != GrQuadAAFlags::kNone) {
                // The clip was anti-aliased and now the draw needs to be upgraded to AA to
                // properly reflect the smooth edge of the clip.
                *aa = GrAA::kYes;
            }
            // We intentionally do not downgrade AA here because we don't know if we need to
            // preserve MSAA (see GrQuadAAFlags docs). But later in the pipeline, the ops can
            // use GrResolveAATypeForQuad() to turn off coverage AA when all flags are off.
            // deviceQuad is exactly the intersection of original quad and clip, so it can be
            // drawn with no clip (submitted by caller)
            return QuadOptimization::kClipApplied;
        }
    } else {
        // Rounded corners and constant filled color (limit ourselves to solid colors because
        // there is no way to use custom local coordinates with drawRRect).
        SkASSERT(simpleColor);
        if (GrQuadUtils::CropToRect(clippedBounds, result.fAA, quad,
                                    /* compute local */ false) &&
            quad->fDevice.quadType() == GrQuad::Type::kAxisAligned &&
            quad->fDevice.bounds().contains(clippedBounds)) {
            // Since the cropped quad became a rectangle which covered the bounds of the rrect,
            // we can draw the rrect directly and ignore the edge flags
            this->drawRRect(nullptr, std::move(*paint), result.fAA, SkMatrix::I(), result.fRRect,
                            GrStyle::SimpleFill());
            return QuadOptimization::kSubmitted;
        }
    }

    // The quads have been updated to better fit the clip bounds, but can't get rid of
    // the clip entirely
    quad->fEdgeFlags = oldFlags;
    return QuadOptimization::kCropped;
}

void GrSurfaceDrawContext::drawFilledQuad(const GrClip* clip,
                                          GrPaint&& paint,
                                          GrAA aa,
                                          DrawQuad* quad,
                                          const GrUserStencilSettings* ss) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawFilledQuad", fContext);

    AutoCheckFlush acf(this->drawingManager());

    QuadOptimization opt = this->attemptQuadOptimization(clip, ss, &aa, quad, &paint);
    if (opt >= QuadOptimization::kClipApplied) {
        // These optimizations require caller to add an op themselves
        const GrClip* finalClip = opt == QuadOptimization::kClipApplied ? nullptr : clip;
        GrAAType aaType;
        if (ss) {
            aaType = (aa == GrAA::kYes) ? GrAAType::kMSAA : GrAAType::kNone;
        } else if (fCanUseDynamicMSAA && aa == GrAA::kNo) {
            // The SkGpuDevice ensures GrAA is always kYes when using dmsaa. If the caller calls
            // into here with GrAA::kNo, trust that they know what they're doing and that the
            // rendering will be equal with or without msaa.
            aaType = GrAAType::kNone;
        } else {
            aaType = this->chooseAAType(aa);
        }
        this->addDrawOp(finalClip, GrFillRectOp::Make(fContext, std::move(paint), aaType,
                                                      quad, ss));
    }
    // All other optimization levels were completely handled inside attempt(), so no extra op needed
}

void GrSurfaceDrawContext::drawTexture(const GrClip* clip,
                                       GrSurfaceProxyView view,
                                       SkAlphaType srcAlphaType,
                                       GrSamplerState::Filter filter,
                                       GrSamplerState::MipmapMode mm,
                                       SkBlendMode blendMode,
                                       const SkPMColor4f& color,
                                       const SkRect& srcRect,
                                       const SkRect& dstRect,
                                       GrAA aa,
                                       GrQuadAAFlags edgeAA,
                                       SkCanvas::SrcRectConstraint constraint,
                                       const SkMatrix& viewMatrix,
                                       sk_sp<GrColorSpaceXform> colorSpaceXform) {
    // If we are using dmsaa then go through GrFillRRectOp (via fillRectToRect).
    if ((this->alwaysAntialias() || this->caps()->reducedShaderMode()) && aa == GrAA::kYes) {
        GrPaint paint;
        paint.setColor4f(color);
        std::unique_ptr<GrFragmentProcessor> fp;
        if (constraint == SkCanvas::kStrict_SrcRectConstraint) {
            fp = GrTextureEffect::MakeSubset(view, srcAlphaType, SkMatrix::I(),
                                             GrSamplerState(filter, mm), srcRect,
                                             *this->caps());
        } else {
            fp = GrTextureEffect::Make(view, srcAlphaType, SkMatrix::I(), filter, mm);
        }
        if (colorSpaceXform) {
            fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(colorSpaceXform));
        }
        fp = GrBlendFragmentProcessor::Make(std::move(fp), nullptr, SkBlendMode::kModulate);
        paint.setColorFragmentProcessor(std::move(fp));
        if (blendMode != SkBlendMode::kSrcOver) {
            paint.setXPFactory(SkBlendMode_AsXPFactory(blendMode));
        }
        this->fillRectToRect(clip, std::move(paint), GrAA::kYes, viewMatrix, dstRect, srcRect);
        return;
    }

    const SkRect* subset = constraint == SkCanvas::kStrict_SrcRectConstraint ?
            &srcRect : nullptr;
    DrawQuad quad{GrQuad::MakeFromRect(dstRect, viewMatrix), GrQuad(srcRect), edgeAA};

    this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(colorSpaceXform), filter,
                           mm, color, blendMode, aa, &quad, subset);
}

void GrSurfaceDrawContext::drawTexturedQuad(const GrClip* clip,
                                            GrSurfaceProxyView proxyView,
                                            SkAlphaType srcAlphaType,
                                            sk_sp<GrColorSpaceXform> textureXform,
                                            GrSamplerState::Filter filter,
                                            GrSamplerState::MipmapMode mm,
                                            const SkPMColor4f& color,
                                            SkBlendMode blendMode,
                                            GrAA aa,
                                            DrawQuad* quad,
                                            const SkRect* subset) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    SkASSERT(proxyView.asTextureProxy());
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawTexturedQuad", fContext);

    AutoCheckFlush acf(this->drawingManager());

    // Functionally this is very similar to drawFilledQuad except that there's no constColor to
    // enable the kSubmitted optimizations, no stencil settings support, and its a GrTextureOp.
    QuadOptimization opt = this->attemptQuadOptimization(clip, nullptr/*stencil*/, &aa, quad,
                                                         nullptr/*paint*/);

    SkASSERT(opt != QuadOptimization::kSubmitted);
    if (opt != QuadOptimization::kDiscarded) {
        // And the texture op if not discarded
        const GrClip* finalClip = opt == QuadOptimization::kClipApplied ? nullptr : clip;
        GrAAType aaType = this->chooseAAType(aa);
        auto clampType = GrColorTypeClampType(this->colorInfo().colorType());
        auto saturate = clampType == GrClampType::kManual ? GrTextureOp::Saturate::kYes
                                                          : GrTextureOp::Saturate::kNo;
        // Use the provided subset, although hypothetically we could detect that the cropped local
        // quad is sufficiently inside the subset and the constraint could be dropped.
        this->addDrawOp(finalClip,
                        GrTextureOp::Make(fContext, std::move(proxyView), srcAlphaType,
                                          std::move(textureXform), filter, mm, color, saturate,
                                          blendMode, aaType, quad, subset));
    }
}

void GrSurfaceDrawContext::drawRect(const GrClip* clip,
                                    GrPaint&& paint,
                                    GrAA aa,
                                    const SkMatrix& viewMatrix,
                                    const SkRect& rect,
                                    const GrStyle* style) {
    if (!style) {
        style = &GrStyle::SimpleFill();
    }
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawRect", fContext);

    // Path effects should've been devolved to a path in SkGpuDevice
    SkASSERT(!style->pathEffect());

    AutoCheckFlush acf(this->drawingManager());

    const SkStrokeRec& stroke = style->strokeRec();
    if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
        // Fills the rect, using rect as its own local coordinates
        this->fillRectToRect(clip, std::move(paint), aa, viewMatrix, rect, rect);
        return;
    } else if ((stroke.getStyle() == SkStrokeRec::kStroke_Style ||
                stroke.getStyle() == SkStrokeRec::kHairline_Style) &&
               rect.width()                                        &&
               rect.height()                                       &&
               !this->caps()->reducedShaderMode()) {
        // Only use the StrokeRectOp for non-empty rectangles. Empty rectangles will be processed by
        // GrStyledShape to handle stroke caps and dashing properly.
        //
        // http://skbug.com/12206 -- there is a double-blend issue with the bevel version of
        // AAStrokeRectOp, and if we increase the AA bloat for MSAA it becomes more pronounced.
        // Don't use the bevel version with DMSAA.
        GrAAType aaType = (fCanUseDynamicMSAA &&
                           stroke.getJoin() == SkPaint::kMiter_Join &&
                           stroke.getMiter() >= SK_ScalarSqrt2) ? GrAAType::kCoverage
                                                                : this->chooseAAType(aa);
        GrOp::Owner op = GrStrokeRectOp::Make(
                fContext, std::move(paint), aaType, viewMatrix, rect, stroke);
        // op may be null if the stroke is not supported or if using coverage aa and the view matrix
        // does not preserve rectangles.
        if (op) {
            this->addDrawOp(clip, std::move(op));
            return;
        }
    }
    assert_alive(paint);
    this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
                                     GrStyledShape(rect, *style, DoSimplify::kNo));
}

void GrSurfaceDrawContext::fillRectToRect(const GrClip* clip,
                                          GrPaint&& paint,
                                          GrAA aa,
                                          const SkMatrix& viewMatrix,
                                          const SkRect& rectToDraw,
                                          const SkRect& localRect) {
    DrawQuad quad{GrQuad::MakeFromRect(rectToDraw, viewMatrix), GrQuad(localRect),
                  aa == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone};

    // If we are using dmsaa then attempt to draw the rect with GrFillRRectOp.
    if ((fContext->priv().caps()->reducedShaderMode() || this->alwaysAntialias()) &&
        this->caps()->drawInstancedSupport()                                      &&
        aa == GrAA::kYes) {  // If aa is kNo when using dmsaa, the rect is axis aligned. Don't use
                             // GrFillRRectOp because it might require dual source blending.
                             // http://skbug.com/11756
        QuadOptimization opt = this->attemptQuadOptimization(clip, nullptr/*stencil*/, &aa, &quad,
                                                             &paint);
        if (opt < QuadOptimization::kClipApplied) {
            // The optimization was completely handled inside attempt().
            return;
        }

        SkRect croppedRect, croppedLocal{};
        const GrClip* optimizedClip = clip;
        if (clip && viewMatrix.isScaleTranslate() && quad.fDevice.asRect(&croppedRect) &&
            (!paint.usesVaryingCoords() || quad.fLocal.asRect(&croppedLocal))) {
            // The cropped quad is still a rect, and our view matrix preserves rects. Map it back
            // to pre-matrix space.
            SkMatrix inverse;
            if (!viewMatrix.invert(&inverse)) {
                return;
            }
            SkASSERT(inverse.rectStaysRect());
            inverse.mapRect(&croppedRect);
            if (opt == QuadOptimization::kClipApplied) {
                optimizedClip = nullptr;
            }
        } else {
            // Even if attemptQuadOptimization gave us an optimized quad, GrFillRRectOp needs a rect
            // in pre-matrix space, so use the original rect. Also preserve the original clip.
            croppedRect = rectToDraw;
            croppedLocal = localRect;
        }

        if (auto op = GrFillRRectOp::Make(fContext, this->arenaAlloc(), std::move(paint),
                                          viewMatrix, SkRRect::MakeRect(croppedRect), croppedLocal,
                                          GrAA::kYes)) {
            this->addDrawOp(optimizedClip, std::move(op));
            return;
        }
    }

    assert_alive(paint);
    this->drawFilledQuad(clip, std::move(paint), aa, &quad);
}

void GrSurfaceDrawContext::drawQuadSet(const GrClip* clip,
                                       GrPaint&& paint,
                                       GrAA aa,
                                       const SkMatrix& viewMatrix,
                                       const QuadSetEntry quads[],
                                       int cnt) {
    GrAAType aaType = this->chooseAAType(aa);

    GrFillRectOp::AddFillRectOps(this, clip, fContext, std::move(paint), aaType, viewMatrix,
                                 quads, cnt);
}

int GrSurfaceDrawContext::maxWindowRectangles() const {
    return this->asRenderTargetProxy()->maxWindowRectangles(*this->caps());
}

GrOpsTask::CanDiscardPreviousOps GrSurfaceDrawContext::canDiscardPreviousOpsOnFullClear() const {
#if GR_TEST_UTILS
    if (fPreserveOpsOnFullClear_TestingOnly) {
        return GrOpsTask::CanDiscardPreviousOps::kNo;
    }
#endif
    // Regardless of how the clear is implemented (native clear or a fullscreen quad), all prior ops
    // would normally be overwritten. The one exception is if the render target context is marked as
    // needing a stencil buffer then there may be a prior op that writes to the stencil buffer.
    // Although the clear will ignore the stencil buffer, following draw ops may not so we can't get
    // rid of all the preceding ops. Beware! If we ever add any ops that have a side effect beyond
    // modifying the stencil buffer we will need a more elaborate tracking system (skbug.com/7002).
    return GrOpsTask::CanDiscardPreviousOps(!fNeedsStencil);
}

void GrSurfaceDrawContext::setNeedsStencil() {
    // Don't clear stencil until after we've set fNeedsStencil. This ensures we don't loop forever
    // in the event that there are driver bugs and we need to clear as a draw.
    bool hasInitializedStencil = fNeedsStencil;
    fNeedsStencil = true;
    if (!hasInitializedStencil) {
        this->asRenderTargetProxy()->setNeedsStencil();
        if (this->caps()->performStencilClearsAsDraws()) {
            // There is a driver bug with clearing stencil. We must use an op to manually clear the
            // stencil buffer before the op that required 'setNeedsStencil'.
            this->internalStencilClear(nullptr, /* inside mask */ false);
        } else {
            this->getOpsTask()->setInitialStencilContent(
                    GrOpsTask::StencilContent::kUserBitsCleared);
        }
    }
}

void GrSurfaceDrawContext::internalStencilClear(const SkIRect* scissor, bool insideStencilMask) {
    this->setNeedsStencil();

    GrScissorState scissorState(this->asSurfaceProxy()->backingStoreDimensions());
    if (scissor && !scissorState.set(*scissor)) {
        // The requested clear region is off screen, so nothing to do.
        return;
    }

    bool clearWithDraw = this->caps()->performStencilClearsAsDraws() ||
                         (scissorState.enabled() && this->caps()->performPartialClearsAsDraws());
    if (clearWithDraw) {
        const GrUserStencilSettings* ss = GrStencilSettings::SetClipBitSettings(insideStencilMask);

        // Configure the paint to have no impact on the color buffer
        GrPaint paint;
        paint.setXPFactory(GrDisableColorXPFactory::Get());
        this->addDrawOp(nullptr,
                        GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
                                                    SkRect::Make(scissorState.rect()), ss));
    } else {
        this->addOp(GrClearOp::MakeStencilClip(fContext, scissorState, insideStencilMask));
    }
}

bool GrSurfaceDrawContext::stencilPath(const GrHardClip* clip,
                                       GrAA doStencilMSAA,
                                       const SkMatrix& viewMatrix,
                                       const SkPath& path) {
#if SK_GPU_V1
    SkIRect clipBounds = clip ? clip->getConservativeBounds()
                              : SkIRect::MakeSize(this->dimensions());
    GrStyledShape shape(path, GrStyledShape::DoSimplify::kNo);

    GrPathRenderer::CanDrawPathArgs canDrawArgs;
    canDrawArgs.fCaps = fContext->priv().caps();
    canDrawArgs.fProxy = this->asRenderTargetProxy();
    canDrawArgs.fClipConservativeBounds = &clipBounds;
    canDrawArgs.fViewMatrix = &viewMatrix;
    canDrawArgs.fShape = &shape;
    canDrawArgs.fPaint = nullptr;
    canDrawArgs.fSurfaceProps = &fSurfaceProps;
    canDrawArgs.fAAType = (doStencilMSAA == GrAA::kYes) ? GrAAType::kMSAA : GrAAType::kNone;
    canDrawArgs.fHasUserStencilSettings = false;
    GrPathRenderer* pr = this->drawingManager()->getPathRenderer(
            canDrawArgs, false, GrPathRendererChain::DrawType::kStencil);
    if (!pr) {
        SkDebugf("WARNING: No path renderer to stencil path.\n");
        return false;
    }

    GrPathRenderer::StencilPathArgs args;
    args.fContext = fContext;
    args.fSurfaceDrawContext = this;
    args.fClip = clip;
    args.fClipConservativeBounds = &clipBounds;
    args.fViewMatrix = &viewMatrix;
    args.fShape = &shape;
    args.fDoStencilMSAA = doStencilMSAA;
    pr->stencilPath(args);
    return true;
#else
    return false;
#endif // SK_GPU_V1
}

void GrSurfaceDrawContext::drawTextureSet(const GrClip* clip,
                                          TextureSetEntry set[],
                                          int cnt,
                                          int proxyRunCnt,
                                          GrSamplerState::Filter filter,
                                          GrSamplerState::MipmapMode mm,
                                          SkBlendMode mode,
                                          GrAA aa,
                                          SkCanvas::SrcRectConstraint constraint,
                                          const SkMatrix& viewMatrix,
                                          sk_sp<GrColorSpaceXform> texXform) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawTextureSet", fContext);

    // Create the minimum number of GrTextureOps needed to draw this set. Individual
    // GrTextureOps can rebind the texture between draws thus avoiding GrPaint (re)creation.
    AutoCheckFlush acf(this->drawingManager());
    GrAAType aaType = this->chooseAAType(aa);
    auto clampType = GrColorTypeClampType(this->colorInfo().colorType());
    auto saturate = clampType == GrClampType::kManual ? GrTextureOp::Saturate::kYes
                                                      : GrTextureOp::Saturate::kNo;
    GrTextureOp::AddTextureSetOps(this, clip, fContext, set, cnt, proxyRunCnt, filter, mm, saturate,
                                  mode, aaType, constraint, viewMatrix, std::move(texXform));
}

void GrSurfaceDrawContext::drawVertices(const GrClip* clip,
                                        GrPaint&& paint,
                                        const SkMatrixProvider& matrixProvider,
                                        sk_sp<SkVertices> vertices,
                                        GrPrimitiveType* overridePrimType,
                                        const SkRuntimeEffect* effect) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawVertices", fContext);

    AutoCheckFlush acf(this->drawingManager());

    SkASSERT(vertices);
    GrAAType aaType = fCanUseDynamicMSAA ? GrAAType::kMSAA : this->chooseAAType(GrAA::kNo);
    GrOp::Owner op =
            GrDrawVerticesOp::Make(fContext, std::move(paint), std::move(vertices), matrixProvider,
                                   aaType, this->colorInfo().refColorSpaceXformFromSRGB(),
                                   overridePrimType, effect);
    this->addDrawOp(clip, std::move(op));
}

///////////////////////////////////////////////////////////////////////////////

void GrSurfaceDrawContext::drawAtlas(const GrClip* clip,
                                     GrPaint&& paint,
                                     const SkMatrix& viewMatrix,
                                     int spriteCount,
                                     const SkRSXform xform[],
                                     const SkRect texRect[],
                                     const SkColor colors[]) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawAtlas", fContext);

    AutoCheckFlush acf(this->drawingManager());

    GrAAType aaType = this->chooseAAType(GrAA::kNo);
    GrOp::Owner op = GrDrawAtlasOp::Make(fContext, std::move(paint), viewMatrix,
                                         aaType, spriteCount, xform, texRect, colors);
    this->addDrawOp(clip, std::move(op));
}

///////////////////////////////////////////////////////////////////////////////

void GrSurfaceDrawContext::drawRRect(const GrClip* origClip,
                                     GrPaint&& paint,
                                     GrAA aa,
                                     const SkMatrix& viewMatrix,
                                     const SkRRect& rrect,
                                     const GrStyle& style) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawRRect", fContext);

    SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice

    const SkStrokeRec& stroke = style.strokeRec();
    if (stroke.getStyle() == SkStrokeRec::kFill_Style && rrect.isEmpty()) {
       return;
    }

    const GrClip* clip = origClip;
    // It is not uncommon to clip to a round rect and then draw that same round rect. Since our
    // lower level clip code works from op bounds, which are SkRects, it doesn't detect that the
    // clip can be ignored. The following test attempts to mitigate the stencil clip cost but only
    // works for axis-aligned round rects. This also only works for filled rrects since the stroke
    // width outsets beyond the rrect itself.
    // TODO: skbug.com/10462 - There was mixed performance wins and regressions when this
    // optimization was turned on outside of Android Framework. I (michaelludwig) believe this is
    // do to the overhead in determining if an SkClipStack is just a rrect. Once that is improved,
    // re-enable this and see if we avoid the regressions.
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    SkRRect devRRect;
    if (clip && stroke.getStyle() == SkStrokeRec::kFill_Style &&
        rrect.transform(viewMatrix, &devRRect)) {
        GrClip::PreClipResult result = clip->preApply(devRRect.getBounds(), aa);
        switch(result.fEffect) {
            case GrClip::Effect::kClippedOut:
                return;
            case GrClip::Effect::kUnclipped:
                clip = nullptr;
                break;
            case GrClip::Effect::kClipped:
                // Currently there's no general-purpose rrect-to-rrect contains function, and if we
                // got here, we know the devRRect's bounds aren't fully contained by the clip.
                // Testing for equality between the two is a reasonable stop-gap for now.
                if (result.fIsRRect && result.fRRect == devRRect) {
                    // NOTE: On the android framework, we allow this optimization even when the clip
                    // is non-AA and the draw is AA.
                    if (result.fAA == aa || (result.fAA == GrAA::kNo && aa == GrAA::kYes)) {
                        clip = nullptr;
                    }
                }
                break;
            default:
                SkUNREACHABLE;
        }
    }
#endif

    AutoCheckFlush acf(this->drawingManager());

    GrAAType aaType = this->chooseAAType(aa);

    GrOp::Owner op;
    if (aaType == GrAAType::kCoverage                          &&
        !fCanUseDynamicMSAA                                    &&
        !this->caps()->reducedShaderMode()                     &&
        rrect.isSimple()                                       &&
        rrect.getSimpleRadii().fX == rrect.getSimpleRadii().fY &&
        viewMatrix.rectStaysRect() && viewMatrix.isSimilarity()) {
        // In specific cases we use a dedicated circular round rect op to try and get better perf.
        assert_alive(paint);
        op = GrOvalOpFactory::MakeCircularRRectOp(fContext, std::move(paint), viewMatrix, rrect,
                                                  stroke, this->caps()->shaderCaps());
    }
    if (!op && style.isSimpleFill()) {
        assert_alive(paint);
        op = GrFillRRectOp::Make(fContext, this->arenaAlloc(), std::move(paint), viewMatrix, rrect,
                                 rrect.rect(), GrAA(aaType != GrAAType::kNone));
    }
    if (!op && (aaType == GrAAType::kCoverage || fCanUseDynamicMSAA)) {
        assert_alive(paint);
        op = GrOvalOpFactory::MakeRRectOp(
                fContext, std::move(paint), viewMatrix, rrect, stroke, this->caps()->shaderCaps());
    }
    if (op) {
        this->addDrawOp(clip, std::move(op));
        return;
    }

    assert_alive(paint);
    this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
                                     GrStyledShape(rrect, style, DoSimplify::kNo));
}

///////////////////////////////////////////////////////////////////////////////

bool GrSurfaceDrawContext::drawFastShadow(const GrClip* clip,
                                          const SkMatrix& viewMatrix,
                                          const SkPath& path,
                                          const SkDrawShadowRec& rec) {
    ASSERT_SINGLE_OWNER
    if (fContext->abandoned()) {
        return true;
    }
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawFastShadow", fContext);

    // check z plane
    bool tiltZPlane = SkToBool(!SkScalarNearlyZero(rec.fZPlaneParams.fX) ||
                               !SkScalarNearlyZero(rec.fZPlaneParams.fY));
    bool skipAnalytic = SkToBool(rec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
    if (tiltZPlane || skipAnalytic || !viewMatrix.rectStaysRect() || !viewMatrix.isSimilarity()) {
        return false;
    }

    SkRRect rrect;
    SkRect rect;
    // we can only handle rects, circles, and simple rrects with circular corners
    bool isRRect = path.isRRect(&rrect) && SkRRectPriv::IsNearlySimpleCircular(rrect) &&
                   rrect.getSimpleRadii().fX > SK_ScalarNearlyZero;
    if (!isRRect &&
        path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
        rect.width() > SK_ScalarNearlyZero) {
        rrect.setOval(rect);
        isRRect = true;
    }
    if (!isRRect && path.isRect(&rect)) {
        rrect.setRect(rect);
        isRRect = true;
    }

    if (!isRRect) {
        return false;
    }

    if (rrect.isEmpty()) {
        return true;
    }

    AutoCheckFlush acf(this->drawingManager());

    SkPoint3 devLightPos = rec.fLightPos;
    bool directional = SkToBool(rec.fFlags & kDirectionalLight_ShadowFlag);
    if (!directional) {
        // transform light
        viewMatrix.mapPoints((SkPoint*)&devLightPos.fX, 1);
    }

    // 1/scale
    SkScalar devToSrcScale = viewMatrix.isScaleTranslate() ?
        SkScalarInvert(SkScalarAbs(viewMatrix[SkMatrix::kMScaleX])) :
        sk_float_rsqrt(viewMatrix[SkMatrix::kMScaleX] * viewMatrix[SkMatrix::kMScaleX] +
                       viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);

    SkScalar occluderHeight = rec.fZPlaneParams.fZ;
    bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);

    if (SkColorGetA(rec.fAmbientColor) > 0) {
        SkScalar devSpaceInsetWidth = SkDrawShadowMetrics::AmbientBlurRadius(occluderHeight);
        const SkScalar umbraRecipAlpha = SkDrawShadowMetrics::AmbientRecipAlpha(occluderHeight);
        const SkScalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraRecipAlpha;

        // Outset the shadow rrect to the border of the penumbra
        SkScalar ambientPathOutset = devSpaceInsetWidth * devToSrcScale;
        SkRRect ambientRRect;
        SkRect outsetRect = rrect.rect().makeOutset(ambientPathOutset, ambientPathOutset);
        // If the rrect was an oval then its outset will also be one.
        // We set it explicitly to avoid errors.
        if (rrect.isOval()) {
            ambientRRect = SkRRect::MakeOval(outsetRect);
        } else {
            SkScalar outsetRad = SkRRectPriv::GetSimpleRadii(rrect).fX + ambientPathOutset;
            ambientRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
        }

        GrColor ambientColor = SkColorToPremulGrColor(rec.fAmbientColor);
        if (transparent) {
            // set a large inset to force a fill
            devSpaceInsetWidth = ambientRRect.width();
        }

        GrOp::Owner op = GrShadowRRectOp::Make(fContext,
                                               ambientColor,
                                               viewMatrix,
                                               ambientRRect,
                                               devSpaceAmbientBlur,
                                               devSpaceInsetWidth);
        if (op) {
            this->addDrawOp(clip, std::move(op));
        }
    }

    if (SkColorGetA(rec.fSpotColor) > 0) {
        SkScalar devSpaceSpotBlur;
        SkScalar spotScale;
        SkVector spotOffset;
        if (directional) {
            SkDrawShadowMetrics::GetDirectionalParams(occluderHeight, devLightPos.fX,
                                                      devLightPos.fY, devLightPos.fZ,
                                                      rec.fLightRadius, &devSpaceSpotBlur,
                                                      &spotScale, &spotOffset);
        } else {
            SkDrawShadowMetrics::GetSpotParams(occluderHeight, devLightPos.fX, devLightPos.fY,
                                               devLightPos.fZ, rec.fLightRadius,
                                               &devSpaceSpotBlur, &spotScale, &spotOffset);
        }
        // handle scale of radius due to CTM
        const SkScalar srcSpaceSpotBlur = devSpaceSpotBlur * devToSrcScale;

        // Adjust translate for the effect of the scale.
        spotOffset.fX += spotScale*viewMatrix[SkMatrix::kMTransX];
        spotOffset.fY += spotScale*viewMatrix[SkMatrix::kMTransY];
        // This offset is in dev space, need to transform it into source space.
        SkMatrix ctmInverse;
        if (viewMatrix.invert(&ctmInverse)) {
            ctmInverse.mapPoints(&spotOffset, 1);
        } else {
            // Since the matrix is a similarity, this should never happen, but just in case...
            SkDebugf("Matrix is degenerate. Will not render spot shadow correctly!\n");
            SkASSERT(false);
        }

        // Compute the transformed shadow rrect
        SkRRect spotShadowRRect;
        SkMatrix shadowTransform;
        shadowTransform.setScaleTranslate(spotScale, spotScale, spotOffset.fX, spotOffset.fY);
        rrect.transform(shadowTransform, &spotShadowRRect);
        SkScalar spotRadius = spotShadowRRect.getSimpleRadii().fX;

        // Compute the insetWidth
        SkScalar blurOutset = srcSpaceSpotBlur;
        SkScalar insetWidth = blurOutset;
        if (transparent) {
            // If transparent, just do a fill
            insetWidth += spotShadowRRect.width();
        } else {
            // For shadows, instead of using a stroke we specify an inset from the penumbra
            // border. We want to extend this inset area so that it meets up with the caster
            // geometry. The inset geometry will by default already be inset by the blur width.
            //
            // We compare the min and max corners inset by the radius between the original
            // rrect and the shadow rrect. The distance between the two plus the difference
            // between the scaled radius and the original radius gives the distance from the
            // transformed shadow shape to the original shape in that corner. The max
            // of these gives the maximum distance we need to cover.
            //
            // Since we are outsetting by 1/2 the blur distance, we just add the maxOffset to
            // that to get the full insetWidth.
            SkScalar maxOffset;
            if (rrect.isRect()) {
                // Manhattan distance works better for rects
                maxOffset = std::max(std::max(SkTAbs(spotShadowRRect.rect().fLeft -
                                                 rrect.rect().fLeft),
                                          SkTAbs(spotShadowRRect.rect().fTop -
                                                 rrect.rect().fTop)),
                                   std::max(SkTAbs(spotShadowRRect.rect().fRight -
                                                 rrect.rect().fRight),
                                          SkTAbs(spotShadowRRect.rect().fBottom -
                                                 rrect.rect().fBottom)));
            } else {
                SkScalar dr = spotRadius - SkRRectPriv::GetSimpleRadii(rrect).fX;
                SkPoint upperLeftOffset = SkPoint::Make(spotShadowRRect.rect().fLeft -
                                                        rrect.rect().fLeft + dr,
                                                        spotShadowRRect.rect().fTop -
                                                        rrect.rect().fTop + dr);
                SkPoint lowerRightOffset = SkPoint::Make(spotShadowRRect.rect().fRight -
                                                         rrect.rect().fRight - dr,
                                                         spotShadowRRect.rect().fBottom -
                                                         rrect.rect().fBottom - dr);
                maxOffset = SkScalarSqrt(std::max(SkPointPriv::LengthSqd(upperLeftOffset),
                                                  SkPointPriv::LengthSqd(lowerRightOffset))) + dr;
            }
            insetWidth += std::max(blurOutset, maxOffset);
        }

        // Outset the shadow rrect to the border of the penumbra
        SkRect outsetRect = spotShadowRRect.rect().makeOutset(blurOutset, blurOutset);
        if (spotShadowRRect.isOval()) {
            spotShadowRRect = SkRRect::MakeOval(outsetRect);
        } else {
            SkScalar outsetRad = spotRadius + blurOutset;
            spotShadowRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
        }

        GrColor spotColor = SkColorToPremulGrColor(rec.fSpotColor);

        GrOp::Owner op = GrShadowRRectOp::Make(fContext,
                                               spotColor,
                                               viewMatrix,
                                               spotShadowRRect,
                                               2.0f * devSpaceSpotBlur,
                                               insetWidth);
        if (op) {
            this->addDrawOp(clip, std::move(op));
        }
    }

    return true;
}

///////////////////////////////////////////////////////////////////////////////

void GrSurfaceDrawContext::drawRegion(const GrClip* clip,
                                      GrPaint&& paint,
                                      GrAA aa,
                                      const SkMatrix& viewMatrix,
                                      const SkRegion& region,
                                      const GrStyle& style,
                                      const GrUserStencilSettings* ss) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawRegion", fContext);

    if (GrAA::kYes == aa) {
        // GrRegionOp performs no antialiasing but is much faster, so here we check the matrix
        // to see whether aa is really required.
        if (!SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) &&
            SkScalarIsInt(viewMatrix.getTranslateX()) &&
            SkScalarIsInt(viewMatrix.getTranslateY())) {
            aa = GrAA::kNo;
        }
    }
    bool complexStyle = !style.isSimpleFill();
    if (complexStyle || GrAA::kYes == aa) {
        SkPath path;
        region.getBoundaryPath(&path);
        path.setIsVolatile(true);

        return this->drawPath(clip, std::move(paint), aa, viewMatrix, path, style);
    }

    GrAAType aaType = (this->numSamples() > 1 &&
                       !this->caps()->multisampleDisableSupport())
                    ? GrAAType::kMSAA
                    : GrAAType::kNone;
    GrOp::Owner op = GrRegionOp::Make(fContext, std::move(paint), viewMatrix, region, aaType, ss);
    this->addDrawOp(clip, std::move(op));
}

void GrSurfaceDrawContext::drawOval(const GrClip* clip,
                                    GrPaint&& paint,
                                    GrAA aa,
                                    const SkMatrix& viewMatrix,
                                    const SkRect& oval,
                                    const GrStyle& style) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawOval", fContext);

    const SkStrokeRec& stroke = style.strokeRec();

    if (oval.isEmpty() && !style.pathEffect()) {
        if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
            return;
        }

        this->drawRect(clip, std::move(paint), aa, viewMatrix, oval, &style);
        return;
    }

    AutoCheckFlush acf(this->drawingManager());

    GrAAType aaType = this->chooseAAType(aa);

    GrOp::Owner op;
    if (aaType == GrAAType::kCoverage      &&
        !fCanUseDynamicMSAA                &&
        !this->caps()->reducedShaderMode() &&
        oval.width() > SK_ScalarNearlyZero &&
        oval.width() == oval.height()      &&
        viewMatrix.isSimilarity()) {
        // In specific cases we use a dedicated circle op to try and get better perf.
        assert_alive(paint);
        op = GrOvalOpFactory::MakeCircleOp(fContext, std::move(paint), viewMatrix, oval, style,
                                           this->caps()->shaderCaps());
    }
    if (!op && style.isSimpleFill()) {
        // GrFillRRectOp has special geometry and a fragment-shader branch to conditionally evaluate
        // the arc equation. This same special geometry and fragment branch also turn out to be a
        // substantial optimization for drawing ovals (namely, by not evaluating the arc equation
        // inside the oval's inner diamond). Given these optimizations, it's a clear win to draw
        // ovals the exact same way we do round rects.
        assert_alive(paint);
        op = GrFillRRectOp::Make(fContext, this->arenaAlloc(), std::move(paint), viewMatrix,
                                 SkRRect::MakeOval(oval), oval, GrAA(aaType != GrAAType::kNone));
    }
    if (!op && (aaType == GrAAType::kCoverage || fCanUseDynamicMSAA)) {
        assert_alive(paint);
        op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix, oval, style,
                                         this->caps()->shaderCaps());
    }
    if (op) {
        this->addDrawOp(clip, std::move(op));
        return;
    }

    assert_alive(paint);
    this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
                                     GrStyledShape(SkRRect::MakeOval(oval), SkPathDirection::kCW, 2,
                                                   false, style, DoSimplify::kNo));
}

void GrSurfaceDrawContext::drawArc(const GrClip* clip,
                                   GrPaint&& paint,
                                   GrAA aa,
                                   const SkMatrix& viewMatrix,
                                   const SkRect& oval,
                                   SkScalar startAngle,
                                   SkScalar sweepAngle,
                                   bool useCenter,
                                   const GrStyle& style) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
            GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawArc", fContext);

    AutoCheckFlush acf(this->drawingManager());

    GrAAType aaType = this->chooseAAType(aa);
    if (aaType == GrAAType::kCoverage) {
        const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
        GrOp::Owner op = GrOvalOpFactory::MakeArcOp(fContext,
                                                    std::move(paint),
                                                    viewMatrix,
                                                    oval,
                                                    startAngle,
                                                    sweepAngle,
                                                    useCenter,
                                                    style,
                                                    shaderCaps);
        if (op) {
            this->addDrawOp(clip, std::move(op));
            return;
        }
        assert_alive(paint);
    }
    this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
                                     GrStyledShape::MakeArc(oval, startAngle, sweepAngle, useCenter,
                                                            style, DoSimplify::kNo));
}

void GrSurfaceDrawContext::drawImageLattice(const GrClip* clip,
                                            GrPaint&& paint,
                                            const SkMatrix& viewMatrix,
                                            GrSurfaceProxyView view,
                                            SkAlphaType alphaType,
                                            sk_sp<GrColorSpaceXform> csxf,
                                            GrSamplerState::Filter filter,
                                            std::unique_ptr<SkLatticeIter> iter,
                                            const SkRect& dst) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawImageLattice", fContext);

    AutoCheckFlush acf(this->drawingManager());

    GrOp::Owner op =
            GrLatticeOp::MakeNonAA(fContext, std::move(paint), viewMatrix, std::move(view),
                                   alphaType, std::move(csxf), filter, std::move(iter), dst);
    this->addDrawOp(clip, std::move(op));
}

void GrSurfaceDrawContext::drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable,
                                         const SkRect& bounds) {
    GrOp::Owner op(GrDrawableOp::Make(fContext, std::move(drawable), bounds));
    SkASSERT(op);
    this->addOp(std::move(op));
}

bool GrSurfaceDrawContext::waitOnSemaphores(int numSemaphores,
                                            const GrBackendSemaphore waitSemaphores[],
                                            bool deleteSemaphoresAfterWait) {
    ASSERT_SINGLE_OWNER
    RETURN_FALSE_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "waitOnSemaphores", fContext);

    AutoCheckFlush acf(this->drawingManager());

    if (numSemaphores && !this->caps()->semaphoreSupport()) {
        return false;
    }

    auto direct = fContext->asDirectContext();
    if (!direct) {
        return false;
    }

    auto resourceProvider = direct->priv().resourceProvider();

    GrWrapOwnership ownership =
            deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;

    std::unique_ptr<std::unique_ptr<GrSemaphore>[]> grSemaphores(
            new std::unique_ptr<GrSemaphore>[numSemaphores]);
    for (int i = 0; i < numSemaphores; ++i) {
        grSemaphores[i] = resourceProvider->wrapBackendSemaphore(waitSemaphores[i],
                                                                 GrSemaphoreWrapType::kWillWait,
                                                                 ownership);
    }
    this->drawingManager()->newWaitRenderTask(this->asSurfaceProxyRef(), std::move(grSemaphores),
                                              numSemaphores);
    return true;
}

void GrSurfaceDrawContext::drawPath(const GrClip* clip,
                                    GrPaint&& paint,
                                    GrAA aa,
                                    const SkMatrix& viewMatrix,
                                    const SkPath& path,
                                    const GrStyle& style) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawPath", fContext);

    GrStyledShape shape(path, style, DoSimplify::kNo);
    this->drawShape(clip, std::move(paint), aa, viewMatrix, std::move(shape));
}

void GrSurfaceDrawContext::drawShape(const GrClip* clip,
                                     GrPaint&& paint,
                                     GrAA aa,
                                     const SkMatrix& viewMatrix,
                                     GrStyledShape&& shape) {
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawShape", fContext);

    if (shape.isEmpty()) {
        if (shape.inverseFilled()) {
            this->drawPaint(clip, std::move(paint), viewMatrix);
        }
        return;
    }

    AutoCheckFlush acf(this->drawingManager());

    // If we get here in drawShape(), we definitely need to use path rendering
    this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, std::move(shape),
                                     /* attemptDrawSimple */ true);
}

#if SK_GPU_V1
static SkIRect get_clip_bounds(const GrSurfaceDrawContext* rtc, const GrClip* clip) {
    return clip ? clip->getConservativeBounds() : SkIRect::MakeWH(rtc->width(), rtc->height());
}
#endif // SK_GPU_V1

bool GrSurfaceDrawContext::drawAndStencilPath(const GrHardClip* clip,
                                              const GrUserStencilSettings* ss,
                                              SkRegion::Op op,
                                              bool invert,
                                              GrAA aa,
                                              const SkMatrix& viewMatrix,
                                              const SkPath& path) {
#if SK_GPU_V1
    ASSERT_SINGLE_OWNER
    RETURN_FALSE_IF_ABANDONED
    SkDEBUGCODE(this->validate();)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "drawAndStencilPath", fContext);

    if (path.isEmpty() && path.isInverseFillType()) {
        GrPaint paint;
        paint.setCoverageSetOpXPFactory(op, invert);
        this->stencilRect(clip, ss, std::move(paint), GrAA::kNo, SkMatrix::I(),
                          SkRect::Make(this->dimensions()));
        return true;
    }

    AutoCheckFlush acf(this->drawingManager());

    // An Assumption here is that path renderer would use some form of tweaking
    // the src color (either the input alpha or in the frag shader) to implement
    // aa. If we have some future driver-mojo path AA that can do the right
    // thing WRT to the blend then we'll need some query on the PR.
    GrAAType aaType = this->chooseAAType(aa);
    bool hasUserStencilSettings = !ss->isUnused();

    SkIRect clipConservativeBounds = get_clip_bounds(this, clip);

    GrPaint paint;
    paint.setCoverageSetOpXPFactory(op, invert);

    GrStyledShape shape(path, GrStyle::SimpleFill());
    GrPathRenderer::CanDrawPathArgs canDrawArgs;
    canDrawArgs.fCaps = this->caps();
    canDrawArgs.fProxy = this->asRenderTargetProxy();
    canDrawArgs.fViewMatrix = &viewMatrix;
    canDrawArgs.fShape = &shape;
    canDrawArgs.fPaint = &paint;
    canDrawArgs.fSurfaceProps = &fSurfaceProps;
    canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
    canDrawArgs.fAAType = aaType;
    canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;

    // Don't allow the SW renderer
    GrPathRenderer* pr = this->drawingManager()->getPathRenderer(
            canDrawArgs, false, GrPathRendererChain::DrawType::kStencilAndColor);
    if (!pr) {
        return false;
    }

    GrPathRenderer::DrawPathArgs args{this->drawingManager()->getContext(),
                                      std::move(paint),
                                      ss,
                                      this,
                                      clip,
                                      &clipConservativeBounds,
                                      &viewMatrix,
                                      &shape,
                                      aaType,
                                      this->colorInfo().isLinearlyBlended()};
    pr->drawPath(args);
    return true;
#else
    return false;
#endif
}

SkBudgeted GrSurfaceDrawContext::isBudgeted() const {
    ASSERT_SINGLE_OWNER

    if (fContext->abandoned()) {
        return SkBudgeted::kNo;
    }

    SkDEBUGCODE(this->validate();)

    return this->asSurfaceProxy()->isBudgeted();
}

void GrSurfaceDrawContext::drawStrokedLine(const GrClip* clip, GrPaint&& paint,
                                           GrAA aa, const SkMatrix& viewMatrix,
                                           const SkPoint points[2], const SkStrokeRec& stroke) {
    ASSERT_SINGLE_OWNER

    SkASSERT(stroke.getStyle() == SkStrokeRec::kStroke_Style);
    SkASSERT(stroke.getWidth() > 0);
    // Adding support for round capping would require a
    // GrSurfaceDrawContext::fillRRectWithLocalMatrix entry point
    SkASSERT(SkPaint::kRound_Cap != stroke.getCap());

    const SkScalar halfWidth = 0.5f * stroke.getWidth();
    if (halfWidth <= 0.f) {
        // Prevents underflow when stroke width is epsilon > 0 (so technically not a hairline).
        // The CTM would need to have a scale near 1/epsilon in order for this to have meaningful
        // coverage (although that would likely overflow elsewhere and cause the draw to drop due
        // to non-finite bounds). At any other scale, this line is so thin, it's coverage is
        // negligible, so discarding the draw is visually equivalent.
        return;
    }

    SkVector parallel = points[1] - points[0];

    if (!SkPoint::Normalize(&parallel)) {
        parallel.fX = 1.0f;
        parallel.fY = 0.0f;
    }
    parallel *= halfWidth;

    SkVector ortho = { parallel.fY, -parallel.fX };
    if (SkPaint::kButt_Cap == stroke.getCap()) {
        // No extra extension for butt caps
        parallel = {0.f, 0.f};
    }
    // Order is TL, TR, BR, BL where arbitrarily "down" is p0 to p1 and "right" is positive
    SkPoint corners[4] = { points[0] - ortho - parallel,
                           points[0] + ortho - parallel,
                           points[1] + ortho + parallel,
                           points[1] - ortho + parallel };

    GrQuadAAFlags edgeAA = (aa == GrAA::kYes) ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone;
    this->fillQuadWithEdgeAA(clip, std::move(paint), aa, edgeAA, viewMatrix, corners, nullptr);
}

bool GrSurfaceDrawContext::drawSimpleShape(const GrClip* clip, GrPaint* paint, GrAA aa,
                                           const SkMatrix& viewMatrix, const GrStyledShape& shape) {
    if (!shape.style().hasPathEffect()) {
        GrAAType aaType = this->chooseAAType(aa);
        SkPoint linePts[2];
        SkRRect rrect;
        // We can ignore the starting point and direction since there is no path effect.
        bool inverted;
        if (shape.asLine(linePts, &inverted) && !inverted &&
            shape.style().strokeRec().getStyle() == SkStrokeRec::kStroke_Style &&
            shape.style().strokeRec().getCap() != SkPaint::kRound_Cap) {
            // The stroked line is an oriented rectangle, which looks the same or better (if
            // perspective) compared to path rendering. The exception is subpixel/hairline lines
            // that are non-AA or MSAA, in which case the default path renderer achieves higher
            // quality.
            // FIXME(michaelludwig): If the fill rect op could take an external coverage, or checks
            // for and outsets thin non-aa rects to 1px, the path renderer could be skipped.
            SkScalar coverage;
            if (aaType == GrAAType::kCoverage ||
                !SkDrawTreatAAStrokeAsHairline(shape.style().strokeRec().getWidth(), viewMatrix,
                                               &coverage)) {
                this->drawStrokedLine(clip, std::move(*paint), aa, viewMatrix, linePts,
                                      shape.style().strokeRec());
                return true;
            }
        } else if (shape.asRRect(&rrect, nullptr, nullptr, &inverted) && !inverted) {
            if (rrect.isRect()) {
                this->drawRect(clip, std::move(*paint), aa, viewMatrix, rrect.rect(),
                               &shape.style());
                return true;
            } else if (rrect.isOval()) {
                this->drawOval(clip, std::move(*paint), aa, viewMatrix, rrect.rect(),
                               shape.style());
                return true;
            }
            this->drawRRect(clip, std::move(*paint), aa, viewMatrix, rrect, shape.style());
            return true;
        } else if (GrAAType::kCoverage == aaType &&
                   shape.style().isSimpleFill()  &&
                   viewMatrix.rectStaysRect()    &&
                   !this->caps()->reducedShaderMode()) {
            // TODO: the rectStaysRect restriction could be lifted if we were willing to apply the
            // matrix to all the points individually rather than just to the rect
            SkRect rects[2];
            if (shape.asNestedRects(rects)) {
                // Concave AA paths are expensive - try to avoid them for special cases
                GrOp::Owner op = GrStrokeRectOp::MakeNested(
                                fContext, std::move(*paint), viewMatrix, rects);
                if (op) {
                    this->addDrawOp(clip, std::move(op));
                }
                // Returning here indicates that there is nothing to draw in this case.
                return true;
            }
        }
    }
    return false;
}

void GrSurfaceDrawContext::drawShapeUsingPathRenderer(const GrClip* clip,
                                                      GrPaint&& paint,
                                                      GrAA aa,
                                                      const SkMatrix& viewMatrix,
                                                      GrStyledShape&& shape,
                                                      bool attemptDrawSimple) {
#if SK_GPU_V1
    ASSERT_SINGLE_OWNER
    RETURN_IF_ABANDONED
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "internalDrawPath", fContext);

    if (!viewMatrix.isFinite() || !shape.bounds().isFinite()) {
        return;
    }

    SkIRect clipConservativeBounds = get_clip_bounds(this, clip);

    // Always allow paths to trigger DMSAA.
    GrAAType aaType = fCanUseDynamicMSAA ? GrAAType::kMSAA : this->chooseAAType(aa);

    GrPathRenderer::CanDrawPathArgs canDrawArgs;
    canDrawArgs.fCaps = this->caps();
    canDrawArgs.fProxy = this->asRenderTargetProxy();
    canDrawArgs.fViewMatrix = &viewMatrix;
    canDrawArgs.fShape = &shape;
    canDrawArgs.fPaint = &paint;
    canDrawArgs.fSurfaceProps = &fSurfaceProps;
    canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
    canDrawArgs.fHasUserStencilSettings = false;
    canDrawArgs.fAAType = aaType;

    constexpr static bool kDisallowSWPathRenderer = false;
    constexpr static bool kAllowSWPathRenderer = true;
    using DrawType = GrPathRendererChain::DrawType;

    GrPathRenderer* pr = nullptr;

    if (!shape.style().strokeRec().isFillStyle() && !shape.isEmpty()) {
        // Give the tessellation path renderer a chance to claim this stroke before we simplify it.
        GrPathRenderer* tess = this->drawingManager()->getTessellationPathRenderer();
        if (tess && tess->canDrawPath(canDrawArgs) == GrPathRenderer::CanDrawPath::kYes) {
            pr = tess;
        }
    }

    if (!pr) {
        // The shape isn't a stroke that can be drawn directly. Simplify if possible.
        shape.simplify();

        if (shape.isEmpty() && !shape.inverseFilled()) {
            return;
        }

        if (attemptDrawSimple || shape.simplified()) {
            // Usually we enter drawShapeUsingPathRenderer() because the shape+style was too complex
            // for dedicated draw ops. However, if GrStyledShape was able to reduce something we
            // ought to try again instead of going right to path rendering.
            if (this->drawSimpleShape(clip, &paint, aa, viewMatrix, shape)) {
                return;
            }
        }

        // Try a 1st time without applying any of the style to the geometry (and barring sw)
        pr = this->drawingManager()->getPathRenderer(canDrawArgs, kDisallowSWPathRenderer,
                                                     DrawType::kColor);
    }

    SkScalar styleScale =  GrStyle::MatrixToScaleFactor(viewMatrix);
    if (styleScale == 0.0f) {
        return;
    }

    if (!pr && shape.style().pathEffect()) {
        // It didn't work above, so try again with the path effect applied.
        shape = shape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
        if (shape.isEmpty()) {
            return;
        }
        pr = this->drawingManager()->getPathRenderer(canDrawArgs, kDisallowSWPathRenderer,
                                                     DrawType::kColor);
    }
    if (!pr) {
        if (shape.style().applies()) {
            shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale);
            if (shape.isEmpty()) {
                return;
            }
            // This time, allow SW renderer
            pr = this->drawingManager()->getPathRenderer(canDrawArgs, kAllowSWPathRenderer,
                                                         DrawType::kColor);
        } else {
            pr = this->drawingManager()->getSoftwarePathRenderer();
#if GR_PATH_RENDERER_SPEW
            SkDebugf("falling back to: %s\n", pr->name());
#endif
        }
    }

    if (!pr) {
#ifdef SK_DEBUG
        SkDebugf("Unable to find path renderer compatible with path.\n");
#endif
        return;
    }

    GrPathRenderer::DrawPathArgs args{this->drawingManager()->getContext(),
                                      std::move(paint),
                                      &GrUserStencilSettings::kUnused,
                                      this,
                                      clip,
                                      &clipConservativeBounds,
                                      &viewMatrix,
                                      canDrawArgs.fShape,
                                      aaType,
                                      this->colorInfo().isLinearlyBlended()};
    pr->drawPath(args);
#endif
}

static void op_bounds(SkRect* bounds, const GrOp* op) {
    *bounds = op->bounds();
    if (op->hasZeroArea()) {
        if (op->hasAABloat()) {
            bounds->outset(0.5f, 0.5f);
        } else {
            // We don't know which way the particular GPU will snap lines or points at integer
            // coords. So we ensure that the bounds is large enough for either snap.
            SkRect before = *bounds;
            bounds->roundOut(bounds);
            if (bounds->fLeft == before.fLeft) {
                bounds->fLeft -= 1;
            }
            if (bounds->fTop == before.fTop) {
                bounds->fTop -= 1;
            }
            if (bounds->fRight == before.fRight) {
                bounds->fRight += 1;
            }
            if (bounds->fBottom == before.fBottom) {
                bounds->fBottom += 1;
            }
        }
    }
}

void GrSurfaceDrawContext::addDrawOp(const GrClip* clip,
                                     GrOp::Owner op,
                                     const std::function<WillAddOpFn>& willAddFn) {
    ASSERT_SINGLE_OWNER
    if (fContext->abandoned()) {
        return;
    }
    GrDrawOp* drawOp = (GrDrawOp*)op.get();
    SkDEBUGCODE(this->validate();)
    SkDEBUGCODE(drawOp->fAddDrawOpCalled = true;)
    GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "addDrawOp", fContext);

    // Setup clip
    SkRect bounds;
    op_bounds(&bounds, op.get());
    GrAppliedClip appliedClip(this->dimensions(), this->asSurfaceProxy()->backingStoreDimensions());
    const bool opUsesMSAA = drawOp->usesMSAA();
    bool skipDraw = false;
    if (clip) {
        // Have a complex clip, so defer to its early clip culling
        GrAAType aaType;
        if (opUsesMSAA) {
            aaType = GrAAType::kMSAA;
        } else {
            aaType = op->hasAABloat() ? GrAAType::kCoverage : GrAAType::kNone;
        }
        skipDraw = clip->apply(fContext, this, drawOp, aaType,
                               &appliedClip, &bounds) == GrClip::Effect::kClippedOut;
    } else {
        // No clipping, so just clip the bounds against the logical render target dimensions
        skipDraw = !bounds.intersect(this->asSurfaceProxy()->getBoundsRect());
    }

    if (skipDraw) {
        return;
    }

    GrClampType clampType = GrColorTypeClampType(this->colorInfo().colorType());
    GrProcessorSet::Analysis analysis = drawOp->finalize(*this->caps(), &appliedClip, clampType);

    const bool opUsesStencil = drawOp->usesStencil();

    // Always trigger DMSAA when there is stencil. This ensures stencil contents get properly
    // preserved between render passes, if needed.
    const bool drawNeedsMSAA = opUsesMSAA || (fCanUseDynamicMSAA && opUsesStencil);

    // Must be called before setDstProxyView so that it sees the final bounds of the op.
    op->setClippedBounds(bounds);

    // Determine if the Op will trigger the use of a separate DMSAA attachment that requires manual
    // resolves.
    // TODO: Currently usesAttachmentIfDMSAA checks if this is a textureProxy or not. This check is
    // really only for GL which uses a normal texture sampling when using barriers. For Vulkan it
    // is possible to use the msaa buffer as an input attachment even if this is not a texture.
    // However, support for that is not fully implemented yet in Vulkan. Once it is, this check
    // should change to a virtual caps check that returns whether we need to break up an OpsTask
    // if it has barriers and we are about to promote to MSAA.
    bool usesAttachmentIfDMSAA =
            fCanUseDynamicMSAA &&
            (!this->caps()->msaaResolvesAutomatically() || !this->asTextureProxy());
    bool opRequiresDMSAAAttachment = usesAttachmentIfDMSAA && drawNeedsMSAA;
    bool opTriggersDMSAAAttachment =
            opRequiresDMSAAAttachment && !this->getOpsTask()->usesMSAASurface();
    if (opTriggersDMSAAAttachment) {
        // This will be the op that actually triggers use of a DMSAA attachment. Texture barriers
        // can't be moved to a DMSAA attachment, so if there already are any on the current opsTask
        // then we need to split.
        if (this->getOpsTask()->renderPassXferBarriers() & GrXferBarrierFlags::kTexture) {
            SkASSERT(!this->getOpsTask()->isColorNoOp());
            this->replaceOpsTask()->setCannotMergeBackward();
        }
    }

    GrDstProxyView dstProxyView;
    if (analysis.requiresDstTexture()) {
        if (!this->setupDstProxyView(drawOp->bounds(), drawNeedsMSAA, &dstProxyView)) {
            return;
        }
#ifdef SK_DEBUG
        if (fCanUseDynamicMSAA && drawNeedsMSAA && !this->caps()->msaaResolvesAutomatically()) {
            // Since we aren't literally writing to the render target texture while using a DMSAA
            // attachment, we need to resolve that texture before sampling it. Ensure the current
            // opsTask got closed off in order to initiate an implicit resolve.
            SkASSERT(this->getOpsTask()->isEmpty());
        }
#endif
    }

    auto opsTask = this->getOpsTask();
    if (willAddFn) {
        willAddFn(op.get(), opsTask->uniqueID());
    }

    // Note if the op needs stencil. Stencil clipping already called setNeedsStencil for itself, if
    // needed.
    if (opUsesStencil) {
        this->setNeedsStencil();
    }

#if GR_GPU_STATS && GR_TEST_UTILS
    if (fCanUseDynamicMSAA && drawNeedsMSAA) {
        if (!opsTask->usesMSAASurface()) {
            fContext->priv().dmsaaStats().fNumMultisampleRenderPasses++;
        }
        fContext->priv().dmsaaStats().fTriggerCounts[op->name()]++;
    }
#endif

    opsTask->addDrawOp(this->drawingManager(), std::move(op), drawNeedsMSAA, analysis,
                       std::move(appliedClip), dstProxyView,
                       GrTextureResolveManager(this->drawingManager()), *this->caps());

#ifdef SK_DEBUG
    if (fCanUseDynamicMSAA && drawNeedsMSAA) {
        SkASSERT(opsTask->usesMSAASurface());
    }
#endif
}

bool GrSurfaceDrawContext::setupDstProxyView(const SkRect& opBounds,
                                             bool opRequiresMSAA,
                                             GrDstProxyView* dstProxyView) {
    // If we are wrapping a vulkan secondary command buffer, we can't make a dst copy because we
    // don't actually have a VkImage to make a copy of. Additionally we don't have the power to
    // start and stop the render pass in order to make the copy.
    if (this->asRenderTargetProxy()->wrapsVkSecondaryCB()) {
        return false;
    }

    // First get the dstSampleFlags as if we will put the draw into the current GrOpsTask
    auto dstSampleFlags = this->caps()->getDstSampleFlagsForProxy(
            this->asRenderTargetProxy(), this->getOpsTask()->usesMSAASurface() || opRequiresMSAA);

    // If we don't have barriers for this draw then we will definitely be breaking up the GrOpsTask.
    // However, if using dynamic MSAA, the new GrOpsTask will not have MSAA already enabled on it
    // and that may allow us to use texture barriers. So we check if we can use barriers on the new
    // ops task and then break it up if so.
    if (!(dstSampleFlags & GrDstSampleFlags::kRequiresTextureBarrier) &&
        fCanUseDynamicMSAA && this->getOpsTask()->usesMSAASurface() && !opRequiresMSAA) {
        auto newFlags =
                this->caps()->getDstSampleFlagsForProxy(this->asRenderTargetProxy(),
                                                        false/*=opRequiresMSAA*/);
        if (newFlags & GrDstSampleFlags::kRequiresTextureBarrier) {
            // We can't have an empty ops task if we are in DMSAA and the ops task already returns
            // true for usesMSAASurface.
            SkASSERT(!this->getOpsTask()->isColorNoOp());
            this->replaceOpsTask()->setCannotMergeBackward();
            dstSampleFlags = newFlags;
        }
    }

    if (dstSampleFlags & GrDstSampleFlags::kRequiresTextureBarrier) {
        // If we require a barrier to sample the dst it means we are sampling the RT itself
        // either as a texture or input attachment. In this case we don't need to break up the
        // GrOpsTask.
        dstProxyView->setProxyView(this->readSurfaceView());
        dstProxyView->setOffset(0, 0);
        dstProxyView->setDstSampleFlags(dstSampleFlags);
        return true;
    }
    SkASSERT(dstSampleFlags == GrDstSampleFlags::kNone);

    // We are using a different surface from the main color attachment to sample the dst from. If we
    // are in DMSAA we can just use the single sampled RT texture itself. Otherwise, we must do a
    // copy.
    // We do have to check if we ended up here becasue we don't have texture barriers but do have
    // msaaResolvesAutomatically (i.e. render-to-msaa-texture). In that case there will be no op or
    // barrier between draws to flush the render target before being used as a texture in the next
    // draw. So in that case we just fall through to doing a copy.
    if (fCanUseDynamicMSAA && opRequiresMSAA && this->asTextureProxy() &&
        !this->caps()->msaaResolvesAutomatically()) {
        this->replaceOpsTaskIfModifiesColor()->setCannotMergeBackward();
        dstProxyView->setProxyView(this->readSurfaceView());
        dstProxyView->setOffset(0, 0);
        dstProxyView->setDstSampleFlags(dstSampleFlags);
        return true;
    }

    // Now we fallback to doing a copy.

    GrColorType colorType = this->colorInfo().colorType();
    // MSAA consideration: When there is support for reading MSAA samples in the shader we could
    // have per-sample dst values by making the copy multisampled.
    GrCaps::DstCopyRestrictions restrictions = this->caps()->getDstCopyRestrictions(
            this->asRenderTargetProxy(), colorType);

    SkIRect copyRect = SkIRect::MakeSize(this->asSurfaceProxy()->backingStoreDimensions());
    if (!restrictions.fMustCopyWholeSrc) {
        // If we don't need the whole source, restrict to the op's bounds. We add an extra pixel
        // of padding to account for AA bloat and the unpredictable rounding of coords near pixel
        // centers during rasterization.
        SkIRect conservativeDrawBounds = opBounds.roundOut();
        conservativeDrawBounds.outset(1, 1);
        SkAssertResult(copyRect.intersect(conservativeDrawBounds));
    }

    SkIPoint dstOffset;
    SkBackingFit fit;
    if (restrictions.fRectsMustMatch == GrSurfaceProxy::RectsMustMatch::kYes) {
        dstOffset = {0, 0};
        fit = SkBackingFit::kExact;
    } else {
        dstOffset = {copyRect.fLeft, copyRect.fTop};
        fit = SkBackingFit::kApprox;
    }
    auto copy = GrSurfaceProxy::Copy(fContext,
                                     this->asSurfaceProxyRef(),
                                     this->origin(),
                                     GrMipmapped::kNo,
                                     copyRect,
                                     fit,
                                     SkBudgeted::kYes,
                                     restrictions.fRectsMustMatch);
    SkASSERT(copy);

    dstProxyView->setProxyView({std::move(copy), this->origin(), this->readSwizzle()});
    dstProxyView->setOffset(dstOffset);
    dstProxyView->setDstSampleFlags(dstSampleFlags);
    return true;
}

GrOpsTask* GrSurfaceDrawContext::replaceOpsTaskIfModifiesColor() {
    if (!this->getOpsTask()->isColorNoOp()) {
        this->replaceOpsTask();
    }
    return this->getOpsTask();
}
