/*
 * Copyright 2011 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/ganesh/Device.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkMesh.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkVertices.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrContextOptions.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SingleOwner.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTo.h"
#include "include/private/chromium/Slug.h"  // IWYU pragma: keep
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkTLazy.h"
#include "src/core/SkDevice.h"
#include "src/core/SkDrawBase.h"
#include "src/core/SkImageFilterTypes.h"  // IWYU pragma: keep
#include "src/core/SkImageInfoPriv.h"
#include "src/core/SkLatticeIter.h"
#include "src/core/SkMeshPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkSpecialImage.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkTraceEvent.h"
#include "src/core/SkVerticesPriv.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/TiledTextureUtils.h"
#include "src/gpu/ganesh/ClipStack.h"
#include "src/gpu/ganesh/GrAuditTrail.h"
#include "src/gpu/ganesh/GrBlurUtils.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColorInfo.h"
#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrFPArgs.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrFragmentProcessors.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
#include "src/gpu/ganesh/GrStyle.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/GrTracing.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/GrXferProcessor.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceContext.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/SurfaceFillContext.h"
#include "src/gpu/ganesh/effects/GrDisableColorXP.h"
#include "src/gpu/ganesh/effects/GrRRectEffect.h"
#include "src/gpu/ganesh/geometry/GrShape.h"
#include "src/gpu/ganesh/geometry/GrStyledShape.h"
#include "src/gpu/ganesh/image/GrImageUtils.h"
#include "src/gpu/ganesh/image/SkSpecialImage_Ganesh.h"
#include "src/text/GlyphRun.h"
#include "src/text/gpu/SlugImpl.h"
#include "src/text/gpu/SubRunContainer.h"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <tuple>
#include <utility>

class GrBackendSemaphore;
struct GrShaderCaps;
struct SkDrawShadowRec;

using namespace skia_private;

#define ASSERT_SINGLE_OWNER SKGPU_ASSERT_SINGLE_OWNER(fContext->priv().singleOwner())

#if defined(GPU_TEST_UTILS)
// GrContextOptions::fMaxTextureSizeOverride exists but doesn't allow for changing the
// maxTextureSize on the fly.
int gOverrideMaxTextureSizeGanesh = 0;
// Allows tests to check how many tiles were drawn on the most recent call to
// Device::drawAsTiledImageRect. This is an atomic because we can write to it from
// multiple threads during "normal" operations. However, the tests that actually
// read from it are done single-threaded.
std::atomic<int> gNumTilesDrawnGanesh{0};
#endif

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

namespace {

bool force_aa_clip(const skgpu::ganesh::SurfaceDrawContext* sdc) {
    return sdc->numSamples() > 1 || sdc->alwaysAntialias();
}

inline GrPrimitiveType point_mode_to_primitive_type(SkCanvas::PointMode mode) {
    switch (mode) {
        case SkCanvas::kPoints_PointMode:
            return GrPrimitiveType::kPoints;
        case SkCanvas::kLines_PointMode:
            return GrPrimitiveType::kLines;
        case SkCanvas::kPolygon_PointMode:
            return GrPrimitiveType::kLineStrip;
    }
    SK_ABORT("Unexpected mode");
}

std::unique_ptr<GrFragmentProcessor> make_inverse_rrect_fp(const SkMatrix& viewMatrix,
                                                           const SkRRect& rrect, GrAA aa,
                                                           const GrShaderCaps& shaderCaps) {
    SkTCopyOnFirstWrite<SkRRect> devRRect(rrect);
    if (viewMatrix.isIdentity() || rrect.transform(viewMatrix, devRRect.writable())) {
        auto edgeType = (aa == GrAA::kYes) ? GrClipEdgeType::kInverseFillAA
                                           : GrClipEdgeType::kInverseFillBW;
        auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, edgeType, *devRRect,
                                                 shaderCaps);
        return (success) ? std::move(fp) : nullptr;
    }
    return nullptr;
}

bool init_vertices_paint(GrRecordingContext* rContext,
                         const GrColorInfo& colorInfo,
                         const SkPaint& skPaint,
                         const SkMatrix& ctm,
                         SkBlender* blender,
                         bool hasColors,
                         const SkSurfaceProps& props,
                         GrPaint* grPaint) {
    if (hasColors) {
        return SkPaintToGrPaintWithBlend(rContext,
                                         colorInfo,
                                         skPaint,
                                         ctm,
                                         blender,
                                         props,
                                         grPaint);
    } else {
        return SkPaintToGrPaint(rContext, colorInfo, skPaint, ctm, props, grPaint);
    }
}

bool init_mesh_child_effects(GrRecordingContext* rContext,
                             const GrColorInfo& colorInfo,
                             const SkSurfaceProps& surfaceProps,
                             const SkMesh& mesh,
                             TArray<std::unique_ptr<GrFragmentProcessor>>* meshChildFPs) {
    // We use `Scope::kRuntimeEffect` here to ensure that mesh shaders get the same "raw" sampling
    // behavior from alpha-only image shaders as a Runtime Effect would, rather than the unexpected
    // tinting-by-input-color.
    GrFPArgs fpArgs(rContext, &colorInfo, surfaceProps, GrFPArgs::Scope::kRuntimeEffect);

    for (const SkRuntimeEffect::ChildPtr& child : mesh.children()) {
        auto [success, childFP] = GrFragmentProcessors::MakeChildFP(child, fpArgs);
        if (!success) {
            return false;
        }
        meshChildFPs->push_back(std::move(childFP));
    }
    return true;
}

} // anonymous namespace

namespace skgpu::ganesh {

sk_sp<Device> Device::Make(GrRecordingContext* rContext,
                           GrColorType colorType,
                           sk_sp<GrSurfaceProxy> proxy,
                           sk_sp<SkColorSpace> colorSpace,
                           GrSurfaceOrigin origin,
                           const SkSurfaceProps& surfaceProps,
                           InitContents init) {
    auto sdc = SurfaceDrawContext::Make(rContext,
                                        colorType,
                                        std::move(proxy),
                                        std::move(colorSpace),
                                        origin,
                                        surfaceProps);

    return Device::Make(std::move(sdc), kPremul_SkAlphaType, init);
}

SkImageInfo Device::MakeInfo(SurfaceContext* sc, DeviceFlags flags) {
    SkColorType colorType = GrColorTypeToSkColorType(sc->colorInfo().colorType());
    return SkImageInfo::Make(sc->width(), sc->height(), colorType,
                             flags & DeviceFlags::kIsOpaque ? kOpaque_SkAlphaType
                                                            : kPremul_SkAlphaType,
                             sc->colorInfo().refColorSpace());
}


/** Checks that the alpha type is legal and gets constructor flags. Returns false if device creation
    should fail. */
