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

#ifndef GrSurfaceDrawContext_DEFINED
#define GrSurfaceDrawContext_DEFINED

#include "include/core/SkCanvas.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/private/GrTypesPriv.h"
#include "src/core/SkGlyphRunPainter.h"
#include "src/gpu/GrOpsTask.h"
#include "src/gpu/GrPaint.h"
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/GrSurfaceFillContext.h"
#include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/text/GrTextBlob.h"

class GrBackendSemaphore;
class GrClip;
class GrColorSpaceXform;
class GrCoverageCountingPathRenderer;
class GrDrawOp;
class GrOp;
class GrRenderTarget;
class GrStyledShape;
class GrStyle;
class GrTextureProxy;
struct GrUserStencilSettings;
struct SkDrawShadowRec;
class SkGlyphRunList;
struct SkIPoint;
struct SkIRect;
class SkLatticeIter;
class SkMatrixProvider;
class SkMatrix;
class SkPaint;
class SkPath;
struct SkPoint;
struct SkRect;
class SkRegion;
class SkRRect;
struct SkRSXform;
class SkRuntimeEffect;
class SkTextBlob;
class SkVertices;

/**
 * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
 */
class GrSurfaceDrawContext : public GrSurfaceFillContext {
public:
    static std::unique_ptr<GrSurfaceDrawContext> Make(GrRecordingContext*,
                                                      GrColorType,
                                                      sk_sp<SkColorSpace>,
                                                      sk_sp<GrSurfaceProxy>,
                                                      GrSurfaceOrigin,
                                                      const SkSurfaceProps*,
                                                      bool flushTimeOpsTask = false);

    /* Uses the default texture format for the color type */
    static std::unique_ptr<GrSurfaceDrawContext> Make(GrRecordingContext*,
                                                      GrColorType,
                                                      sk_sp<SkColorSpace>,
                                                      SkBackingFit,
                                                      SkISize dimensions,
                                                      int sampleCnt = 1,
                                                      GrMipmapped = GrMipmapped::kNo,
                                                      GrProtected = GrProtected::kNo,
                                                      GrSurfaceOrigin = kBottomLeft_GrSurfaceOrigin,
                                                      SkBudgeted = SkBudgeted::kYes,
                                                      const SkSurfaceProps* = nullptr);

    /**
     * Takes custom swizzles rather than determining swizzles from color type and format.
     * It will have color type kUnknown.
     */
    static std::unique_ptr<GrSurfaceDrawContext> Make(GrRecordingContext*,
                                                      sk_sp<SkColorSpace>,
                                                      SkBackingFit,
                                                      SkISize dimensions,
                                                      const GrBackendFormat&,
                                                      int sampleCnt,
                                                      GrMipmapped,
                                                      GrProtected,
                                                      GrSwizzle readSwizzle,
                                                      GrSwizzle writeSwizzle,
                                                      GrSurfaceOrigin,
                                                      SkBudgeted,
                                                      const SkSurfaceProps*);

    // Same as previous factory but will try to use fallback GrColorTypes if the one passed in
    // fails. The fallback GrColorType will have at least the number of channels and precision per
    // channel as the passed in GrColorType. It may also swizzle the changes (e.g., BGRA -> RGBA).
    // SRGB-ness will be preserved.
    static std::unique_ptr<GrSurfaceDrawContext> MakeWithFallback(
            GrRecordingContext*,
            GrColorType,
            sk_sp<SkColorSpace>,
            SkBackingFit,
            SkISize dimensions,
            int sampleCnt = 1,
            GrMipmapped = GrMipmapped::kNo,
            GrProtected = GrProtected::kNo,
            GrSurfaceOrigin = kBottomLeft_GrSurfaceOrigin,
            SkBudgeted = SkBudgeted::kYes,
            const SkSurfaceProps* = nullptr);

    // These match the definitions in SkSurface & GrSurface.h, for whence they came
    typedef void* ReleaseContext;
    typedef void (*ReleaseProc)(ReleaseContext);

