/*
 * Copyright 2018 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/ops/GrFillRectOp.h"

#include "include/core/SkMatrix.h"
#include "include/core/SkRect.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrPaint.h"
#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/geometry/GrQuadBuffer.h"
#include "src/gpu/geometry/GrQuadUtils.h"
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
#include "src/gpu/ops/GrQuadPerEdgeAA.h"
#include "src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h"

namespace {

using VertexSpec = GrQuadPerEdgeAA::VertexSpec;
using ColorType = GrQuadPerEdgeAA::ColorType;

#if GR_TEST_UTILS
static 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 FillRectOp 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<FillRectOp>(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.
    FillRectOp(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 = GrQuadPerEdgeAA::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, GrQuadPerEdgeAA::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 ::GrFillRectOp; // for access to addQuad

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

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

        return VertexSpec(fQuads.deviceQuadType(), fColorType, fQuads.localQuadType(),
                          fHelper.usesLocalCoords(), GrQuadPerEdgeAA::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 = GrQuadPerEdgeAA::MakeProcessor(arena, vertexSpec);
        SkASSERT(gp->vertexStride() == vertexSpec.vertexSize());

        fProgramInfo = fHelper.createProgramInfoWithStencil(caps, arena, writeView,
                                                            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();

        GrQuadPerEdgeAA::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 = GrQuadPerEdgeAA::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());
        GrQuadPerEdgeAA::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);
        const auto* that = t->cast<FillRectOp>();

        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 GR_TEST_UTILS
    SkString onDumpInfo() const override {
        SkString str = SkStringPrintf("# draws: %u\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 = GrQuadPerEdgeAA::CalcIndexBufferOption(aaType, quadCount);
            if (quadCount > GrQuadPerEdgeAA::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 = GrQuadPerEdgeAA::CalcIndexBufferOption(fHelper.aaType(),
                                                                            quadCount);
            if (quadCount > GrQuadPerEdgeAA::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

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

GrOp::Owner GrFillRectOp::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 FillRectOp::Make(context, std::move(paint), GrAAType::kNone, &quad, stencil,
                            InputFlags::kNone);
}

GrOp::Owner GrFillRectOp::MakeOp(GrRecordingContext* context,
                                 GrPaint&& paint,
                                 GrAAType aaType,
                                 const SkMatrix& viewMatrix,
                                 const GrSurfaceDrawContext::QuadSetEntry 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);
    FillRectOp* fillRects = op->cast<FillRectOp>();

    *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 GrFillRectOp::AddFillRectOps(GrSurfaceDrawContext* rtc,
                                  const GrClip* clip,
                                  GrRecordingContext* context,
                                  GrPaint&& paint,
                                  GrAAType aaType,
                                  const SkMatrix& viewMatrix,
                                  const GrSurfaceDrawContext::QuadSetEntry 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;

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

    SkASSERT(offset == cnt);
}

#if GR_TEST_UTILS

uint32_t GrFillRectOp::ClassID() {
    return FillRectOp::ClassID();
}

#include "src/gpu/GrDrawOpTest.h"
#include "src/gpu/SkGr.h"

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 GrFillRectOp::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 GrFillRectOp::Make(context, std::move(paint), aaType, &quad, stencil);
        }
    } else {
        // The simplest constructor
        DrawQuad quad = {GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(rect), aaFlags};
        return GrFillRectOp::Make(context, std::move(paint), aaType, &quad, stencil);
    }
}

#endif