bool Device::CheckAlphaTypeAndGetFlags(SkAlphaType alphaType,
                                       InitContents init,
                                       DeviceFlags* flags) {
    *flags = DeviceFlags::kNone;
    switch (alphaType) {
        case kPremul_SkAlphaType:
            break;
        case kOpaque_SkAlphaType:
            *flags |= DeviceFlags::kIsOpaque;
            break;
        default: // If it is unpremul or unknown don't try to render
            return false;
    }
    if (InitContents::kClear == init) {
        *flags |= DeviceFlags::kNeedClear;
    }
    return true;
}

sk_sp<Device> Device::Make(std::unique_ptr<SurfaceDrawContext> sdc,
                           SkAlphaType alphaType,
                           InitContents init) {
    if (!sdc) {
        return nullptr;
    }

    GrRecordingContext* rContext = sdc->recordingContext();
    if (rContext->abandoned()) {
        return nullptr;
    }

    SkColorType ct = GrColorTypeToSkColorType(sdc->colorInfo().colorType());

    DeviceFlags flags;
    if (!rContext->colorTypeSupportedAsSurface(ct) ||
        !CheckAlphaTypeAndGetFlags(alphaType, init, &flags)) {
        return nullptr;
    }
    return sk_sp<Device>(new Device(std::move(sdc), flags));
}

sk_sp<Device> Device::Make(GrRecordingContext* rContext,
                           skgpu::Budgeted budgeted,
                           const SkImageInfo& ii,
                           SkBackingFit fit,
                           int sampleCount,
                           skgpu::Mipmapped mipmapped,
                           GrProtected isProtected,
                           GrSurfaceOrigin origin,
                           const SkSurfaceProps& props,
                           InitContents init) {
    if (!rContext) {
        return nullptr;
    }

    auto sdc = SurfaceDrawContext::Make(rContext,
                                        SkColorTypeToGrColorType(ii.colorType()),
                                        ii.refColorSpace(),
                                        fit,
                                        ii.dimensions(),
                                        props,
                                        /*label=*/"MakeDevice",
                                        sampleCount,
                                        mipmapped,
                                        isProtected,
                                        origin,
                                        budgeted);

    return Device::Make(std::move(sdc), ii.alphaType(), init);
}

Device::Device(std::unique_ptr<SurfaceDrawContext> sdc, DeviceFlags flags)
        : SkDevice(MakeInfo(sdc.get(), flags), sdc->surfaceProps())
        , fContext(sk_ref_sp(sdc->recordingContext()))
        , fSubRunControl(sdc->recordingContext()->priv().getSubRunControl(
                         sdc->surfaceProps().isUseDeviceIndependentFonts()))
        , fSurfaceDrawContext(std::move(sdc))
        , fClip(SkIRect::MakeSize(fSurfaceDrawContext->dimensions()),
                &this->localToDevice(),
                force_aa_clip(fSurfaceDrawContext.get())) {
    if (flags & DeviceFlags::kNeedClear) {
        this->clearAll();
    }
}

Device::~Device() = default;

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

bool Device::onReadPixels(const SkPixmap& pm, int x, int y) {
    ASSERT_SINGLE_OWNER

    // Context TODO: Elevate direct context requirement to public API
    auto dContext = fContext->asDirectContext();
    if (!dContext || !SkImageInfoValidConversion(pm.info(), this->imageInfo())) {
        return false;
    }

    return fSurfaceDrawContext->readPixels(dContext, pm, {x, y});
}

bool Device::onWritePixels(const SkPixmap& pm, int x, int y) {
    ASSERT_SINGLE_OWNER

    // Context TODO: Elevate direct context requirement to public API
    auto dContext = fContext->asDirectContext();
    if (!dContext || !SkImageInfoValidConversion(this->imageInfo(), pm.info())) {
        return false;
    }

    return fSurfaceDrawContext->writePixels(dContext, pm, {x, y});
}

bool Device::onAccessPixels(SkPixmap* pmap) {
    ASSERT_SINGLE_OWNER
    return false;
}

SurfaceDrawContext* Device::surfaceDrawContext() {
    ASSERT_SINGLE_OWNER
    return fSurfaceDrawContext.get();
}

const SurfaceDrawContext* Device::surfaceDrawContext() const {
    ASSERT_SINGLE_OWNER
    return fSurfaceDrawContext.get();
}

SurfaceFillContext* Device::surfaceFillContext() {
    ASSERT_SINGLE_OWNER
    return fSurfaceDrawContext.get();
}

void Device::clearAll() {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "clearAll", fContext.get());

    SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
    fSurfaceDrawContext->clearAtLeast(rect, SK_PMColor4fTRANSPARENT);
}

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

void Device::clipPath(const SkPath& path, SkClipOp op, bool aa) {
#if defined(GPU_TEST_UTILS)
    if (fContext->priv().options().fAllPathsVolatile && !path.isVolatile()) {
        this->clipPath(SkPath(path).setIsVolatile(true), op, aa);
        return;
    }
#endif
    SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
    fClip.clipPath(this->localToDevice(), path, GrAA(aa), op);
}

void Device::clipRegion(const SkRegion& globalRgn, SkClipOp op) {
    SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);

    // Regions don't actually need AA, but in DMSAA mode every clip element is antialiased.
    GrAA aa = GrAA(fSurfaceDrawContext->alwaysAntialias());

    if (globalRgn.isEmpty()) {
        fClip.clipRect(SkMatrix::I(), SkRect::MakeEmpty(), aa, op);
    } else if (globalRgn.isRect()) {
        fClip.clipRect(this->globalToDevice().asM33(), SkRect::Make(globalRgn.getBounds()), aa, op);
    } else {
        SkPath path;
        globalRgn.getBoundaryPath(&path);
        fClip.clipPath(this->globalToDevice().asM33(), path, aa, op);
    }
}

void Device::android_utils_clipAsRgn(SkRegion* region) const {
    SkIRect bounds = fClip.getConservativeBounds();
    // Assume wide open and then perform intersect/difference operations reducing the region
    region->setRect(bounds);
    const SkRegion deviceBounds(bounds);
    for (const ClipStack::Element& e : fClip) {
        SkRegion tmp;
        if (e.fShape.isRect() && e.fLocalToDevice.isIdentity()) {
            tmp.setRect(e.fShape.rect().roundOut());
        } else {
            SkPath tmpPath;
            e.fShape.asPath(&tmpPath);
            tmpPath.transform(e.fLocalToDevice);
            tmp.setPath(tmpPath, deviceBounds);
        }

        region->op(tmp, (SkRegion::Op) e.fOp);
    }
}

bool Device::isClipAntiAliased() const {
    for (const ClipStack::Element& e : fClip) {
        if (e.fAA == GrAA::kYes) {
            return true;
        }
        SkASSERT(!fSurfaceDrawContext->alwaysAntialias());
    }
    return false;
}

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

