/*
 * 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 GrRenderTargetContext_DEFINED
#define GrRenderTargetContext_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/gpu/GrOpsTask.h"
#include "src/gpu/GrPaint.h"
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/GrSurfaceContext.h"
#include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/text/GrTextTarget.h"

class GrBackendSemaphore;
class GrClip;
class GrColorSpaceXform;
class GrCoverageCountingPathRenderer;
class GrDrawOp;
class GrFixedClip;
class GrOp;
class GrRenderTarget;
class GrRenderTargetContextPriv;
class GrShape;
class GrStyle;
class GrTextureProxy;
struct GrUserStencilSettings;
struct SkDrawShadowRec;
class SkGlyphRunList;
struct SkIPoint;
struct SkIRect;
class SkLatticeIter;
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 GrRenderTargetContext : public GrSurfaceContext {
public:
    static std::unique_ptr<GrRenderTargetContext> Make(
            GrRecordingContext*, GrColorType, sk_sp<SkColorSpace>, sk_sp<GrSurfaceProxy>,
            GrSurfaceOrigin, const SkSurfaceProps*, bool managedOps = true);

    static std::unique_ptr<GrRenderTargetContext> Make(GrRecordingContext*,
                                                       GrColorType,
                                                       sk_sp<SkColorSpace>,
                                                       SkBackingFit,
                                                       SkISize dimensions,
                                                       const GrBackendFormat&,
                                                       int sampleCnt,
                                                       GrMipMapped,
                                                       GrProtected,
                                                       GrSurfaceOrigin,
                                                       SkBudgeted,
                                                       const SkSurfaceProps*);

    // Same as above but will use the default GrBackendFormat for the given GrColorType
    static std::unique_ptr<GrRenderTargetContext> 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);

    // 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<GrRenderTargetContext> 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 GrRenderTargetContext that wraps the passed in GrBackendTexture.
    static std::unique_ptr<GrRenderTargetContext> MakeFromBackendTexture(
            GrRecordingContext*, GrColorType, sk_sp<SkColorSpace>, const GrBackendTexture&,
            int sampleCnt, GrSurfaceOrigin, const SkSurfaceProps*, ReleaseProc releaseProc,
            ReleaseContext releaseCtx);

    static std::unique_ptr<GrRenderTargetContext> MakeFromBackendTextureAsRenderTarget(
            GrRecordingContext*, GrColorType, sk_sp<SkColorSpace>, const GrBackendTexture&,
            int sampleCnt, GrSurfaceOrigin, const SkSurfaceProps*);

    static std::unique_ptr<GrRenderTargetContext> MakeFromBackendRenderTarget(
            GrRecordingContext*, GrColorType, sk_sp<SkColorSpace>, const GrBackendRenderTarget&,
            GrSurfaceOrigin, const SkSurfaceProps*, ReleaseProc releaseProc,
            ReleaseContext releaseCtx);

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

    GrRenderTargetContext(GrRecordingContext*, GrSurfaceProxyView readView,
                          GrSurfaceProxyView outputView, GrColorType, sk_sp<SkColorSpace>,
                          const SkSurfaceProps*, bool managedOpsTask = true);

    ~GrRenderTargetContext() override;

    virtual void drawGlyphRunList(const GrClip&, const SkMatrix& viewMatrix, const SkGlyphRunList&);

    /**
     * Provides a perfomance hint that the render target's contents are allowed
     * to become undefined.
     */
    void discard();

    enum class CanClearFullscreen : bool {
        kNo = false,
        kYes = true
    };

    /**
     * Clear the entire or rect of the render target, ignoring any clips.
     * @param rect  the rect to clear or the whole thing if rect is NULL.
     * @param color the color to clear to.
     * @param CanClearFullscreen allows partial clears to be converted to fullscreen clears on
     *                           tiling platforms where that is an optimization.
     */
    void clear(const SkIRect* rect, const SkPMColor4f& color, CanClearFullscreen);

    void clear(const SkPMColor4f& color) {
        return this->clear(nullptr, color, CanClearFullscreen::kYes);
    }

    /**
     *  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, 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* domain = 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, color, mode, aa, &quad, domain);
    }

    /**
     * Variant of drawTexture that instead draws the texture applied to 'dstQuad' transformed by
     * 'viewMatrix', using the 'srcQuad' texture coordinates clamped to the optional 'domain'. If
     * 'domain' is null, it's equivalent to using the fast src rect constraint. If 'domain' is
     * provided, the strict src rect constraint is applied using 'domain'.
     */
    void drawTextureQuad(const GrClip& clip, GrSurfaceProxyView view, GrColorType srcColorType,
                         SkAlphaType srcAlphaType, GrSamplerState::Filter filter, SkBlendMode mode,
                         const SkPMColor4f& color, const SkPoint srcQuad[4],
                         const SkPoint dstQuad[4], GrAA aa, GrQuadAAFlags edgeAA,
                         const SkRect* domain, 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, color, mode, aa, &quad, domain);
    }

    /** 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
        float fAlpha;
        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, 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,
                   const GrShape&);


    /**
     * 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 SkMatrix& viewMatrix,
                      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);

    /**
     * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
     * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
     * respectively.
     */
    bool blitTexture(GrSurfaceProxyView view, const SkIRect& srcRect, const SkIPoint& dstPoint);

    /**
     * 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);

    using ReadPixelsCallback = SkSurface::ReadPixelsCallback;
    using ReadPixelsContext = SkSurface::ReadPixelsContext;
    using RescaleGamma = SkSurface::RescaleGamma;

    // GPU implementation for SkSurface::asyncRescaleAndReadPixels.
    void asyncRescaleAndReadPixels(const SkImageInfo& info, const SkIRect& srcRect,
                                   RescaleGamma rescaleGamma, SkFilterQuality rescaleQuality,
                                   ReadPixelsCallback callback, ReadPixelsContext context);
    // GPU implementation for SkSurface::asyncRescaleAndReadPixelsYUV420.
    void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
                                         sk_sp<SkColorSpace> dstColorSpace,
                                         const SkIRect& srcRect,
                                         SkISize dstSize,
                                         RescaleGamma rescaleGamma,
                                         SkFilterQuality rescaleQuality,
                                         ReadPixelsCallback callback,
                                         ReadPixelsContext context);

    /**
     * After this returns any pending surface IO will be issued to the backend 3D API and
     * if the surface has MSAA it will be resolved.
     */
    GrSemaphoresSubmitted flush(SkSurface::BackendSurfaceAccess access, const GrFlushInfo&);

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

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

    // TODO: See if it makes sense for this to return a const& instead and require the callers to
    // make a copy (which refs the proxy) if needed.
    GrSurfaceProxyView outputSurfaceView() { return fOutputView; }

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

    GrRenderTargetContext* asRenderTargetContext() override { return this; }

    // Provides access to functions that aren't part of the public API.
    GrRenderTargetContextPriv priv();
    const GrRenderTargetContextPriv priv() const;

    GrTextTarget* textTarget() { return fTextTarget.get(); }