    // Creates a GrSurfaceDrawContext that wraps the passed in GrBackendTexture.
    static std::unique_ptr<GrSurfaceDrawContext> MakeFromBackendTexture(
            GrRecordingContext*, GrColorType, sk_sp<SkColorSpace>, const GrBackendTexture&,
            int sampleCnt, GrSurfaceOrigin, const SkSurfaceProps*,
            sk_sp<GrRefCntedCallback> releaseHelper);

    static std::unique_ptr<GrSurfaceDrawContext> MakeFromBackendRenderTarget(
            GrRecordingContext*,
            GrColorType,
            sk_sp<SkColorSpace>,
            const GrBackendRenderTarget&,
            GrSurfaceOrigin,
            const SkSurfaceProps*,
            sk_sp<GrRefCntedCallback> releaseHelper);

    static std::unique_ptr<GrSurfaceDrawContext> MakeFromVulkanSecondaryCB(
            GrRecordingContext*, const SkImageInfo&, const GrVkDrawableInfo&,
            const SkSurfaceProps*);

    GrSurfaceDrawContext(GrRecordingContext*,
                         GrSurfaceProxyView readView,
                         GrSurfaceProxyView writeView,
                         GrColorType,
                         sk_sp<SkColorSpace>,
                         const SkSurfaceProps*,
                         bool flushTimeOpsTask = false);

    ~GrSurfaceDrawContext() override;

    /**
     *  Draw everywhere (respecting the clip) with the paint.
     */
    void drawPaint(const GrClip*, GrPaint&&, const SkMatrix& viewMatrix);

    /**
     * Draw the rect using a paint.
     * @param paint        describes how to color pixels.
     * @param GrAA         Controls whether rect is antialiased
     * @param viewMatrix   transformation matrix
     * @param style        The style to apply. Null means fill. Currently path effects are not
     *                     allowed.
     * The rects coords are used to access the paint (through texture matrix)
     */
    void drawRect(const GrClip*,
                  GrPaint&& paint,
                  GrAA,
                  const SkMatrix& viewMatrix,
                  const SkRect&,
                  const GrStyle* style = nullptr);