void Device::drawPaint(const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawPaint", fContext.get());

    GrPaint grPaint;
    if (!SkPaintToGrPaint(this->recordingContext(),
                          fSurfaceDrawContext->colorInfo(),
                          paint,
                          this->localToDevice(),
                          fSurfaceDrawContext->surfaceProps(),
                          &grPaint)) {
        return;
    }

    fSurfaceDrawContext->drawPaint(this->clip(), std::move(grPaint), this->localToDevice());
}

void Device::drawPoints(SkCanvas::PointMode mode,
                        size_t count,
                        const SkPoint pts[],
                        const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawPoints", fContext.get());
    SkScalar width = paint.getStrokeWidth();
    if (width < 0) {
        return;
    }

    GrAA aa = fSurfaceDrawContext->chooseAA(paint);

    if (count == 2 && mode == SkCanvas::kLines_PointMode) {
        if (paint.getPathEffect()) {
            // Probably a dashed line. Draw as a path.
            GrPaint grPaint;
            if (SkPaintToGrPaint(this->recordingContext(),
                                 fSurfaceDrawContext->colorInfo(),
                                 paint,
                                 this->localToDevice(),
                                 fSurfaceDrawContext->surfaceProps(),
                                 &grPaint)) {
                SkPath path;
                path.setIsVolatile(true);
                path.moveTo(pts[0]);
                path.lineTo(pts[1]);
                fSurfaceDrawContext->drawPath(this->clip(),
                                              std::move(grPaint),
                                              aa,
                                              this->localToDevice(),
                                              path,
                                              GrStyle(paint, SkPaint::kStroke_Style));
            }
            return;
        }
        if (!paint.getMaskFilter() &&
            paint.getStrokeWidth() > 0 &&  // drawStrokedLine doesn't support hairlines.
            paint.getStrokeCap() != SkPaint::kRound_Cap) { // drawStrokedLine doesn't do round caps.
            // Simple stroked line. Bypass path rendering.
            GrPaint grPaint;
            if (SkPaintToGrPaint(this->recordingContext(),
                                 fSurfaceDrawContext->colorInfo(),
                                 paint,
                                 this->localToDevice(),
                                 fSurfaceDrawContext->surfaceProps(),
                                 &grPaint)) {
                fSurfaceDrawContext->drawStrokedLine(this->clip(),
                                                     std::move(grPaint),
                                                     aa,
                                                     this->localToDevice(),
                                                     pts,
                                                     SkStrokeRec(paint, SkPaint::kStroke_Style));
            }
            return;
        }
    }

    const GrCaps* caps = fContext->priv().caps();
    SkScalar scales[2];
    bool isHairline =
            ((0 == width) ||
             (1 == width && this->localToDevice().getMinMaxScales(scales) &&
              SkScalarNearlyEqual(scales[0], 1.f) && SkScalarNearlyEqual(scales[1], 1.f))) &&

            // Don't do this as a hairline draw, which will emit line primitives, if
            // lines are not permitted by caps.
            !((mode == SkCanvas::kLines_PointMode || mode == SkCanvas::kPolygon_PointMode) &&
              caps->avoidLineDraws());

    // we only handle non-coverage-aa hairlines and paints without path effects or mask filters,
    // else we let the SkDraw call our drawPath()
    if (!isHairline ||
        paint.getPathEffect() ||
        paint.getMaskFilter() ||
        fSurfaceDrawContext->chooseAAType(aa) == GrAAType::kCoverage) {
        SkRasterClip rc(this->devClipBounds());
        SkDrawBase draw;
        // don't need to set fBlitterChoose, as it should never get used
        draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(this->width(), this->height()), nullptr, 0);
        draw.fCTM = &this->localToDevice();
        draw.fRC = &rc;
        draw.drawDevicePoints(mode, count, pts, paint, this);
        return;
    }

    GrPaint grPaint;
    if (!SkPaintToGrPaint(this->recordingContext(),
                          fSurfaceDrawContext->colorInfo(),
                          paint,
                          this->localToDevice(),
                          fSurfaceDrawContext->surfaceProps(),
                          &grPaint)) {
        return;
    }

    static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
    sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, SkToS32(count), pts, nullptr,
                                                      nullptr);

    GrPrimitiveType primitiveType = point_mode_to_primitive_type(mode);
    fSurfaceDrawContext->drawVertices(this->clip(), std::move(grPaint), this->localToDevice(),
                                      std::move(vertices), &primitiveType);
}

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

void Device::drawRect(const SkRect& rect, const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawRect", fContext.get());

    GrStyle style(paint);

    // A couple reasons we might need to call drawPath.
    if (paint.getMaskFilter() || paint.getPathEffect()) {
        GrStyledShape shape(rect, style);

        GrBlurUtils::DrawShapeWithMaskFilter(fContext.get(), fSurfaceDrawContext.get(),
                                             this->clip(), paint, this->localToDevice(), shape);
        return;
    }

    GrPaint grPaint;
    if (!SkPaintToGrPaint(this->recordingContext(),
                          fSurfaceDrawContext->colorInfo(),
                          paint,
                          this->localToDevice(),
                          fSurfaceDrawContext->surfaceProps(),
                          &grPaint)) {
        return;
    }

    fSurfaceDrawContext->drawRect(this->clip(), std::move(grPaint),
                                  fSurfaceDrawContext->chooseAA(paint), this->localToDevice(), rect,
                                  &style);
}

void Device::drawEdgeAAQuad(const SkRect& rect,
                            const SkPoint clip[4],
                            SkCanvas::QuadAAFlags aaFlags,
                            const SkColor4f& color,
                            SkBlendMode mode) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawEdgeAAQuad", fContext.get());

    SkPMColor4f dstColor = SkColor4fPrepForDst(color, fSurfaceDrawContext->colorInfo()).premul();

    GrPaint grPaint;
    grPaint.setColor4f(dstColor);
    if (mode != SkBlendMode::kSrcOver) {
        grPaint.setXPFactory(GrXPFactory::FromBlendMode(mode));
    }

    if (clip) {
        // Use fillQuadWithEdgeAA
        fSurfaceDrawContext->fillQuadWithEdgeAA(this->clip(),
                                                std::move(grPaint),
                                                SkToGrQuadAAFlags(aaFlags),
                                                this->localToDevice(),
                                                clip,
                                                nullptr);
    } else {
        // Use fillRectWithEdgeAA to preserve mathematical properties of dst being rectangular
        fSurfaceDrawContext->fillRectWithEdgeAA(this->clip(),
                                                std::move(grPaint),
                                                SkToGrQuadAAFlags(aaFlags),
                                                this->localToDevice(),
                                                rect);
    }
}

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