#if GR_TEST_UTILS
    bool testingOnly_IsInstantiated() const { return this->asSurfaceProxy()->isInstantiated(); }
    void testingOnly_SetPreserveOpsOnFullClear() { fPreserveOpsOnFullClear_TestingOnly = true; }
    GrOpsTask* testingOnly_PeekLastOpsTask() { return fOpsTask.get(); }
#endif

private:
    class TextTarget;
    enum class QuadOptimization;

    GrAAType chooseAAType(GrAA);

    friend class GrAtlasTextBlob;               // for access to add[Mesh]DrawOp
    friend class GrClipStackClip;               // for access to getOpsTask
    friend class GrOnFlushResourceProvider;     // for access to getOpsTask (http://skbug.com/9357)

    friend class GrRenderTargetContextPriv;

    // All the path renderers currently make their own ops
    friend class GrSoftwarePathRenderer;             // for access to add[Mesh]DrawOp
    friend class GrAAConvexPathRenderer;             // for access to add[Mesh]DrawOp
    friend class GrDashLinePathRenderer;             // for access to add[Mesh]DrawOp
    friend class GrAAHairLinePathRenderer;           // for access to add[Mesh]DrawOp
    friend class GrAALinearizingConvexPathRenderer;  // for access to add[Mesh]DrawOp
    friend class GrSmallPathRenderer;                // for access to add[Mesh]DrawOp
    friend class GrDefaultPathRenderer;              // for access to add[Mesh]DrawOp
    friend class GrStencilAndCoverPathRenderer;      // for access to add[Mesh]DrawOp
    friend class GrTriangulatingPathRenderer;        // for access to add[Mesh]DrawOp
    friend class GrCCPerFlushResources;              // for access to addDrawOp
    friend class GrCoverageCountingPathRenderer;     // for access to addDrawOp
    friend class GrFillRectOp;                       // for access to addDrawOp
    friend class GrGpuTessellationPathRenderer;      // for access to addDrawOp
    friend class GrTextureOp;                        // for access to addDrawOp

    SkDEBUGCODE(void onValidate() const override;)


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

    void internalClear(const GrFixedClip&, const SkPMColor4f&, CanClearFullscreen);
    void internalStencilClear(const GrFixedClip&, 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,
                          const SkPMColor4f& color,
                          SkBlendMode blendMode,
                          GrAA aa,
                          DrawQuad* quad,
                          const SkRect* domain = nullptr);

    void drawShapeUsingPathRenderer(const GrClip&, GrPaint&&, GrAA, const SkMatrix&,
                                    const GrShape&);

    void addOp(std::unique_ptr<GrOp>);

    // 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).
    void addDrawOp(const GrClip&, std::unique_ptr<GrDrawOp>,
                   const std::function<WillAddOpFn>& = std::function<WillAddOpFn>());

    // 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.
    bool SK_WARN_UNUSED_RESULT setupDstProxyView(const GrClip&, const GrOp& op,
                                                 GrXferProcessor::DstProxyView* result);

    class AsyncReadResult;

    // The async read step of asyncRescaleAndReadPixels()
    void asyncReadPixels(const SkIRect& rect, SkColorType colorType, ReadPixelsCallback callback,
                         ReadPixelsContext context);

    GrOpsTask* getOpsTask();

    std::unique_ptr<GrTextTarget> fTextTarget;

    GrSurfaceProxyView fOutputView;

    // In MDB-mode the GrOpsTask can be closed by some other renderTargetContext that has picked
    // it up. For this reason, the GrOpsTask should only ever be accessed via 'getOpsTask'.
    sk_sp<GrOpsTask> fOpsTask;

    SkSurfaceProps fSurfaceProps;
    bool fManagedOpsTask;

    int fNumStencilSamples = 0;
#if GR_TEST_UTILS
    bool fPreserveOpsOnFullClear_TestingOnly = false;
#endif

    typedef GrSurfaceContext INHERITED;
};

#endif