    /**
     * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
     *
     * @param paint        describes how to color pixels.
     * @param GrAA         Controls whether rect is antialiased
     * @param viewMatrix   transformation matrix which applies to rectToDraw
     * @param rectToDraw   the rectangle to draw
     * @param localRect    the rectangle of shader coordinates applied to rectToDraw
     */
    void 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};
        this->drawFilledQuad(clip, std::move(paint), aa, &quad);
    }

    /**
     * Fills a rect with a paint and a localMatrix.
     */
    void fillRectWithLocalMatrix(const GrClip* clip,
                                 GrPaint&& paint,
                                 GrAA aa,
                                 const SkMatrix& viewMatrix,
                                 const SkRect& rect,
                                 const SkMatrix& localMatrix) {
        DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix),
                      GrQuad::MakeFromRect(rect, localMatrix),
                      aa == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone};
        this->drawFilledQuad(clip, std::move(paint), aa, &quad);
    }

    /**
     * Creates an op that draws a fill rect with per-edge control over anti-aliasing.
     *
     * This is a specialized version of fillQuadWithEdgeAA, but is kept separate since knowing
     * the geometry is a rectangle affords more optimizations.
     */
    void fillRectWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrAA aa, GrQuadAAFlags edgeAA,
                            const SkMatrix& viewMatrix, const SkRect& rect,
                            const SkRect* optionalLocalRect = nullptr) {
        const SkRect& localRect = optionalLocalRect ? *optionalLocalRect : rect;
        DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(localRect), edgeAA};
        this->drawFilledQuad(clip, std::move(paint), aa, &quad);
    }

    /**
     * Similar to fillRectWithEdgeAA but draws an arbitrary 2D convex quadrilateral transformed
     * by 'viewMatrix', with per-edge control over anti-aliasing. The quad should follow the
     * ordering used by SkRect::toQuad(), which determines how the edge AA is applied:
     *  - "top" = points [0] and [1]
     *  - "right" = points[1] and [2]
     *  - "bottom" = points[2] and [3]
     *  - "left" = points[3] and [0]
     *
     * The last argument, 'optionalLocalQuad', can be null if no separate local coordinates are
     * necessary.
     */
    void fillQuadWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrAA aa, GrQuadAAFlags edgeAA,
                            const SkMatrix& viewMatrix, const SkPoint points[4],
                            const SkPoint optionalLocalPoints[4]) {
        const SkPoint* localPoints = optionalLocalPoints ? optionalLocalPoints : points;
        DrawQuad quad{GrQuad::MakeFromSkQuad(points, viewMatrix),
                      GrQuad::MakeFromSkQuad(localPoints, SkMatrix::I()), edgeAA};
        this->drawFilledQuad(clip, std::move(paint), aa, &quad);
    }

    /** Used with drawQuadSet */
    struct QuadSetEntry {
        SkRect fRect;
        SkPMColor4f fColor; // Overrides any color on the GrPaint
        SkMatrix fLocalMatrix;
        GrQuadAAFlags fAAFlags;
    };

    // TODO(michaelludwig) - remove if the bulk API is not useful for SkiaRenderer
    void drawQuadSet(const GrClip* clip, GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix,
                     const QuadSetEntry[], int cnt);

    /**
     * Creates an op that draws a subrectangle of a texture. The passed color is modulated by the
     * texture's color. 'srcRect' specifies the rectangle of the texture to draw. 'dstRect'
     * specifies the rectangle to draw in local coords which will be transformed by 'viewMatrix' to
     * device space.
     */
    void drawTexture(const GrClip* clip,
                     GrSurfaceProxyView view,
                     SkAlphaType srcAlphaType,
                     GrSamplerState::Filter filter,
                     GrSamplerState::MipmapMode mm,
                     SkBlendMode mode,
                     const SkPMColor4f& color,
                     const SkRect& srcRect,
                     const SkRect& dstRect,
                     GrAA aa,
                     GrQuadAAFlags edgeAA,
                     SkCanvas::SrcRectConstraint constraint,
                     const SkMatrix& viewMatrix,
                     sk_sp<GrColorSpaceXform> texXform) {
        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(texXform), filter, mm,
                               color, mode, aa, &quad, subset);
    }

    /**
     * Variant of drawTexture that instead draws the texture applied to 'dstQuad' transformed by
     * 'viewMatrix', using the 'srcQuad' texture coordinates clamped to the optional 'subset'. If
     * 'subset' is null, it's equivalent to using the fast src rect constraint. If 'subset' is
     * provided, the strict src rect constraint is applied using 'subset'.
     */
    void drawTextureQuad(const GrClip* clip,
                         GrSurfaceProxyView view,
                         GrColorType srcColorType,
                         SkAlphaType srcAlphaType,
                         GrSamplerState::Filter filter,
                         GrSamplerState::MipmapMode mm,
                         SkBlendMode mode,
                         const SkPMColor4f& color,
                         const SkPoint srcQuad[4],
                         const SkPoint dstQuad[4],
                         GrAA aa,
                         GrQuadAAFlags edgeAA,
                         const SkRect* subset,
                         const SkMatrix& viewMatrix,
                         sk_sp<GrColorSpaceXform> texXform) {
        DrawQuad quad{GrQuad::MakeFromSkQuad(dstQuad, viewMatrix),
                      GrQuad::MakeFromSkQuad(srcQuad, SkMatrix::I()), edgeAA};
        this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(texXform), filter, mm,
                               color, mode, aa, &quad, subset);
    }

    /** Used with drawTextureSet */
    struct TextureSetEntry {
        GrSurfaceProxyView fProxyView;
        SkAlphaType fSrcAlphaType;
        SkRect fSrcRect;
        SkRect fDstRect;
        const SkPoint* fDstClipQuad; // Must be null, or point to an array of 4 points
        const SkMatrix* fPreViewMatrix; // If not null, entry's CTM is 'viewMatrix' * fPreViewMatrix
        SkPMColor4f   fColor; // {a,a,a,a} for rgb textures, {r,g,b,a} for alpha-only textures
        GrQuadAAFlags fAAFlags;
    };
    /**
     * Draws a set of textures with a shared filter, color, view matrix, color xform, and
     * texture color xform. The textures must all have the same GrTextureType and GrConfig.
     *
     * If any entries provide a non-null fDstClip array, it will be read from immediately based on
     * fDstClipCount, so the pointer can become invalid after this returns.
     *
     * 'proxRunCnt' is the number of proxy changes encountered in the entry array. Technically this
     * can be inferred from the array within this function, but the information is already known
     * by SkGpuDevice, so no need to incur another iteration over the array.
     */
    void drawTextureSet(const GrClip*,
                        TextureSetEntry[],
                        int cnt,
                        int proxyRunCnt,
                        GrSamplerState::Filter,
                        GrSamplerState::MipmapMode,
                        SkBlendMode mode,
                        GrAA aa,
                        SkCanvas::SrcRectConstraint,
                        const SkMatrix& viewMatrix,
                        sk_sp<GrColorSpaceXform> texXform);

    /**
     * Draw a roundrect using a paint.
     *
     * @param paint       describes how to color pixels.
     * @param GrAA        Controls whether rrect is antialiased.
     * @param viewMatrix  transformation matrix
     * @param rrect       the roundrect to draw
     * @param style       style to apply to the rrect. Currently path effects are not allowed.
     */
    void drawRRect(const GrClip*,
                   GrPaint&&,
                   GrAA,
                   const SkMatrix& viewMatrix,
                   const SkRRect& rrect,
                   const GrStyle& style);

    /**
     * Use a fast method to render the ambient and spot shadows for a path.
     * Will return false if not possible for the given path.
     *
     * @param viewMatrix   transformation matrix
     * @param path         the path to shadow
     * @param rec          parameters for shadow rendering
     */
    bool drawFastShadow(const GrClip*,
                        const SkMatrix& viewMatrix,
                        const SkPath& path,
                        const SkDrawShadowRec& rec);

    /**
     * Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
     * undefined if outer does not contain inner.
     *
     * @param paint        describes how to color pixels.
     * @param GrAA         Controls whether rrects edges are antialiased
     * @param viewMatrix   transformation matrix
     * @param outer        the outer roundrect
     * @param inner        the inner roundrect
     */
    void drawDRRect(const GrClip*,
                    GrPaint&&,
                    GrAA,
                    const SkMatrix& viewMatrix,
                    const SkRRect& outer,
                    const SkRRect& inner);

    /**
     * Draws a path.
     *
     * @param paint         describes how to color pixels.
     * @param GrAA          Controls whether the path is antialiased.
     * @param viewMatrix    transformation matrix
     * @param path          the path to draw
     * @param style         style to apply to the path.
     */
    void drawPath(const GrClip*,
                  GrPaint&&,
                  GrAA,
                  const SkMatrix& viewMatrix,
                  const SkPath&,
                  const GrStyle&);

    /**
     * Draws a shape.
     *
     * @param paint         describes how to color pixels.
     * @param GrAA          Controls whether the path is antialiased.
     * @param viewMatrix    transformation matrix
     * @param shape         the shape to draw
     */
    void drawShape(const GrClip*,
                   GrPaint&&,
                   GrAA,
                   const SkMatrix& viewMatrix,
                   GrStyledShape&&);


    /**
     * Draws vertices with a paint.
     *
     * @param   paint            describes how to color pixels.
     * @param   viewMatrix       transformation matrix
     * @param   vertices         specifies the mesh to draw.
     * @param   overridePrimType primitive type to draw. If NULL, derive prim type from vertices.
     * @param   effect           runtime effect that will handle custom vertex attributes.
     */
    void drawVertices(const GrClip*,
                      GrPaint&& paint,
                      const SkMatrixProvider& matrixProvider,
                      sk_sp<SkVertices> vertices,
                      GrPrimitiveType* overridePrimType = nullptr,
                      const SkRuntimeEffect* effect = nullptr);

    /**
     * Draws textured sprites from an atlas with a paint. This currently does not support AA for the
     * sprite rectangle edges.
     *
     * @param   paint           describes how to color pixels.
     * @param   viewMatrix      transformation matrix
     * @param   spriteCount     number of sprites.
     * @param   xform           array of compressed transformation data, required.
     * @param   texRect         array of texture rectangles used to access the paint.
     * @param   colors          optional array of per-sprite colors, supercedes
     *                          the paint's color field.
     */
    void drawAtlas(const GrClip*,
                   GrPaint&& paint,
                   const SkMatrix& viewMatrix,
                   int spriteCount,
                   const SkRSXform xform[],
                   const SkRect texRect[],
                   const SkColor colors[]);

    /**
     * Draws a region.
     *
     * @param paint         describes how to color pixels
     * @param viewMatrix    transformation matrix
     * @param aa            should the rects of the region be antialiased.
     * @param region        the region to be drawn
     * @param style         style to apply to the region
     */
    void drawRegion(const GrClip*,
                    GrPaint&& paint,
                    GrAA aa,
                    const SkMatrix& viewMatrix,
                    const SkRegion& region,
                    const GrStyle& style,
                    const GrUserStencilSettings* ss = nullptr);

    /**
     * Draws an oval.
     *
     * @param paint         describes how to color pixels.
     * @param GrAA          Controls whether the oval is antialiased.
     * @param viewMatrix    transformation matrix
     * @param oval          the bounding rect of the oval.
     * @param style         style to apply to the oval. Currently path effects are not allowed.
     */
    void drawOval(const GrClip*,
                  GrPaint&& paint,
                  GrAA,
                  const SkMatrix& viewMatrix,
                  const SkRect& oval,
                  const GrStyle& style);

    /**
     * Draws a partial arc of an oval.
     *
     * @param paint         describes how to color pixels.
     * @param GrGrAA        Controls whether the arc is antialiased.
     * @param viewMatrix    transformation matrix.
     * @param oval          the bounding rect of the oval.
     * @param startAngle    starting angle in degrees.
     * @param sweepAngle    angle to sweep in degrees. Must be in (-360, 360)
     * @param useCenter     true means that the implied path begins at the oval center, connects as
     *                      a line to the point indicated by the start contains the arc indicated by
     *                      the sweep angle. If false the line beginning at the center point is
     *                      omitted.
     * @param style         style to apply to the oval.
     */
    void drawArc(const GrClip*,
                 GrPaint&& paint,
                 GrAA,
                 const SkMatrix& viewMatrix,
                 const SkRect& oval,
                 SkScalar startAngle,
                 SkScalar sweepAngle,
                 bool useCenter,
                 const GrStyle& style);

    /**
     * Draw the image as a set of rects, specified by |iter|.
     */
    void drawImageLattice(const GrClip*,
                          GrPaint&&,
                          const SkMatrix& viewMatrix,
                          GrSurfaceProxyView,
                          SkAlphaType alphaType,
                          sk_sp<GrColorSpaceXform>,
                          GrSamplerState::Filter,
                          std::unique_ptr<SkLatticeIter>,
                          const SkRect& dst);

    /**
     * Draw the text specified by the SkGlyphRunList.
     *
     * @param viewMatrix      transformationMatrix
     * @param glyphRunList    text, text positions, and paint.
     */
    void drawGlyphRunList(const GrClip*,
                          const SkMatrixProvider& viewMatrix,
                          const SkGlyphRunList& glyphRunList);

    /**
     * Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the
     * command stream.
     */
    void drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>, const SkRect& bounds);

    // called to note the last clip drawn to the stencil buffer.
    // TODO: remove after clipping overhaul.
    void setLastClip(uint32_t clipStackGenID,
                     const SkIRect& devClipBounds,
                     int numClipAnalyticElements) {
        GrOpsTask* opsTask = this->getOpsTask();
        opsTask->fLastClipStackGenID = clipStackGenID;
        opsTask->fLastDevClipBounds = devClipBounds;
        opsTask->fLastClipNumAnalyticElements = numClipAnalyticElements;
    }

    // called to determine if we have to render the clip into SB.
    // TODO: remove after clipping overhaul.
    bool mustRenderClip(uint32_t clipStackGenID,
                        const SkIRect& devClipBounds,
                        int numClipAnalyticElements) {
        GrOpsTask* opsTask = this->getOpsTask();
        return opsTask->fLastClipStackGenID != clipStackGenID ||
               !opsTask->fLastDevClipBounds.contains(devClipBounds) ||
               opsTask->fLastClipNumAnalyticElements != numClipAnalyticElements;
    }

    void clearStencilClip(const SkIRect& scissor, bool insideStencilMask) {
        this->internalStencilClear(&scissor, insideStencilMask);
    }

    // While this can take a general clip, since GrReducedClip relies on this function, it must take
    // care to only provide hard clips or we could get stuck in a loop. The general clip is needed
    // so that path renderers can use this function.
    void stencilRect(const GrClip* clip,
                     const GrUserStencilSettings* ss,
                     GrPaint&& paint,
                     GrAA doStencilMSAA,
                     const SkMatrix& viewMatrix,
                     const SkRect& rect,
                     const SkMatrix* localMatrix = nullptr) {
        // Since this provides stencil settings to drawFilledQuad, it performs a different AA type
        // resolution compared to regular rect draws, which is the main reason it remains separate.
        DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix),
                      localMatrix ? GrQuad::MakeFromRect(rect, *localMatrix) : GrQuad(rect),
                      GrQuadAAFlags::kNone};
        this->drawFilledQuad(clip, std::move(paint), doStencilMSAA, &quad, ss);
    }

    void stencilPath(const GrHardClip*,
                     GrAA doStencilMSAA,
                     const SkMatrix& viewMatrix,
                     sk_sp<const GrPath>);

    /**
     * Draws a path, either AA or not, and touches the stencil buffer with the user stencil settings
     * for each color sample written.
     */
    bool drawAndStencilPath(const GrHardClip*,
                            const GrUserStencilSettings*,
                            SkRegion::Op op,
                            bool invert,
                            GrAA doStencilMSAA,
                            const SkMatrix& viewMatrix,
                            const SkPath&);

    SkBudgeted isBudgeted() const;

    int maxWindowRectangles() const;

    SkGlyphRunListPainter* glyphRunPainter() { return &fGlyphPainter; }

    /*
     * This unique ID will not change for a given RenderTargetContext. However, it is _NOT_
     * guaranteed to match the uniqueID of the underlying GrRenderTarget - beware!
     */
    GrSurfaceProxy::UniqueID uniqueID() const { return this->asSurfaceProxy()->uniqueID(); }

    // Allows caller of addDrawOp to know which op list an op will be added to.
    using WillAddOpFn = void(GrOp*, uint32_t opsTaskID);
    // These perform processing specific to GrDrawOp-derived ops before recording them into an
    // op list. Before adding the op to an op list the WillAddOpFn is called. Note that it
    // will not be called in the event that the op is discarded. Moreover, the op may merge into
    // another op after the function is called (either before addDrawOp returns or some time later).
    //
    // If the clip pointer is null, no clipping will be performed.
    void addDrawOp(const GrClip*,
                   GrOp::Owner,
                   const std::function<WillAddOpFn>& = std::function<WillAddOpFn>());
    void addDrawOp(GrOp::Owner op) { this->addDrawOp(nullptr, std::move(op)); }

    bool refsWrappedObjects() const { return this->asRenderTargetProxy()->refsWrappedObjects(); }

    /**
     *  The next time this GrSurfaceDrawContext is flushed, the gpu will wait on the passed in
     *  semaphores before executing any commands.
     */
    bool waitOnSemaphores(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
                          bool deleteSemaphoresAfterWait);

    int numSamples() const { return this->asRenderTargetProxy()->numSamples(); }
    const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
    bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
    GrMipmapped mipmapped() const;

    // This entry point should only be called if the backing GPU object is known to be
    // instantiated.
    GrRenderTarget* accessRenderTarget() { return this->asSurfaceProxy()->peekRenderTarget(); }

    GrSurfaceDrawContext* asRenderTargetContext() override { return this; }