void Device::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawRRect", fContext.get());

    auto mf = paint.getMaskFilter();
    if (mf) {
        if (GrFragmentProcessors::IsSupported(mf)) {
            mf = nullptr; // already handled in SkPaintToGrPaint
        }
    }

    GrStyle style(paint);

    if (mf || style.pathEffect()) {
        // A path effect will presumably transform this rrect into something else.
        GrStyledShape shape(rrect, style);

        GrBlurUtils::DrawShapeWithMaskFilter(fContext.get(), fSurfaceDrawContext.get(),
                                             this->clip(), paint, this->localToDevice(), shape);
        return;
    }

    SkASSERT(!style.pathEffect());

    GrPaint grPaint;
    if (!SkPaintToGrPaint(this->recordingContext(),
                          fSurfaceDrawContext->colorInfo(),
                          paint,
                          this->localToDevice(),
                          fSurfaceDrawContext->surfaceProps(),
                          &grPaint)) {
        return;
    }

    fSurfaceDrawContext->drawRRect(this->clip(), std::move(grPaint),
                                   fSurfaceDrawContext->chooseAA(paint), this->localToDevice(),
                                   rrect, style);
}

void Device::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawDRRect", fContext.get());
    if (outer.isEmpty()) {
       return;
    }

    if (inner.isEmpty()) {
        return this->drawRRect(outer, paint);
    }

    SkStrokeRec stroke(paint);

    if (stroke.isFillStyle() && !paint.getMaskFilter() && !paint.getPathEffect()) {
        // For axis-aligned filled DRRects, just draw a regular rrect with inner clipped out using a
        // coverage FP instead of using path rendering.
        if (auto fp = make_inverse_rrect_fp(this->localToDevice(), inner,
                                            fSurfaceDrawContext->chooseAA(paint),
                                            *fSurfaceDrawContext->caps()->shaderCaps())) {
            GrPaint grPaint;
            if (!SkPaintToGrPaint(this->recordingContext(),
                                  fSurfaceDrawContext->colorInfo(),
                                  paint,
                                  this->localToDevice(),
                                  fSurfaceDrawContext->surfaceProps(),
                                  &grPaint)) {
                return;
            }
            SkASSERT(!grPaint.hasCoverageFragmentProcessor());
            grPaint.setCoverageFragmentProcessor(std::move(fp));
            fSurfaceDrawContext->drawRRect(this->clip(), std::move(grPaint),
                                           fSurfaceDrawContext->chooseAA(paint),
                                           this->localToDevice(), outer, GrStyle());
            return;
        }
    }

    SkPath path;
    path.setIsVolatile(true);
    path.addRRect(outer);
    path.addRRect(inner);
    path.setFillType(SkPathFillType::kEvenOdd);

    // TODO: We are losing the possible mutability of the path here but this should probably be
    // fixed by upgrading GrStyledShape to handle DRRects.
    GrStyledShape shape(path, paint);

    GrBlurUtils::DrawShapeWithMaskFilter(fContext.get(), fSurfaceDrawContext.get(), this->clip(),
                                         paint, this->localToDevice(), shape);
}

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

void Device::drawRegion(const SkRegion& region, const SkPaint& paint) {
    ASSERT_SINGLE_OWNER

    if (paint.getMaskFilter()) {
        SkPath path;
        region.getBoundaryPath(&path);
        path.setIsVolatile(true);
        return this->drawPath(path, paint, true);
    }

    GrPaint grPaint;
    if (!SkPaintToGrPaint(this->recordingContext(),
                          fSurfaceDrawContext->colorInfo(),
                          paint,
                          this->localToDevice(),
                          fSurfaceDrawContext->surfaceProps(),
                          &grPaint)) {
        return;
    }

    fSurfaceDrawContext->drawRegion(this->clip(), std::move(grPaint),
                                    fSurfaceDrawContext->chooseAA(paint), this->localToDevice(),
                                    region, GrStyle(paint));
}

void Device::drawOval(const SkRect& oval, const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawOval", fContext.get());

    if (paint.getMaskFilter()) {
        // The RRect path can handle special case blurring
        SkRRect rr = SkRRect::MakeOval(oval);
        return this->drawRRect(rr, paint);
    }

    GrPaint grPaint;
    if (!SkPaintToGrPaint(this->recordingContext(),
                          fSurfaceDrawContext->colorInfo(),
                          paint,
                          this->localToDevice(),
                          fSurfaceDrawContext->surfaceProps(),
                          &grPaint)) {
        return;
    }

    fSurfaceDrawContext->drawOval(this->clip(), std::move(grPaint),
                                  fSurfaceDrawContext->chooseAA(paint), this->localToDevice(), oval,
                                  GrStyle(paint));
}

void Device::drawArc(const SkArc& arc, const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawArc", fContext.get());
    if (paint.getMaskFilter()) {
        this->SkDevice::drawArc(arc, paint);
        return;
    }
    GrPaint grPaint;
    if (!SkPaintToGrPaint(this->recordingContext(),
                          fSurfaceDrawContext->colorInfo(),
                          paint,
                          this->localToDevice(),
                          fSurfaceDrawContext->surfaceProps(),
                          &grPaint)) {
        return;
    }

    fSurfaceDrawContext->drawArc(this->clip(),
                                 std::move(grPaint),
                                 fSurfaceDrawContext->chooseAA(paint),
                                 this->localToDevice(),
                                 arc,
                                 GrStyle(paint));
}

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

void Device::drawPath(const SkPath& origSrcPath, const SkPaint& paint, bool pathIsMutable) {
#if defined(GPU_TEST_UTILS)
    if (fContext->priv().options().fAllPathsVolatile && !origSrcPath.isVolatile()) {
        this->drawPath(SkPath(origSrcPath).setIsVolatile(true), paint, true);
        return;
    }
#endif
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawPath", fContext.get());
    if (!paint.getMaskFilter()) {
        GrPaint grPaint;
        if (!SkPaintToGrPaint(this->recordingContext(),
                              fSurfaceDrawContext->colorInfo(),
                              paint,
                              this->localToDevice(),
                              fSurfaceDrawContext->surfaceProps(),
                              &grPaint)) {
            return;
        }
        fSurfaceDrawContext->drawPath(this->clip(), std::move(grPaint),
                                      fSurfaceDrawContext->chooseAA(paint), this->localToDevice(),
                                      origSrcPath, GrStyle(paint));
        return;
    }

    // TODO: losing possible mutability of 'origSrcPath' here
    GrStyledShape shape(origSrcPath, paint);

    GrBlurUtils::DrawShapeWithMaskFilter(fContext.get(), fSurfaceDrawContext.get(), this->clip(),
                                         paint, this->localToDevice(), shape);
}

sk_sp<skif::Backend> Device::createImageFilteringBackend(const SkSurfaceProps& surfaceProps,
                                                         SkColorType colorType) const {
    return skif::MakeGaneshBackend(
            fContext, fSurfaceDrawContext->origin(), surfaceProps, colorType);
}

