/*
 * 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/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/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/SkColorData.h"
#include "src/core/SkDevice.h"
#include "src/core/SkDraw.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/GrShaderCaps.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/gpu/ganesh/ops/AtlasTextOp.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 <optional>
#include <utility>

class GrBackendSemaphore;
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) {
    if (auto rr = rrect.transform(viewMatrix)) {
        auto edgeType = (aa == GrAA::kYes) ? GrClipEdgeType::kInverseFillAA
                                           : GrClipEdgeType::kInverseFillBW;
        auto [success, fp] = GrRRectEffect::Make(/*inputFP=*/nullptr, edgeType, *rr, shaderCaps);
        return (success) ? std::move(fp) : nullptr;
    }
    return nullptr;
}

bool init_vertices_paint(skgpu::ganesh::SurfaceDrawContext* sdc,
                         const SkPaint& skPaint,
                         const SkMatrix& ctm,
                         SkBlender* blender,
                         bool hasColors,
                         GrPaint* grPaint) {
    if (hasColors) {
        return SkPaintToGrPaintWithBlend(sdc, skPaint, ctm, blender, grPaint);
    } else {
        return SkPaintToGrPaint(sdc, skPaint, ctm, grPaint);
    }
}

bool init_mesh_child_effects(skgpu::ganesh::SurfaceDrawContext* sdc,
                             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(sdc, &sdc->colorInfo(), sdc->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();
        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().makeTransform(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(fSurfaceDrawContext.get(),
                          paint,
                          this->localToDevice(),
                          &grPaint)) {
        return;
    }

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

void Device::drawPoints(SkCanvas::PointMode mode, SkSpan<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;
    }

    const size_t count = pts.size();

    // If there is an image filter or mask filter these bounds were already checked in
    // the canvas.
    if (!paint.getImageFilter() && !paint.getMaskFilter()) {
        auto bounds = SkRect::Bounds(pts);
        if (!bounds || paint.nothingToDraw()) {
            return;
        }

        SkRect devBounds = SkMatrixPriv::MapRect(this->localToDevice44(), bounds.value());
        if (!devBounds.isFinite()) {
            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(fSurfaceDrawContext.get(),
                                 paint,
                                 this->localToDevice(),
                                 &grPaint)) {
                SkPath path = SkPath::Line(pts[0], pts[1]);
                path.setIsVolatile(true);
                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(fSurfaceDrawContext.get(),
                                 paint,
                                 this->localToDevice(),
                                 &grPaint)) {
                fSurfaceDrawContext->drawStrokedLine(this->clip(),
                                                     std::move(grPaint),
                                                     aa,
                                                     this->localToDevice(),
                                                     pts.data(),
                                                     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());
        skcpu::Draw 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, pts, paint, this);
        return;
    }

    GrPaint grPaint;
    if (!SkPaintToGrPaint(fSurfaceDrawContext.get(), paint, this->localToDevice(), &grPaint)) {
        return;
    }

    static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
    sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, SkToS32(count), pts.data(),
                                                      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(fSurfaceDrawContext.get(), paint, this->localToDevice(), &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(fSurfaceDrawContext.get(),
                          paint,
                          this->localToDevice(),
                          &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(fSurfaceDrawContext.get(),
                                  paint,
                                  this->localToDevice(),
                                  &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;
        }
    }

    auto path = SkPathBuilder(SkPathFillType::kEvenOdd)
                .addRRect(outer)
                .addRRect(inner)
                .detach();
    path.setIsVolatile(true);

    // 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.setIsVolatile(true);
        return this->drawPath(path, paint);
    }

    GrPaint grPaint;
    if (!SkPaintToGrPaint(fSurfaceDrawContext.get(),
                          paint,
                          this->localToDevice(),
                          &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(fSurfaceDrawContext.get(), paint, this->localToDevice(), &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(fSurfaceDrawContext.get(), paint, this->localToDevice(), &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) {
#if defined(GPU_TEST_UTILS)
    if (fContext->priv().options().fAllPathsVolatile && !origSrcPath.isVolatile()) {
        this->drawPath(SkPath(origSrcPath).setIsVolatile(true), paint);
        return;
    }
#endif
    ASSERT_SINGLE_OWNER
    GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::ganesh::Device", "drawPath", fContext.get());
    if (!paint.getMaskFilter()) {
        GrPaint grPaint;
        if (!SkPaintToGrPaint(fSurfaceDrawContext.get(),
                              paint,
                              this->localToDevice(),
                              &grPaint)) {
            return;
        }
        fSurfaceDrawContext->drawPath(this->clip(), std::move(grPaint),
                                      fSurfaceDrawContext->chooseAA(paint), this->localToDevice(),
                                      origSrcPath, GrStyle(paint));
        return;
    }

    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::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,
            !rCtx->priv().caps()->shaderCaps()->fHasLowFragmentPrecision);
#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(fSurfaceDrawContext.get(),
                                       *paint,
                                       this->localToDevice(),
                                       /*shaderFP=*/nullptr,
                                       &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,
                                            this->targetProxy());
    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(fSurfaceDrawContext.get(),
                             paint,
                             this->localToDevice(),
                             blender.get(),
                             info.hasColors(),
                             &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(fSurfaceDrawContext.get(),
                             paint,
                             this->localToDevice(),
                             blender.get(),
                             SkMeshSpecificationPriv::HasColors(*mesh.spec()),
                             &grPaint)) {
        return;
    }

    TArray<std::unique_ptr<GrFragmentProcessor>> meshChildFPs;
    if (!init_mesh_child_effects(fSurfaceDrawContext.get(), 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(SkCanvas* canvas, const SkPath& path, const SkDrawShadowRec& rec) {
#if defined(GPU_TEST_UTILS)
    if (fContext->priv().options().fAllPathsVolatile && !path.isVolatile()) {
        this->drawShadow(canvas, 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(canvas, path, rec);
    }
}
#endif  // SK_ENABLE_OPTIMIZE_SIZE

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

void Device::drawAtlas(SkSpan<const SkRSXform> xform,
                       SkSpan<const SkRect> texRect,
                       SkSpan<const SkColor> colors,
                       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.empty()) {
        if (!SkPaintToGrPaintWithBlend(fSurfaceDrawContext.get(),
                                       paint,
                                       this->localToDevice(),
                                       blender.get(),
                                       &grPaint)) {
            return;
        }
    } else {
        if (!SkPaintToGrPaint(fSurfaceDrawContext.get(),
                              paint,
                              this->localToDevice(),
                              &grPaint)) {
            return;
        }
    }

    fSurfaceDrawContext->drawAtlas(this->clip(), std::move(grPaint), this->localToDevice(),
                                   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] = AtlasTextOp::Make(
                fSurfaceDrawContext.get(), subRun,
                this->clip(), this->localToDevice(), drawOrigin, paint,
                std::move(subRunStorage));
        if (op != nullptr) {
            fSurfaceDrawContext->addDrawOp(drawingClip, std::move(op));
        }
    };

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

}  // namespace skgpu::ganesh