#if GR_TEST_UTILS
    void testingOnly_SetPreserveOpsOnFullClear() { fPreserveOpsOnFullClear_TestingOnly = true; }
#endif

private:
    enum class QuadOptimization;

    GrAAType chooseAAType(GrAA);

    GrOpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const override;
    void setNeedsStencil(bool useMixedSamplesIfNotMSAA);

    void internalStencilClear(const SkIRect* scissor, bool insideStencilMask);

    // Only consumes the GrPaint if successful.
    bool drawFilledDRRect(const GrClip* clip,
                          GrPaint&& paint,
                          GrAA,
                          const SkMatrix& viewMatrix,
                          const SkRRect& origOuter,
                          const SkRRect& origInner);

    // If the drawn quad's paint is a const blended color, provide it as a non-null pointer to
    // 'constColor', which enables the draw-as-clear optimization. Otherwise it is assumed the paint
    // requires some form of shading that invalidates using a clear op.
    //
    // The non-const pointers should be the original draw request on input, and will be updated as
    // appropriate depending on the returned optimization level.
    //
    // 'stencilSettings' are provided merely for decision making purposes; When non-null,
    // optimization strategies that submit special ops are avoided.
    QuadOptimization attemptQuadOptimization(const GrClip* clip,
                                             const SkPMColor4f* constColor,
                                             const GrUserStencilSettings* stencilSettings,
                                             GrAA* aa,
                                             DrawQuad* quad);

    // If stencil settings, 'ss', are non-null, AA controls MSAA or no AA. If they are null, then AA
    // can choose between coverage, MSAA as per chooseAAType(). This will always attempt to apply
    // quad optimizations, so all quad/rect public APIs should rely on this function for consistent
    // clipping behavior. 'quad' will be modified in place to reflect final rendered geometry.
    void drawFilledQuad(const GrClip* clip,
                        GrPaint&& paint,
                        GrAA aa,
                        DrawQuad* quad,
                        const GrUserStencilSettings* ss = nullptr);

    // Like drawFilledQuad but does not require using a GrPaint or FP for texturing.
    // 'quad' may be modified in place to reflect final geometry.
    void drawTexturedQuad(const GrClip* clip,
                          GrSurfaceProxyView proxyView,
                          SkAlphaType alphaType,
                          sk_sp<GrColorSpaceXform> textureXform,
                          GrSamplerState::Filter filter,
                          GrSamplerState::MipmapMode,
                          const SkPMColor4f& color,
                          SkBlendMode blendMode,
                          GrAA aa,
                          DrawQuad* quad,
                          const SkRect* subset = nullptr);

    void drawStrokedLine(const GrClip*, GrPaint&&, GrAA, const SkMatrix&, const SkPoint[2],
                         const SkStrokeRec&);

    // Tries to detect if the given shape is a simple, and draws it without path rendering if
    // we know how.
    bool drawSimpleShape(const GrClip*, GrPaint*, GrAA, const SkMatrix&, const GrStyledShape&);

    // If 'attemptDrawSimple' is true, of if the original shape is marked as having been simplfied,
    // this will attempt to re-route through drawSimpleShape() to see if we can avoid path rendering
    // one more time.
    void drawShapeUsingPathRenderer(const GrClip*, GrPaint&&, GrAA, const SkMatrix&,
                                    GrStyledShape&&, bool attemptDrawSimple = false);

    // Makes a copy of the proxy if it is necessary for the draw and places the texture that should
    // be used by GrXferProcessor to access the destination color in 'result'. If the return
    // value is false then a texture copy could not be made.
    //
    // The op should have already had setClippedBounds called on it.
    bool SK_WARN_UNUSED_RESULT setupDstProxyView(const GrOp& op,
                                                 GrXferProcessor::DstProxyView* result);

    SkGlyphRunListPainter* glyphPainter() { return &fGlyphPainter; }

    SkSurfaceProps fSurfaceProps;

    int fNumStencilSamples = 0;

    GrDstSampleType fDstSampleType = GrDstSampleType::kNone;

#if GR_TEST_UTILS
    bool fPreserveOpsOnFullClear_TestingOnly = false;
#endif
    SkGlyphRunListPainter fGlyphPainter;
    using INHERITED = GrSurfaceFillContext;
};

#endif