sk_sp<SkSpecialImage> Device::makeSpecial(const SkBitmap& bitmap) {
    ASSERT_SINGLE_OWNER

    // TODO: this makes a tight copy of 'bitmap' but it doesn't have to be (given SkSpecialImage's
    // semantics). Since this is cached we would have to bake the fit into the cache key though.
    auto view = std::get<0>(
            GrMakeCachedBitmapProxyView(fContext.get(), bitmap, /*label=*/"Device_MakeSpecial"));
    if (!view) {
        return nullptr;
    }

    const SkIRect rect = SkIRect::MakeSize(view.proxy()->dimensions());

    // GrMakeCachedBitmapProxyView creates a tight copy of 'bitmap' so we don't have to subset
    // the special image
    return SkSpecialImages::MakeDeferredFromGpu(fContext.get(),
                                                rect,
                                                bitmap.getGenerationID(),
                                                std::move(view),
                                                {SkColorTypeToGrColorType(bitmap.colorType()),
                                                 kPremul_SkAlphaType,
                                                 bitmap.refColorSpace()},
                                                this->surfaceProps());
}

sk_sp<SkSpecialImage> Device::makeSpecial(const SkImage* image) {
    ASSERT_SINGLE_OWNER

    SkPixmap pm;
    if (image->isTextureBacked()) {
        auto [view, ct] =
                skgpu::ganesh::AsView(this->recordingContext(), image, skgpu::Mipmapped::kNo);
        SkASSERT(view);

        return SkSpecialImages::MakeDeferredFromGpu(
                fContext.get(),
                SkIRect::MakeWH(image->width(), image->height()),
                image->uniqueID(),
                std::move(view),
                {ct, kPremul_SkAlphaType, image->refColorSpace()},
                this->surfaceProps());
    } else if (image->peekPixels(&pm)) {
        SkBitmap bm;

        bm.installPixels(pm);
        return this->makeSpecial(bm);
    } else {
        return nullptr;
    }
}

sk_sp<SkSpecialImage> Device::snapSpecial(const SkIRect& subset, bool forceCopy) {
    ASSERT_SINGLE_OWNER

    auto sdc = fSurfaceDrawContext.get();

    // If we are wrapping a vulkan secondary command buffer, then we can't snap off a special image
    // since it would require us to make a copy of the underlying VkImage which we don't have access
    // to. Additionaly we can't stop and start the render pass that is used with the secondary
    // command buffer.
    if (sdc->wrapsVkSecondaryCB()) {
        return nullptr;
    }

    SkASSERT(sdc->asSurfaceProxy());

    SkIRect finalSubset = subset;
    GrSurfaceProxyView view = sdc->readSurfaceView();
    if (forceCopy || !view.asTextureProxy()) {
        // When the device doesn't have a texture, or a copy is requested, we create a temporary
        // texture that matches the device contents
        view = GrSurfaceProxyView::Copy(fContext.get(),
                                        std::move(view),
                                        skgpu::Mipmapped::kNo,  // Don't auto generate mips
                                        subset,
                                        SkBackingFit::kApprox,
                                        skgpu::Budgeted::kYes,
                                        /*label=*/"Device_SnapSpecial");  // Always budgeted
        if (!view) {
            return nullptr;
        }
        // Since this copied only the requested subset, the special image wrapping the proxy no
        // longer needs the original subset.
        finalSubset = SkIRect::MakeSize(view.dimensions());
    }

    return SkSpecialImages::MakeDeferredFromGpu(fContext.get(),
                                                finalSubset,
                                                kNeedNewImageUniqueID_SpecialImage,
                                                std::move(view),
                                                GrColorInfo(this->imageInfo().colorInfo()),
                                                this->surfaceProps());
}

sk_sp<SkSpecialImage> Device::snapSpecialScaled(const SkIRect& subset, const SkISize& dstDims) {
     ASSERT_SINGLE_OWNER

    auto sdc = fSurfaceDrawContext.get();

    // If we are wrapping a vulkan secondary command buffer, then we can't snap off a special image
    // since it would require us to make a copy of the underlying VkImage which we don't have access
    // to. Additionaly we can't stop and start the render pass that is used with the secondary
    // command buffer.
    if (sdc->wrapsVkSecondaryCB()) {
        return nullptr;
    }

    SkASSERT(sdc->asSurfaceProxy());

    auto scaledContext = sdc->rescale(sdc->imageInfo().makeDimensions(dstDims),
                                      sdc->origin(),
                                      subset,
                                      RescaleGamma::kSrc,
                                      RescaleMode::kLinear);
    if (!scaledContext) {
        return nullptr;
    }

    return SkSpecialImages::MakeDeferredFromGpu(fContext.get(),
                                                SkIRect::MakeSize(dstDims),
                                                kNeedNewImageUniqueID_SpecialImage,
                                                scaledContext->readSurfaceView(),
                                                GrColorInfo(this->imageInfo().colorInfo()),
                                                this->surfaceProps());
}

void Device::drawDevice(SkDevice* device,
                        const SkSamplingOptions& sampling,
                        const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    // clear of the source device must occur before CHECK_SHOULD_DRAW
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawDevice", fContext.get());
    this->SkDevice::drawDevice(device, sampling, paint);
}

void Device::drawImageRect(const SkImage* image,
                           const SkRect* src,
                           const SkRect& dst,
                           const SkSamplingOptions& sampling,
                           const SkPaint& paint,
                           SkCanvas::SrcRectConstraint constraint) {
    ASSERT_SINGLE_OWNER

    GrAA aa = fSurfaceDrawContext->chooseAA(paint);
    SkCanvas::QuadAAFlags aaFlags = (aa == GrAA::kYes) ? SkCanvas::kAll_QuadAAFlags
                                                       : SkCanvas::kNone_QuadAAFlags;

    this->drawImageQuadDirect(image,
                              src ? *src
                                  : SkRect::MakeIWH(image->width(), image->height()),
                              dst,
                              /* dstClip= */ nullptr,
                              aaFlags,
                              /* preViewMatrix= */ nullptr,
                              sampling,
                              paint,
                              constraint);
}

