/*
 * Copyright 2018 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "src/gpu/ganesh/ops/FillRectOp.h"

#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/private/SkAssert.h"
#include "include/private/SkDebug.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkColorData.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrOpsTypes.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"
#include "src/gpu/ganesh/geometry/GrQuadBuffer.h"
#include "src/gpu/ganesh/geometry/GrQuadUtils.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelperWithStencil.h"
#include "src/gpu/ganesh/ops/QuadPerEdgeAA.h"

#if defined(GPU_TEST_UTILS)
#include "src/core/SkRandom.h"
#include "src/gpu/ganesh/GrDrawOpTest.h"
#include "src/gpu/ganesh/GrTestUtils.h"
#endif

#include <algorithm>
#include <cstring>
#include <memory>
#include <utility>

class GrCaps;
class GrDstProxyView;
class GrSurfaceProxyView;
enum class GrXferBarrierFlags;

namespace {

using VertexSpec = skgpu::ganesh::QuadPerEdgeAA::VertexSpec;
using ColorType = skgpu::ganesh::QuadPerEdgeAA::ColorType;
using Subset = skgpu::ganesh::QuadPerEdgeAA::Subset;

#if defined(GPU_TEST_UTILS)
SkString dump_quad_info(int index, const GrQuad* deviceQuad,
                        const GrQuad* localQuad, const SkPMColor4f& color,
                        GrQuadAAFlags aaFlags) {
    GrQuad safeLocal = localQuad ? *localQuad : GrQuad();
    SkString str;
    str.appendf("%d: Color: [%.2f, %.2f, %.2f, %.2f], Edge AA: l%u_t%u_r%u_b%u, \n"
                "  device quad: [(%.2f, %2.f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), "
                "(%.2f, %.2f, %.2f)],\n"
                "  local quad: [(%.2f, %2.f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), "
                "(%.2f, %.2f, %.2f)]\n",
                index, color.fR, color.fG, color.fB, color.fA,
                (uint32_t) (aaFlags & GrQuadAAFlags::kLeft),
                (uint32_t) (aaFlags & GrQuadAAFlags::kTop),
                (uint32_t) (aaFlags & GrQuadAAFlags::kRight),
                (uint32_t) (aaFlags & GrQuadAAFlags::kBottom),
                deviceQuad->x(0), deviceQuad->y(0), deviceQuad->w(0),
                deviceQuad->x(1), deviceQuad->y(1), deviceQuad->w(1),
                deviceQuad->x(2), deviceQuad->y(2), deviceQuad->w(2),
                deviceQuad->x(3), deviceQuad->y(3), deviceQuad->w(3),
                safeLocal.x(0), safeLocal.y(0), safeLocal.w(0),
                safeLocal.x(1), safeLocal.y(1), safeLocal.w(1),
                safeLocal.x(2), safeLocal.y(2), safeLocal.w(2),
                safeLocal.x(3), safeLocal.y(3), safeLocal.w(3));
    return str;
}
#endif

class FillRectOpImpl final : public GrMeshDrawOp {
private:
    using Helper = GrSimpleMeshDrawOpHelperWithStencil;

public:
    static GrOp::Owner Make(GrRecordingContext* context,
                            GrPaint&& paint,
                            GrAAType aaType,
                            DrawQuad* quad,
                            const GrUserStencilSettings* stencilSettings,
                            Helper::InputFlags inputFlags) {
        // Clean up deviations between aaType and edgeAA
        GrQuadUtils::ResolveAAType(aaType, quad->fEdgeFlags, quad->fDevice,
                                   &aaType, &quad->fEdgeFlags);
        return Helper::FactoryHelper<FillRectOpImpl>(context, std::move(paint), aaType, quad,
                                                     stencilSettings, inputFlags);
    }

    // aaType is passed to Helper in the initializer list, so incongruities between aaType and
    // edgeFlags must be resolved prior to calling this constructor.
    FillRectOpImpl(GrProcessorSet* processorSet, SkPMColor4f paintColor, GrAAType aaType,
                   DrawQuad* quad, const GrUserStencilSettings* stencil,
                   Helper::InputFlags inputFlags)
            : INHERITED(ClassID())
            , fHelper(processorSet, aaType, stencil, inputFlags)
            , fQuads(1, !fHelper.isTrivial()) {
        // Set bounds before clipping so we don't have to worry about unioning the bounds of
        // the two potential quads (GrQuad::bounds() is perspective-safe).
        bool hairline = GrQuadUtils::WillUseHairline(quad->fDevice, aaType, quad->fEdgeFlags);
        this->setBounds(quad->fDevice.bounds(), HasAABloat(aaType == GrAAType::kCoverage),
                        hairline ? IsHairline::kYes : IsHairline::kNo);
        DrawQuad extra;
        // Always crop to W>0 to remain consistent with GrQuad::bounds()
        int count = GrQuadUtils::ClipToW0(quad, &extra);
        if (count == 0) {
            // We can't discard the op at this point, but disable AA flags so it won't go through
            // inset/outset processing
            quad->fEdgeFlags = GrQuadAAFlags::kNone;
            count = 1;
        }

        // Conservatively keep track of the local coordinates; it may be that the paint doesn't
        // need them after analysis is finished. If the paint is known to be solid up front they
        // can be skipped entirely.
        fQuads.append(quad->fDevice, {paintColor, quad->fEdgeFlags},
                      fHelper.isTrivial() ? nullptr : &quad->fLocal);
        if (count > 1) {
            fQuads.append(extra.fDevice, { paintColor, extra.fEdgeFlags },
                          fHelper.isTrivial() ? nullptr : &extra.fLocal);
        }
    }

    const char* name() const override { return "FillRectOp"; }

    void visitProxies(const GrVisitProxyFunc& func) const override {
        if (fProgramInfo) {
            fProgramInfo->visitFPProxies(func);
        } else {
            return fHelper.visitProxies(func);
        }
    }

    GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip,
                                      GrClampType clampType) override {
        // Initialize aggregate color analysis with the first quad's color (which always exists)
        auto iter = fQuads.metadata();
        SkAssertResult(iter.next());
        GrProcessorAnalysisColor quadColors(iter->fColor);
        // Then combine the colors of any additional quads (e.g. from MakeSet)
        while(iter.next()) {
            quadColors = GrProcessorAnalysisColor::Combine(quadColors, iter->fColor);
            if (quadColors.isUnknown()) {
                // No point in accumulating additional starting colors, combining cannot make it
                // less unknown.
                break;
            }
        }

        // If the AA type is coverage, it will be a single value per pixel; if it's not coverage AA
        // then the coverage is always 1.0, so specify kNone for more optimal blending.
        auto coverage = fHelper.aaType() == GrAAType::kCoverage
                                                    ? GrProcessorAnalysisCoverage::kSingleChannel
                                                    : GrProcessorAnalysisCoverage::kNone;
        auto result = fHelper.finalizeProcessors(caps, clip, clampType, coverage, &quadColors);
        // If there is a constant color after analysis, that means all of the quads should be set
        // to the same color (even if they started out with different colors).
        iter = fQuads.metadata();
        SkPMColor4f colorOverride;
        if (quadColors.isConstant(&colorOverride)) {
            fColorType = skgpu::ganesh::QuadPerEdgeAA::MinColorType(colorOverride);
            while(iter.next()) {
                iter->fColor = colorOverride;
            }
        } else {
            // Otherwise compute the color type needed as the max over all quads.
            fColorType = ColorType::kNone;
            while(iter.next()) {
                fColorType = std::max(fColorType,
                                      skgpu::ganesh::QuadPerEdgeAA::MinColorType(iter->fColor));
            }
        }
        // Most SkShaders' FPs multiply their calculated color by the paint color or alpha. We want
        // to use ColorType::kNone to optimize out that multiply. However, if there are no color
        // FPs then were really writing a special shader for white rectangles and not saving any
        // multiples. So in that case use bytes to avoid the extra shader (and possibly work around
        // an ANGLE issue: crbug.com/942565).
        if (fColorType == ColorType::kNone && !result.hasColorFragmentProcessor()) {
            fColorType = ColorType::kByte;
        }

        return result;
    }

    FixedFunctionFlags fixedFunctionFlags() const override {
        // Since the AA type of the whole primitive is kept consistent with the per edge AA flags
        // the helper's fixed function flags are appropriate.
        return fHelper.fixedFunctionFlags();
    }

    DEFINE_OP_CLASS_ID

private:
    friend class skgpu::ganesh::FillRectOp;  // for access to addQuad

#if defined(GPU_TEST_UTILS)
    int numQuads() const final { return fQuads.count(); }
#endif

    VertexSpec vertexSpec() const {
        auto indexBufferOption = skgpu::ganesh::QuadPerEdgeAA::CalcIndexBufferOption(
                fHelper.aaType(), fQuads.count());

        return VertexSpec(fQuads.deviceQuadType(), fColorType, fQuads.localQuadType(),
                          fHelper.usesLocalCoords(), Subset::kNo, fHelper.aaType(),
                          fHelper.compatibleWithCoverageAsAlpha(), indexBufferOption);
    }

    GrProgramInfo* programInfo() override {
        return fProgramInfo;
    }

    void onCreateProgramInfo(const GrCaps* caps,
                             SkArenaAlloc* arena,
                             const GrSurfaceProxyView& writeView,
                             bool usesMSAASurface,
                             GrAppliedClip&& appliedClip,
                             const GrDstProxyView& dstProxyView,
                             GrXferBarrierFlags renderPassXferBarriers,
                             GrLoadOp colorLoadOp) override {
        const VertexSpec vertexSpec = this->vertexSpec();

        GrGeometryProcessor* gp = skgpu::ganesh::QuadPerEdgeAA::MakeProcessor(arena, vertexSpec);
        SkASSERT(gp->vertexStride() == vertexSpec.vertexSize());

        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView, usesMSAASurface,
                                                            std::move(appliedClip),
                                                            dstProxyView, gp,
                                                            vertexSpec.primitiveType(),
                                                            renderPassXferBarriers, colorLoadOp);
    }

    void onPrePrepareDraws(GrRecordingContext* rContext,
                           const GrSurfaceProxyView& writeView,
                           GrAppliedClip* clip,
                           const GrDstProxyView& dstProxyView,
                           GrXferBarrierFlags renderPassXferBarriers,
                           GrLoadOp colorLoadOp) override {
        TRACE_EVENT0("skia.gpu", TRACE_FUNC);

        SkASSERT(!fPrePreparedVertices);

        INHERITED::onPrePrepareDraws(rContext, writeView, clip, dstProxyView,
                                     renderPassXferBarriers, colorLoadOp);

        SkArenaAlloc* arena = rContext->priv().recordTimeAllocator();

        const VertexSpec vertexSpec = this->vertexSpec();

        const int totalNumVertices = fQuads.count() * vertexSpec.verticesPerQuad();
        const size_t totalVertexSizeInBytes = vertexSpec.vertexSize() * totalNumVertices;

        fPrePreparedVertices = arena->makeArrayDefault<char>(totalVertexSizeInBytes);

        this->tessellate(vertexSpec, fPrePreparedVertices);
    }

    void tessellate(const VertexSpec& vertexSpec, char* dst) const {
        static constexpr SkRect kEmptyDomain = SkRect::MakeEmpty();

        skgpu::ganesh::QuadPerEdgeAA::Tessellator tessellator(vertexSpec, dst);
        auto iter = fQuads.iterator();
        while (iter.next()) {
            // All entries should have local coords, or no entries should have local coords,
            // matching !helper.isTrivial() (which is more conservative than helper.usesLocalCoords)
            SkASSERT(iter.isLocalValid() != fHelper.isTrivial());
            auto info = iter.metadata();
            tessellator.append(iter.deviceQuad(), iter.localQuad(),
                               info.fColor, kEmptyDomain, info.fAAFlags);
        }
    }

    void onPrepareDraws(GrMeshDrawTarget* target) override {
        TRACE_EVENT0("skia.gpu", TRACE_FUNC);

        const VertexSpec vertexSpec = this->vertexSpec();

        // Make sure that if the op thought it was a solid color, the vertex spec does not use
        // local coords.
        SkASSERT(!fHelper.isTrivial() || !fHelper.usesLocalCoords());

        const int totalNumVertices = fQuads.count() * vertexSpec.verticesPerQuad();

        // Fill the allocated vertex data
        void* vdata = target->makeVertexSpace(vertexSpec.vertexSize(), totalNumVertices,
                                              &fVertexBuffer, &fBaseVertex);
        if (!vdata) {
            SkDebugf("Could not allocate vertices\n");
            return;
        }

        if (fPrePreparedVertices) {
            const size_t totalVertexSizeInBytes = vertexSpec.vertexSize() * totalNumVertices;

            memcpy(vdata, fPrePreparedVertices, totalVertexSizeInBytes);
        } else {
            this->tessellate(vertexSpec, (char*) vdata);
        }

        if (vertexSpec.needsIndexBuffer()) {
            fIndexBuffer = skgpu::ganesh::QuadPerEdgeAA::GetIndexBuffer(
                    target, vertexSpec.indexBufferOption());
            if (!fIndexBuffer) {
                SkDebugf("Could not allocate indices\n");
                return;
            }
        }
    }

    void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
        if (!fVertexBuffer) {
            return;
        }

        const VertexSpec vertexSpec = this->vertexSpec();

        if (vertexSpec.needsIndexBuffer() && !fIndexBuffer) {
            return;
        }

        if (!fProgramInfo) {
            this->createProgramInfo(flushState);
        }

        const int totalNumVertices = fQuads.count() * vertexSpec.verticesPerQuad();

        flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
        flushState->bindBuffers(std::move(fIndexBuffer), nullptr, std::move(fVertexBuffer));
        flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline());
        skgpu::ganesh::QuadPerEdgeAA::IssueDraw(flushState->caps(),
                                                flushState->opsRenderPass(),
                                                vertexSpec,
                                                0,
                                                fQuads.count(),
                                                totalNumVertices,
                                                fBaseVertex);
    }

    CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override {
        TRACE_EVENT0("skia.gpu", TRACE_FUNC);
        auto that = t->cast<FillRectOpImpl>();

        bool upgradeToCoverageAAOnMerge = false;
        if (fHelper.aaType() != that->fHelper.aaType()) {
            if (!CanUpgradeAAOnMerge(fHelper.aaType(), that->fHelper.aaType())) {
                return CombineResult::kCannotCombine;
            }
            upgradeToCoverageAAOnMerge = true;
        }

        if (CombinedQuadCountWillOverflow(fHelper.aaType(), upgradeToCoverageAAOnMerge,
                                          fQuads.count() + that->fQuads.count())) {
            return CombineResult::kCannotCombine;
        }

        // Unlike most users of the draw op helper, this op can merge none-aa and coverage-aa draw
        // ops together, so pass true as the last argument.
        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds(), true)) {
            return CombineResult::kCannotCombine;
        }

        // If the paints were compatible, the trivial/solid-color state should be the same
        SkASSERT(fHelper.isTrivial() == that->fHelper.isTrivial());

        // If the processor sets are compatible, the two ops are always compatible; it just needs to
        // adjust the state of the op to be the more general quad and aa types of the two ops and
        // then concatenate the per-quad data.
        fColorType = std::max(fColorType, that->fColorType);

        // The helper stores the aa type, but isCompatible(with true arg) allows the two ops' aa
        // types to be none and coverage, in which case this op's aa type must be lifted to coverage
        // so that quads with no aa edges can be batched with quads that have some/all edges aa'ed.
        if (upgradeToCoverageAAOnMerge) {
            fHelper.setAAType(GrAAType::kCoverage);
        }

        fQuads.concat(that->fQuads);
        return CombineResult::kMerged;
    }

#if defined(GPU_TEST_UTILS)
    SkString onDumpInfo() const override {
        SkString str = SkStringPrintf("# draws: %d\n", fQuads.count());
        str.appendf("Device quad type: %u, local quad type: %u\n",
                    (uint32_t) fQuads.deviceQuadType(), (uint32_t) fQuads.localQuadType());
        str += fHelper.dumpInfo();
        int i = 0;
        auto iter = fQuads.iterator();
        while(iter.next()) {
            const ColorAndAA& info = iter.metadata();
            str += dump_quad_info(i, iter.deviceQuad(), iter.localQuad(),
                                  info.fColor, info.fAAFlags);
            i++;
        }
        return str;
    }
#endif

    bool canAddQuads(int numQuads, GrAAType aaType) {
        // The new quad's aa type should be the same as the first quad's or none, except when the
        // first quad's aa type was already downgraded to none, in which case the stored type must
        // be lifted to back to the requested type.
        int quadCount = fQuads.count() + numQuads;
        if (aaType != fHelper.aaType() && aaType != GrAAType::kNone) {
            auto indexBufferOption =
                    skgpu::ganesh::QuadPerEdgeAA::CalcIndexBufferOption(aaType, quadCount);
            if (quadCount > skgpu::ganesh::QuadPerEdgeAA::QuadLimit(indexBufferOption)) {
                // Promoting to the new aaType would've caused an overflow of the indexBuffer
                // limit
                return false;
            }

            // Original quad was downgraded to non-aa, lift back up to this quad's required type
            SkASSERT(fHelper.aaType() == GrAAType::kNone);
            fHelper.setAAType(aaType);
        } else {
            auto indexBufferOption = skgpu::ganesh::QuadPerEdgeAA::CalcIndexBufferOption(
                    fHelper.aaType(), quadCount);
            if (quadCount > skgpu::ganesh::QuadPerEdgeAA::QuadLimit(indexBufferOption)) {
                return false; // This op can't grow any more
            }
        }

        return true;
    }

    // Similar to onCombineIfPossible, but adds a quad assuming its op would have been compatible.
    // But since it's avoiding the op list management, it must update the op's bounds.
    bool addQuad(DrawQuad* quad, const SkPMColor4f& color, GrAAType aaType) {
        SkRect newBounds = this->bounds();
        newBounds.joinPossiblyEmptyRect(quad->fDevice.bounds());

        DrawQuad extra;
        int count = quad->fEdgeFlags != GrQuadAAFlags::kNone ? GrQuadUtils::ClipToW0(quad, &extra)
                                                             : 1;
        if (count == 0 ) {
            // Just skip the append (trivial success)
            return true;
        } else if (!this->canAddQuads(count, aaType)) {
            // Not enough room in the index buffer for the AA type
            return false;
        } else {
            // Can actually add the 1 or 2 quads representing the draw
            fQuads.append(quad->fDevice, { color, quad->fEdgeFlags },
                          fHelper.isTrivial() ? nullptr : &quad->fLocal);
            if (count > 1) {
                fQuads.append(extra.fDevice, { color, extra.fEdgeFlags },
                              fHelper.isTrivial() ? nullptr : &extra.fLocal);
            }
            // Update the bounds
            this->setBounds(newBounds, HasAABloat(fHelper.aaType() == GrAAType::kCoverage),
                            IsHairline::kNo);
            return true;
        }
    }

    struct ColorAndAA {
        SkPMColor4f fColor;
        GrQuadAAFlags fAAFlags;
    };

    Helper fHelper;
    GrQuadBuffer<ColorAndAA> fQuads;
    char* fPrePreparedVertices = nullptr;

    GrProgramInfo* fProgramInfo = nullptr;
    ColorType      fColorType;

    sk_sp<const GrBuffer> fVertexBuffer;
    sk_sp<const GrBuffer> fIndexBuffer;
    int fBaseVertex;

    using INHERITED = GrMeshDrawOp;
};

} // anonymous namespace

namespace skgpu::ganesh {

GrOp::Owner FillRectOp::Make(GrRecordingContext* context,
                             GrPaint&& paint,
                             GrAAType aaType,
                             DrawQuad* quad,
                             const GrUserStencilSettings* stencil,
                             InputFlags inputFlags) {
    return FillRectOpImpl::Make(context, std::move(paint), aaType, std::move(quad), stencil,
                                inputFlags);
}

GrOp::Owner FillRectOp::MakeNonAARect(GrRecordingContext* context,
                                      GrPaint&& paint,
                                      const SkMatrix& view,
                                      const SkRect& rect,
                                      const GrUserStencilSettings* stencil) {
    DrawQuad quad{GrQuad::MakeFromRect(rect, view), GrQuad(rect), GrQuadAAFlags::kNone};
    return FillRectOpImpl::Make(context, std::move(paint), GrAAType::kNone, &quad, stencil,
                                InputFlags::kNone);
}

GrOp::Owner FillRectOp::MakeOp(GrRecordingContext* context,
                               GrPaint&& paint,
                               GrAAType aaType,
                               const SkMatrix& viewMatrix,
                               const GrQuadSetEntry quads[],
                               int cnt,
                               const GrUserStencilSettings* stencilSettings,
                               int* numConsumed) {
    // First make a draw op for the first quad in the set
    SkASSERT(cnt > 0);

    DrawQuad quad{GrQuad::MakeFromRect(quads[0].fRect, viewMatrix),
                  GrQuad::MakeFromRect(quads[0].fRect, quads[0].fLocalMatrix),
                  quads[0].fAAFlags};
    paint.setColor4f(quads[0].fColor);
    GrOp::Owner op = FillRectOp::Make(context, std::move(paint), aaType,
                                      &quad, stencilSettings, InputFlags::kNone);
    auto fillRects = op->cast<FillRectOpImpl>();

    *numConsumed = 1;
    // Accumulate remaining quads similar to onCombineIfPossible() without creating an op
    for (int i = 1; i < cnt; ++i) {
        quad = {GrQuad::MakeFromRect(quads[i].fRect, viewMatrix),
                GrQuad::MakeFromRect(quads[i].fRect, quads[i].fLocalMatrix),
                quads[i].fAAFlags};

        GrAAType resolvedAA;
        GrQuadUtils::ResolveAAType(aaType, quads[i].fAAFlags, quad.fDevice,
                                   &resolvedAA, &quad.fEdgeFlags);

        if (!fillRects->addQuad(&quad, quads[i].fColor, resolvedAA)) {
            break;
        }

        (*numConsumed)++;
    }

    return op;
}

void FillRectOp::AddFillRectOps(skgpu::ganesh::SurfaceDrawContext* sdc,
                                const GrClip* clip,
                                GrRecordingContext* context,
                                GrPaint&& paint,
                                GrAAType aaType,
                                const SkMatrix& viewMatrix,
                                const GrQuadSetEntry quads[],
                                int cnt,
                                const GrUserStencilSettings* stencilSettings) {
    int offset = 0;
    int numLeft = cnt;
    while (numLeft) {
        int numConsumed = 0;

        GrOp::Owner op = MakeOp(context, GrPaint::Clone(paint), aaType, viewMatrix,
                                &quads[offset], numLeft, stencilSettings,
                                &numConsumed);

        offset += numConsumed;
        numLeft -= numConsumed;

        sdc->addDrawOp(clip, std::move(op));
    }

    SkASSERT(offset == cnt);
}

}  // namespace skgpu::ganesh

#if defined(GPU_TEST_UTILS)

uint32_t skgpu::ganesh::FillRectOp::ClassID() { return FillRectOpImpl::ClassID(); }

GR_DRAW_OP_TEST_DEFINE(FillRectOp) {
    SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
    SkRect rect = GrTest::TestRect(random);

    GrAAType aaType = GrAAType::kNone;
    if (random->nextBool()) {
        aaType = (numSamples > 1) ? GrAAType::kMSAA : GrAAType::kCoverage;
    }
    const GrUserStencilSettings* stencil = random->nextBool() ? nullptr
                                                              : GrGetRandomStencil(random, context);

    GrQuadAAFlags aaFlags = GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kLeft : GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kTop : GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kRight : GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kBottom : GrQuadAAFlags::kNone;

    if (random->nextBool()) {
        if (random->nextBool()) {
            // Single local matrix
            SkMatrix localMatrix = GrTest::TestMatrixInvertible(random);
            DrawQuad quad = {GrQuad::MakeFromRect(rect, viewMatrix),
                             GrQuad::MakeFromRect(rect, localMatrix), aaFlags};
            return skgpu::ganesh::FillRectOp::Make(
                    context, std::move(paint), aaType, &quad, stencil);
        } else {
            // Pass local rect directly
            SkRect localRect = GrTest::TestRect(random);
            DrawQuad quad = {GrQuad::MakeFromRect(rect, viewMatrix),
                             GrQuad(localRect), aaFlags};
            return skgpu::ganesh::FillRectOp::Make(
                    context, std::move(paint), aaType, &quad, stencil);
        }
    } else {
        // The simplest constructor
        DrawQuad quad = {GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(rect), aaFlags};
        return skgpu::ganesh::FillRectOp::Make(context, std::move(paint), aaType, &quad, stencil);
    }
}

#endif