bool Device::drawAsTiledImageRect(SkCanvas* canvas,
                                  const SkImage* image,
                                  const SkRect* src,
                                  const SkRect& dst,
                                  const SkSamplingOptions& sampling,
                                  const SkPaint& paint,
                                  SkCanvas::SrcRectConstraint constraint) {
    GrRecordingContext* rCtx = canvas->recordingContext();
    if (!rCtx) {
        return false;
    }
    ASSERT_SINGLE_OWNER

    GrAA aa = fSurfaceDrawContext->chooseAA(paint);
    SkCanvas::QuadAAFlags aaFlags = (aa == GrAA::kYes) ? SkCanvas::kAll_QuadAAFlags
                                                       : SkCanvas::kNone_QuadAAFlags;

    // NOTE: if the context is not a direct context, it doesn't have access to the resource
    // cache, and theoretically, the resource cache's limits could be being changed on
    // another thread, so even having access to just the limit wouldn't be a reliable
    // test during recording here.
    size_t cacheSize = 0;
    if (auto dCtx = GrAsDirectContext(rCtx)) {
        cacheSize = dCtx->getResourceCacheLimit();
    }
    size_t maxTextureSize = rCtx->maxTextureSize();
#if defined(GPU_TEST_UTILS)
    if (gOverrideMaxTextureSizeGanesh) {
        maxTextureSize = gOverrideMaxTextureSizeGanesh;
    }
    gNumTilesDrawnGanesh.store(0, std::memory_order_relaxed);
#endif

    [[maybe_unused]] auto [wasTiled, numTiles] = TiledTextureUtils::DrawAsTiledImageRect(
            canvas,
            image,
            src ? *src : SkRect::MakeIWH(image->width(), image->height()),
            dst,
            aaFlags,
            sampling,
            &paint,
            constraint,
            rCtx->priv().options().fSharpenMipmappedTextures,
            cacheSize,
            maxTextureSize);
#if defined(GPU_TEST_UTILS)
    gNumTilesDrawnGanesh.store(numTiles, std::memory_order_relaxed);
#endif
    return wasTiled;
}

void Device::drawViewLattice(GrSurfaceProxyView view,
                             const GrColorInfo& info,
                             std::unique_ptr<SkLatticeIter> iter,
                             const SkRect& dst,
                             SkFilterMode filter,
                             const SkPaint& origPaint) {
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawViewLattice", fContext.get());
    SkASSERT(view);

    SkTCopyOnFirstWrite<SkPaint> paint(&origPaint);

    if (!info.isAlphaOnly() && (paint->getColor() & 0x00FFFFFF) != 0x00FFFFFF) {
        paint.writable()->setColor(SkColorSetARGB(origPaint.getAlpha(), 0xFF, 0xFF, 0xFF));
    }
    GrPaint grPaint;
    // Passing null as shaderFP indicates that the GP will provide the shader.
    if (!SkPaintToGrPaintReplaceShader(this->recordingContext(),
                                       fSurfaceDrawContext->colorInfo(),
                                       *paint,
                                       this->localToDevice(),
                                       /*shaderFP=*/nullptr,
                                       fSurfaceDrawContext->surfaceProps(),
                                       &grPaint)) {
        return;
    }

    if (info.isAlphaOnly()) {
        // If we were doing this with an FP graph we'd use a kDstIn blend between the texture
        // and the paint color.
        view.concatSwizzle(skgpu::Swizzle("aaaa"));
    }
    auto csxf = GrColorSpaceXform::Make(info, fSurfaceDrawContext->colorInfo());

    fSurfaceDrawContext->drawImageLattice(this->clip(),
                                          std::move(grPaint),
                                          this->localToDevice(),
                                          std::move(view),
                                          info.alphaType(),
                                          std::move(csxf),
                                          filter,
                                          std::move(iter),
                                          dst);
}

void Device::drawImageLattice(const SkImage* image,
                              const SkCanvas::Lattice& lattice,
                              const SkRect& dst,
                              SkFilterMode filter,
                              const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    auto iter = std::make_unique<SkLatticeIter>(lattice, dst);

    auto [view, ct] = skgpu::ganesh::AsView(this->recordingContext(), image, skgpu::Mipmapped::kNo);
    if (view) {
        GrColorInfo colorInfo(ct, image->alphaType(), image->refColorSpace());
        this->drawViewLattice(
                std::move(view), std::move(colorInfo), std::move(iter), dst, filter, paint);
    }
}

void Device::drawVertices(const SkVertices* vertices,
                          sk_sp<SkBlender> blender,
                          const SkPaint& paint,
                          bool skipColorXform) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawVertices", fContext.get());
    SkASSERT(vertices);

#ifdef SK_LEGACY_IGNORE_DRAW_VERTICES_BLEND_WITH_NO_SHADER
    if (!paint.getShader()) {
        blender = SkBlender::Mode(SkBlendMode::kDst);
    }
#endif

    SkVerticesPriv info(vertices->priv());

    GrPaint grPaint;
    if (!init_vertices_paint(fContext.get(),
                             fSurfaceDrawContext->colorInfo(),
                             paint,
                             this->localToDevice(),
                             blender.get(),
                             info.hasColors(),
                             fSurfaceDrawContext->surfaceProps(),
                             &grPaint)) {
        return;
    }
    fSurfaceDrawContext->drawVertices(this->clip(),
                                      std::move(grPaint),
                                      this->localToDevice(),
                                      sk_ref_sp(const_cast<SkVertices*>(vertices)),
                                      nullptr,
                                      skipColorXform);
}

void Device::drawMesh(const SkMesh& mesh, sk_sp<SkBlender> blender, const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawMesh", fContext.get());
    if (!mesh.isValid()) {
        return;
    }

    GrPaint grPaint;
    if (!init_vertices_paint(fContext.get(),
                             fSurfaceDrawContext->colorInfo(),
                             paint,
                             this->localToDevice(),
                             blender.get(),
                             SkMeshSpecificationPriv::HasColors(*mesh.spec()),
                             fSurfaceDrawContext->surfaceProps(),
                             &grPaint)) {
        return;
    }

    TArray<std::unique_ptr<GrFragmentProcessor>> meshChildFPs;
    if (!init_mesh_child_effects(fContext.get(),
                                 fSurfaceDrawContext->colorInfo(),
                                 fSurfaceDrawContext->surfaceProps(),
                                 mesh,
                                 &meshChildFPs)) {
        return;
    }
    fSurfaceDrawContext->drawMesh(this->clip(), std::move(grPaint), this->localToDevice(), mesh,
                                  std::move(meshChildFPs));
}

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

#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
void Device::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
#if defined(GPU_TEST_UTILS)
    if (fContext->priv().options().fAllPathsVolatile && !path.isVolatile()) {
        this->drawShadow(SkPath(path).setIsVolatile(true), rec);
        return;
    }
#endif
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawShadow", fContext.get());

    if (!fSurfaceDrawContext->drawFastShadow(this->clip(), this->localToDevice(), path, rec)) {
        // failed to find an accelerated case
        this->SkDevice::drawShadow(path, rec);
    }
}
#endif  // SK_ENABLE_OPTIMIZE_SIZE

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

void Device::drawAtlas(const SkRSXform xform[],
                       const SkRect texRect[],
                       const SkColor colors[],
                       int count,
                       sk_sp<SkBlender> blender,
                       const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawAtlas", fContext.get());

    GrPaint grPaint;
    if (colors) {
        if (!SkPaintToGrPaintWithBlend(this->recordingContext(),
                                       fSurfaceDrawContext->colorInfo(),
                                       paint,
                                       this->localToDevice(),
                                       blender.get(),
                                       fSurfaceDrawContext->surfaceProps(),
                                       &grPaint)) {
            return;
        }
    } else {
        if (!SkPaintToGrPaint(this->recordingContext(),
                              fSurfaceDrawContext->colorInfo(),
                              paint,
                              this->localToDevice(),
                              fSurfaceDrawContext->surfaceProps(),
                              &grPaint)) {
            return;
        }
    }

    fSurfaceDrawContext->drawAtlas(this->clip(), std::move(grPaint), this->localToDevice(), count,
                                   xform, texRect, colors);
}

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

void Device::onDrawGlyphRunList(SkCanvas* canvas,
                                const sktext::GlyphRunList& glyphRunList,
                                const SkPaint& paint) {
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawGlyphRunList", fContext.get());
    SkASSERT(!glyphRunList.hasRSXForm());

    if (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.). Use a Slug to draw the glyphs.
        auto slug = this->convertGlyphRunListToSlug(glyphRunList, paint);
        if (slug != nullptr) {
            this->drawSlug(canvas, slug.get(), paint);
        }
    } else {
        fSurfaceDrawContext->drawGlyphRunList(canvas,
                                              this->clip(),
                                              this->localToDevice(),
                                              glyphRunList,
                                              this->strikeDeviceInfo(),
                                              paint);
    }
}

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

void Device::drawDrawable(SkCanvas* canvas, SkDrawable* drawable, const SkMatrix* matrix) {
    ASSERT_SINGLE_OWNER

    GrBackendApi api = this->recordingContext()->backend();
    if (GrBackendApi::kVulkan == api) {
        const SkMatrix& ctm = this->localToDevice();
        const SkMatrix& combinedMatrix = matrix ? SkMatrix::Concat(ctm, *matrix) : ctm;
        std::unique_ptr<SkDrawable::GpuDrawHandler> gpuDraw =
                drawable->snapGpuDrawHandler(api, combinedMatrix, this->devClipBounds(),
                                             this->imageInfo());
        if (gpuDraw) {
            fSurfaceDrawContext->drawDrawable(
                    std::move(gpuDraw), combinedMatrix.mapRect(drawable->getBounds()));
            return;
        }
    }
    this->SkDevice::drawDrawable(canvas, drawable, matrix);
}


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

GrSurfaceProxyView Device::readSurfaceView() {
    return this->surfaceFillContext()->readSurfaceView();
}

GrRenderTargetProxy* Device::targetProxy() {
    return this->readSurfaceView().asRenderTargetProxy();
}

bool Device::wait(int numSemaphores,
                  const GrBackendSemaphore* waitSemaphores,
                  bool deleteSemaphoresAfterWait) {
    ASSERT_SINGLE_OWNER

    return fSurfaceDrawContext->waitOnSemaphores(numSemaphores, waitSemaphores,
                                                 deleteSemaphoresAfterWait);
}

void Device::discard() {
    fSurfaceDrawContext->discard();
}

void Device::resolveMSAA() {
    fSurfaceDrawContext->resolveMSAA();
}

bool Device::replaceBackingProxy(SkSurface::ContentChangeMode mode,
                                 sk_sp<GrRenderTargetProxy> newRTP,
                                 GrColorType grColorType,
                                 sk_sp<SkColorSpace> colorSpace,
                                 GrSurfaceOrigin origin,
                                 const SkSurfaceProps& props) {
    auto sdc = SurfaceDrawContext::Make(fContext.get(), grColorType, std::move(newRTP),
                                        std::move(colorSpace), origin, props);
    if (!sdc) {
        return false;
    }

    SkASSERT(sdc->dimensions() == fSurfaceDrawContext->dimensions());
    SkASSERT(sdc->numSamples() == fSurfaceDrawContext->numSamples());
    SkASSERT(sdc->asSurfaceProxy()->priv().isExact());
    if (mode == SkSurface::kRetain_ContentChangeMode) {
        if (fContext->abandoned()) {
            return false;
        }

        SkASSERT(fSurfaceDrawContext->asTextureProxy());
        SkAssertResult(sdc->blitTexture(fSurfaceDrawContext->readSurfaceView(),
                                        SkIRect::MakeWH(this->width(), this->height()),
                                        SkIPoint::Make(0, 0)));
    }

    fSurfaceDrawContext = std::move(sdc);
    return true;
}

bool Device::replaceBackingProxy(SkSurface::ContentChangeMode mode) {
    ASSERT_SINGLE_OWNER

    const SkImageInfo& ii = this->imageInfo();
    GrRenderTargetProxy* oldRTP = this->targetProxy();
    GrSurfaceProxyView oldView = this->readSurfaceView();

    auto grColorType = SkColorTypeToGrColorType(ii.colorType());
    auto format = fContext->priv().caps()->getDefaultBackendFormat(grColorType, GrRenderable::kYes);
    if (!format.isValid()) {
        return false;
    }

    GrProxyProvider* proxyProvider = fContext->priv().proxyProvider();
    // This entry point is used by SkSurface_Ganesh::onCopyOnWrite so it must create a
    // kExact-backed render target proxy
    sk_sp<GrTextureProxy> proxy =
            proxyProvider->createProxy(format,
                                       ii.dimensions(),
                                       GrRenderable::kYes,
                                       oldRTP->numSamples(),
                                       oldView.mipmapped(),
                                       SkBackingFit::kExact,
                                       oldRTP->isBudgeted(),
                                       oldRTP->isProtected(),
                                       /*label=*/"BaseDevice_ReplaceBackingProxy");
    if (!proxy) {
        return false;
    }

    return this->replaceBackingProxy(mode, sk_ref_sp(proxy->asRenderTargetProxy()),
                                     grColorType, ii.refColorSpace(), oldView.origin(),
                                     this->surfaceProps());
}

void Device::asyncRescaleAndReadPixels(const SkImageInfo& info,
                                       const SkIRect& srcRect,
                                       RescaleGamma rescaleGamma,
                                       RescaleMode rescaleMode,
                                       ReadPixelsCallback callback,
                                       ReadPixelsContext context) {
    auto* sdc = fSurfaceDrawContext.get();
    // Context TODO: Elevate direct context requirement to public API.
    auto dContext = sdc->recordingContext()->asDirectContext();
    if (!dContext) {
        return;
    }
    sdc->asyncRescaleAndReadPixels(dContext, info, srcRect, rescaleGamma, rescaleMode, callback,
                                   context);
}

void Device::asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
                                             bool readAlpha,
                                             sk_sp<SkColorSpace> dstColorSpace,
                                             const SkIRect& srcRect,
                                             SkISize dstSize,
                                             RescaleGamma rescaleGamma,
                                             RescaleMode rescaleMode,
                                             ReadPixelsCallback callback,
                                             ReadPixelsContext context) {
    auto* sdc = fSurfaceDrawContext.get();
    // Context TODO: Elevate direct context requirement to public API.
    auto dContext = sdc->recordingContext()->asDirectContext();
    if (!dContext) {
        return;
    }
    sdc->asyncRescaleAndReadPixelsYUV420(dContext,
                                         yuvColorSpace,
                                         readAlpha,
                                         std::move(dstColorSpace),
                                         srcRect,
                                         dstSize,
                                         rescaleGamma,
                                         rescaleMode,
                                         callback,
                                         context);
}

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

sk_sp<SkDevice> Device::createDevice(const CreateInfo& cinfo, const SkPaint*) {
    ASSERT_SINGLE_OWNER

    SkSurfaceProps props =
        this->surfaceProps().cloneWithPixelGeometry(cinfo.fPixelGeometry);

    SkASSERT(cinfo.fInfo.colorType() != kRGBA_1010102_SkColorType);

    auto sdc = SurfaceDrawContext::MakeWithFallback(
            fContext.get(),
            SkColorTypeToGrColorType(cinfo.fInfo.colorType()),
            cinfo.fInfo.refColorSpace(),
            SkBackingFit::kApprox,
            cinfo.fInfo.dimensions(),
            props,
            fSurfaceDrawContext->numSamples(),
            skgpu::Mipmapped::kNo,
            fSurfaceDrawContext->asSurfaceProxy()->isProtected(),
            fSurfaceDrawContext->origin(),
            skgpu::Budgeted::kYes);
    if (!sdc) {
        return nullptr;
    }

    // Skia's convention is to only clear a device if it is non-opaque.
    InitContents init = cinfo.fInfo.isOpaque() ? InitContents::kUninit : InitContents::kClear;

    return Device::Make(std::move(sdc), cinfo.fInfo.alphaType(), init);
}

sk_sp<SkSurface> Device::makeSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
    ASSERT_SINGLE_OWNER
    // TODO: Change the signature of newSurface to take a budgeted parameter.
    static const skgpu::Budgeted kBudgeted = skgpu::Budgeted::kNo;
    bool isProtected = this->targetProxy()->isProtected() == GrProtected::kYes;
    return SkSurfaces::RenderTarget(fContext.get(),
                                    kBudgeted,
                                    info,
                                    fSurfaceDrawContext->numSamples(),
                                    fSurfaceDrawContext->origin(),
                                    &props,
                                    /* shouldCreateWithMips= */ false,
                                    isProtected);
}

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

bool Device::android_utils_clipWithStencil() {
    SkRegion clipRegion;
    this->android_utils_clipAsRgn(&clipRegion);
    if (clipRegion.isEmpty()) {
        return false;
    }
    auto sdc = fSurfaceDrawContext.get();
    SkASSERT(sdc);
    GrPaint grPaint;
    grPaint.setXPFactory(GrDisableColorXPFactory::Get());
    static constexpr GrUserStencilSettings kDrawToStencil(
        GrUserStencilSettings::StaticInit<
            0x1,
            GrUserStencilTest::kAlways,
            0x1,
            GrUserStencilOp::kReplace,
            GrUserStencilOp::kReplace,
            0x1>()
    );
    // Regions don't actually need AA, but in DMSAA mode everything is antialiased.
    GrAA aa = GrAA(fSurfaceDrawContext->alwaysAntialias());
    sdc->drawRegion(nullptr, std::move(grPaint), aa, SkMatrix::I(), clipRegion,
                    GrStyle::SimpleFill(), &kDrawToStencil);
    return true;
}

SkStrikeDeviceInfo Device::strikeDeviceInfo() const {
    return {this->surfaceProps(), this->scalerContextFlags(), &fSubRunControl};
}

sk_sp<sktext::gpu::Slug> Device::convertGlyphRunListToSlug(const sktext::GlyphRunList& glyphRunList,
                                                           const SkPaint& paint) {
    return sktext::gpu::SlugImpl::Make(this->localToDevice(),
                                       glyphRunList,
                                       paint,
                                       this->strikeDeviceInfo(),
                                       SkStrikeCache::GlobalStrikeCache());
}

#if defined(SK_DEBUG)
static bool valid_slug_matrices(const SkMatrix& creationMatrix, const SkMatrix& positionMatrix) {
    // A Slug can be drawn with:
    //   The exact same matrix that was used for creation
    // - OR -
    //   A non-perspective matrix that has the same 2x2 and a relative integer translation
    //
    // For the second case, calculate the translation in source space to a translation in
    // device space by mapping (0, 0) through both the creationMatrix and the positionMatrix;
    // take the difference.
    if (creationMatrix == positionMatrix) {
        return true;
    }

    SkVector translation = positionMatrix.mapOrigin() - creationMatrix.mapOrigin();
    return creationMatrix.getScaleX() == positionMatrix.getScaleX() &&
           creationMatrix.getScaleY() == positionMatrix.getScaleY() &&
           creationMatrix.getSkewX() == positionMatrix.getSkewX() &&
           creationMatrix.getSkewY() == positionMatrix.getSkewY() &&
           !positionMatrix.hasPerspective() && !creationMatrix.hasPerspective() &&
           SkScalarIsInt(translation.x()) && SkScalarIsInt(translation.y());
}
#endif


void Device::drawSlug(SkCanvas* canvas, const sktext::gpu::Slug* slug, const SkPaint& paint) {
    SkASSERT(canvas);
    SkASSERT(slug);
    const sktext::gpu::SlugImpl* slugImpl = static_cast<const sktext::gpu::SlugImpl*>(slug);
#if defined(SK_DEBUG)
    if (!fContext->priv().options().fSupportBilerpFromGlyphAtlas) {
        // We can draw a slug if the atlas has padding or if the creation matrix and the
        // drawing matrix are the same (up to integer translation).
        // If they are the same, then the Slug will use the direct drawing code and not use bi-lerp.
        SkMatrix slugMatrix = slugImpl->initialPositionMatrix();
        SkMatrix positionMatrix = this->localToDevice();
        positionMatrix.preTranslate(slugImpl->origin().x(), slugImpl->origin().y());
        SkASSERT(valid_slug_matrices(slugMatrix, positionMatrix));
    }
#endif
    auto atlasDelegate = [&](const sktext::gpu::AtlasSubRun* subRun,
                             SkPoint drawOrigin,
                             const SkPaint& paint,
                             sk_sp<SkRefCnt> subRunStorage,
                             sktext::gpu::RendererData) {
        auto[drawingClip, op] = subRun->makeAtlasTextOp(
                this->clip(), this->localToDevice(), drawOrigin, paint,
                std::move(subRunStorage), fSurfaceDrawContext.get());
        if (op != nullptr) {
            fSurfaceDrawContext->addDrawOp(drawingClip, std::move(op));
        }
    };

    slugImpl->subRuns()->draw(canvas, slugImpl->origin(), paint, slugImpl, atlasDelegate);
}

}  // namespace skgpu::ganesh
