19c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt/*
2ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon * Copyright 2017 Google Inc.
39c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt *
49c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt * Use of this source code is governed by a BSD-style license that can be
59c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt * found in the LICENSE file.
69c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt */
79c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
8ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon#include "GrAppliedClip.h"
99c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#include "GrColor.h"
109c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#include "GrDefaultGeoProcFactory.h"
11177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon#include "GrDrawOpTest.h"
12dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "GrMeshDrawOp.h"
13742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h"
149c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#include "GrPrimitiveProcessor.h"
15ae5b2c623b22b24ea7c0d6200298e5bc366faa63joshualitt#include "GrQuad.h"
16baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon#include "GrRectOpFactory.h"
17dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "GrResourceProvider.h"
18ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon#include "GrSimpleMeshDrawOpHelper.h"
19a39667c848146d9070e1a45662fb292d8e6bb8fbreed#include "SkMatrixPriv.h"
20a39667c848146d9070e1a45662fb292d8e6bb8fbreed
21ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonstatic const int kVertsPerRect = 4;
22ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonstatic const int kIndicesPerRect = 6;
232244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt
2453e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon/** We always use per-vertex colors so that rects can be combined across color changes. Sometimes
252244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    we  have explicit local coords and sometimes not. We *could* always provide explicit local
262244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    coords and just duplicate the positions when the caller hasn't provided a local coord rect,
272244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    but we haven't seen a use case which frequently switches between local rect and no local
282244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    rect draws.
292244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt
302244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    The vertex attrib order is always pos, color, [local coords].
312244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt */
328c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomonstatic sk_sp<GrGeometryProcessor> make_gp() {
336abd1d192e0b2698d19e0b03fe4c2a34fb604b8frobertphillips    using namespace GrDefaultGeoProcFactory;
343de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
358c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                                         LocalCoords::kHasExplicit_Type, SkMatrix::I());
366abd1d192e0b2698d19e0b03fe4c2a34fb604b8frobertphillips}
376abd1d192e0b2698d19e0b03fe4c2a34fb604b8frobertphillips
38ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonstatic sk_sp<GrGeometryProcessor> make_perspective_gp(const SkMatrix& viewMatrix,
39ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                      bool hasExplicitLocalCoords,
40ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                      const SkMatrix* localMatrix) {
41ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
42ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
43ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    using namespace GrDefaultGeoProcFactory;
44ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
45ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    // If we have perspective on the viewMatrix then we won't map on the CPU, nor will we map
46ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    // the local rect on the cpu (in case the localMatrix also has perspective).
47ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    // Otherwise, if we have a local rect, then we apply the localMatrix directly to the localRect
48ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    // to generate vertex local coords
49ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    if (viewMatrix.hasPerspective()) {
50ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type
51ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                       : LocalCoords::kUsePosition_Type,
52ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                localMatrix);
53ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
54ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                             Coverage::kSolid_Type, localCoords, viewMatrix);
55ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    } else if (hasExplicitLocalCoords) {
56ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix);
57ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
58ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                             Coverage::kSolid_Type, localCoords, SkMatrix::I());
59ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    } else {
60ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix);
61ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return GrDefaultGeoProcFactory::MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type,
62ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                           Coverage::kSolid_Type, localCoords,
63ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                           viewMatrix);
64ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
65ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon}
66ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
672244c27ea4db85df305fa09f664b7d75f637e7a9joshualittstatic void tesselate(intptr_t vertices,
682244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt                      size_t vertexStride,
692244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt                      GrColor color,
706abd1d192e0b2698d19e0b03fe4c2a34fb604b8frobertphillips                      const SkMatrix* viewMatrix,
712244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt                      const SkRect& rect,
728cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt                      const GrQuad* localQuad) {
732244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    SkPoint* positions = reinterpret_cast<SkPoint*>(vertices);
742244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt
756a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon    positions->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride);
769c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
776abd1d192e0b2698d19e0b03fe4c2a34fb604b8frobertphillips    if (viewMatrix) {
78ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerRect);
798cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt    }
808cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt
818cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt    // Setup local coords
822244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    // TODO we should only do this if local coords are being read
838cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt    if (localQuad) {
842244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt        static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
85ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        for (int i = 0; i < kVertsPerRect; i++) {
866a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon            SkPoint* coords =
876a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon                    reinterpret_cast<SkPoint*>(vertices + kLocalOffset + i * vertexStride);
888cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt            *coords = localQuad->point(i);
892244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt        }
902244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    }
912244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt
922244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    static const int kColorOffset = sizeof(SkPoint);
932244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset);
942244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    for (int j = 0; j < 4; ++j) {
952244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt        *vertColor = color;
966a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon        vertColor = (GrColor*)((intptr_t)vertColor + vertexStride);
972244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt    }
982244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt}
992244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt
100ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonnamespace {
101ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
102ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonclass NonAAFillRectOp final : public GrMeshDrawOp {
103ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonprivate:
104ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    using Helper = GrSimpleMeshDrawOpHelperWithStencil;
105ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
1069c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualittpublic:
107ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
108ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                          const SkRect& rect, const SkRect* localRect,
109ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                          const SkMatrix* localMatrix, GrAAType aaType,
110ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                          const GrUserStencilSettings* stencilSettings) {
111ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkASSERT(GrAAType::kCoverage != aaType);
112ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return Helper::FactoryHelper<NonAAFillRectOp>(std::move(paint), viewMatrix, rect, localRect,
113ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                      localMatrix, aaType, stencilSettings);
114ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
11508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
116ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    NonAAFillRectOp() = delete;
117ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
118ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    NonAAFillRectOp(const Helper::MakeArgs& args, GrColor color, const SkMatrix& viewMatrix,
119ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                    const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix,
120ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                    GrAAType aaType, const GrUserStencilSettings* stencilSettings)
121ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            : INHERITED(ClassID()), fHelper(args, aaType, stencilSettings) {
1221d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
1236a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon        SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
1249d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        RectInfo& info = fRects.push_back();
1259d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        info.fColor = color;
1269d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        info.fViewMatrix = viewMatrix;
1279d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        info.fRect = rect;
1289d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        if (localRect && localMatrix) {
1299d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon            info.fLocalQuad.setFromMappedRect(*localRect, *localMatrix);
1309d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        } else if (localRect) {
1319d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon            info.fLocalQuad.set(*localRect);
1329d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        } else if (localMatrix) {
1339d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon            info.fLocalQuad.setFromMappedRect(rect, *localMatrix);
1349d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        } else {
1359d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon            info.fLocalQuad.set(rect);
1369d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        }
13788cf17d099085b8085ab11571b5094163dbb2c84bsalomon        this->setTransformedBounds(fRects[0].fRect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
1389d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon    }
13908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
1406a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon    const char* name() const override { return "NonAAFillRectOp"; }
14108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
14208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon    SkString dumpInfo() const override {
14308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        SkString str;
144ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        str.append(GrMeshDrawOp::dumpInfo());
14553e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon        str.appendf("# combined: %d\n", fRects.count());
1469d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        for (int i = 0; i < fRects.count(); ++i) {
1479d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon            const RectInfo& info = fRects[i];
1486a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon            str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
1496a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon                        info.fColor, info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight,
1506a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon                        info.fRect.fBottom);
15108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        }
15282dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        str += fHelper.dumpInfo();
15382dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        str += INHERITED::dumpInfo();
15408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        return str;
15508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon    }
15608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
157f86d37be5b539e8b318d4449713e13f2cfc94da8Brian Salomon    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
158ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        GrColor* color = &fRects.front().fColor;
159ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
16008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon    }
16108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
162ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
163ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
164ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    DEFINE_OP_CLASS_ID
16508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
166ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonprivate:
16708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon    void onPrepareDraws(Target* target) const override {
1688c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon        sk_sp<GrGeometryProcessor> gp = make_gp();
16908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        if (!gp) {
17008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon            SkDebugf("Couldn't create GrGeometryProcessor\n");
17108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon            return;
17208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        }
173bc9b6a4239b797fe7fbdb876607053b18eba2380bsalomon        SkASSERT(gp->getVertexStride() ==
174bc9b6a4239b797fe7fbdb876607053b18eba2380bsalomon                 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr));
17508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
17608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        size_t vertexStride = gp->getVertexStride();
177ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        int rectCount = fRects.count();
17808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
179144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary        sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
1803809bab7ed344ad140346c38e149dabf10bd525fChris Dalton        PatternHelper helper(GrPrimitiveType::kTriangles);
181bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton        void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
182bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton                                     kIndicesPerRect, rectCount);
18308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        if (!vertices || !indexBuffer) {
18408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon            SkDebugf("Could not allocate vertices\n");
18508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon            return;
18608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        }
18708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
188ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        for (int i = 0; i < rectCount; i++) {
1896a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon            intptr_t verts =
190ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                    reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
1916abd1d192e0b2698d19e0b03fe4c2a34fb604b8frobertphillips            tesselate(verts, vertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
1929d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon                      fRects[i].fRect, &fRects[i].fLocalQuad);
19308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        }
194ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
19508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon    }
19608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
19725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
1986a639040bc3ee5369d86c9cb5b9047208beb5206Brian Salomon        NonAAFillRectOp* that = t->cast<NonAAFillRectOp>();
199ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
20008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon            return false;
20108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        }
2029d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        fRects.push_back_n(that->fRects.count(), that->fRects.begin());
20388cf17d099085b8085ab11571b5094163dbb2c84bsalomon        this->joinBounds(*that);
20408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon        return true;
20508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon    }
20608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon
2079d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon    struct RectInfo {
2089d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        GrColor fColor;
2099d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        SkMatrix fViewMatrix;
2109d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        SkRect fRect;
2119d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon        GrQuad fLocalQuad;
2129d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon    };
2139d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon
214ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    Helper fHelper;
2159d7f1849a88f5f2f6c7c00fe826d1d42a2df990fbsalomon    SkSTArray<1, RectInfo, true> fRects;
216ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    typedef GrMeshDrawOp INHERITED;
2172244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt};
2189c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
219ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon// We handle perspective in the local matrix or viewmatrix with special ops.
220ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonclass NonAAFillRectPerspectiveOp final : public GrMeshDrawOp {
221ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonprivate:
222ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    using Helper = GrSimpleMeshDrawOpHelperWithStencil;
223b8cbd2098225ee2ec1bd96b3e2b1cf3f5164d2d8bsalomon
224ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonpublic:
225ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
226ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                          const SkRect& rect, const SkRect* localRect,
227ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                          const SkMatrix* localMatrix, GrAAType aaType,
228ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                          const GrUserStencilSettings* stencilSettings) {
229ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkASSERT(GrAAType::kCoverage != aaType);
230ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return Helper::FactoryHelper<NonAAFillRectPerspectiveOp>(std::move(paint), viewMatrix, rect,
231ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                                 localRect, localMatrix, aaType,
232ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                                                 stencilSettings);
233ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
2349c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
235ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    NonAAFillRectPerspectiveOp() = delete;
236ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
237ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    NonAAFillRectPerspectiveOp(const Helper::MakeArgs& args, GrColor color,
238ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                               const SkMatrix& viewMatrix, const SkRect& rect,
239ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                               const SkRect* localRect, const SkMatrix* localMatrix,
240ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                               GrAAType aaType, const GrUserStencilSettings* stencilSettings)
241ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            : INHERITED(ClassID())
242ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            , fHelper(args, aaType, stencilSettings)
243ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            , fViewMatrix(viewMatrix) {
244ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
245ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        RectInfo& info = fRects.push_back();
246ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        info.fColor = color;
247ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        info.fRect = rect;
248ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        fHasLocalRect = SkToBool(localRect);
249ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        fHasLocalMatrix = SkToBool(localMatrix);
250ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (fHasLocalMatrix) {
251ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            fLocalMatrix = *localMatrix;
252ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
253ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (fHasLocalRect) {
254ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            info.fLocalRect = *localRect;
255ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
256ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        this->setTransformedBounds(rect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
257ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
258ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
259ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    const char* name() const override { return "NonAAFillRectPerspectiveOp"; }
260ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
261ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    SkString dumpInfo() const override {
262ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkString str;
263ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        str.appendf("# combined: %d\n", fRects.count());
264ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        for (int i = 0; i < fRects.count(); ++i) {
265ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            const RectInfo& geo = fRects[0];
266ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
267ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                        geo.fColor, geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight,
268ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                        geo.fRect.fBottom);
269ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
27082dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        str += fHelper.dumpInfo();
27182dfd3d1b2e173e10d2b4b7ac6c843554a1b229fBrian Salomon        str += INHERITED::dumpInfo();
272ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return str;
273ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
274ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
275f86d37be5b539e8b318d4449713e13f2cfc94da8Brian Salomon    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
276ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        GrColor* color = &fRects.front().fColor;
277ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
278ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
279ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
280ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
2819c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
282ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    DEFINE_OP_CLASS_ID
283ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
284ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomonprivate:
285ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    void onPrepareDraws(Target* target) const override {
286ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        sk_sp<GrGeometryProcessor> gp = make_perspective_gp(
287ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                fViewMatrix, fHasLocalRect, fHasLocalMatrix ? &fLocalMatrix : nullptr);
288ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (!gp) {
289ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            SkDebugf("Couldn't create GrGeometryProcessor\n");
290ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            return;
291ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
292ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkASSERT(fHasLocalRect
293ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                         ? gp->getVertexStride() ==
294ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                   sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
295ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                         : gp->getVertexStride() ==
296ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                   sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
297ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
298ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        size_t vertexStride = gp->getVertexStride();
299ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        int rectCount = fRects.count();
300ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
301ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
3023809bab7ed344ad140346c38e149dabf10bd525fChris Dalton        PatternHelper helper(GrPrimitiveType::kTriangles);
303bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton        void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
304bca46e29e9f96999df0b38fb9359e71b73217c94Chris Dalton                                     kIndicesPerRect, rectCount);
305ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (!vertices || !indexBuffer) {
306ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            SkDebugf("Could not allocate vertices\n");
307ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            return;
308ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
3099c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
310ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        for (int i = 0; i < rectCount; i++) {
311ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            const RectInfo& info = fRects[i];
312ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            intptr_t verts =
313ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                    reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
314ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            if (fHasLocalRect) {
315ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                GrQuad quad(info.fLocalRect);
316ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, &quad);
317ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            } else {
318ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, nullptr);
319ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            }
320ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
321ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
322ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
3239c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
324ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
325ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        NonAAFillRectPerspectiveOp* that = t->cast<NonAAFillRectPerspectiveOp>();
326ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
327ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            return false;
328ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
3292244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt
330ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        // We could combine across perspective vm changes if we really wanted to.
331ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
332ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            return false;
333ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
334ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (fHasLocalRect != that->fHasLocalRect) {
335ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            return false;
336ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
337ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        if (fHasLocalMatrix && !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
338ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon            return false;
339ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        }
340ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
341ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        fRects.push_back_n(that->fRects.count(), that->fRects.begin());
342ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        this->joinBounds(*that);
343ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        return true;
344ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
345ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
346ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    struct RectInfo {
347ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkRect fRect;
348ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        GrColor fColor;
349ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon        SkRect fLocalRect;
350ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    };
351ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
352ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    SkSTArray<1, RectInfo, true> fRects;
353ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    Helper fHelper;
354ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    bool fHasLocalMatrix;
355ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    bool fHasLocalRect;
356ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    SkMatrix fLocalMatrix;
357ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    SkMatrix fViewMatrix;
358ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
359ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    typedef GrMeshDrawOp INHERITED;
360ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon};
361ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
362ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon}  // anonymous namespace
363ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
364baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomonnamespace GrRectOpFactory {
365baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon
366baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomonstd::unique_ptr<GrDrawOp> MakeNonAAFill(GrPaint&& paint, const SkMatrix& viewMatrix,
367baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                        const SkRect& rect, GrAAType aaType,
368baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                        const GrUserStencilSettings* stencilSettings) {
369baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    if (viewMatrix.hasPerspective()) {
370baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr,
371baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                                nullptr, aaType, stencilSettings);
372baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    } else {
373baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, nullptr, aaType,
374baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                     stencilSettings);
375baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    }
376baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon}
377baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon
378baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomonstd::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix(
379baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        GrPaint&& paint, const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
380baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        const SkRect& rect, GrAAType aaType, const GrUserStencilSettings* stencilSettings) {
381baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    if (viewMatrix.hasPerspective() || localMatrix.hasPerspective()) {
382baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr,
383baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                                &localMatrix, aaType, stencilSettings);
384baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    } else {
385baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, &localMatrix,
386ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon                                     aaType, stencilSettings);
387baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    }
388baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon}
389baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon
390baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomonstd::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix,
391baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                                     const SkRect& rect, const SkRect& localRect,
392baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                                     GrAAType aaType) {
393baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    if (viewMatrix.hasPerspective()) {
394baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, &localRect,
395baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                                nullptr, aaType, nullptr);
396ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    } else {
397baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, &localRect, nullptr,
398baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                     aaType, nullptr);
399ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon    }
4009c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt}
4019c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt
402baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon}  // namespace GrRectOpFactory
403ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon
404ac70f84e7f4fc9ddd344753b92cdf4be540d32bfBrian Salomon///////////////////////////////////////////////////////////////////////////////////////////////////
405177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon
4060c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon#if GR_TEST_UTILS
4070c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon
408177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian SalomonGR_DRAW_OP_TEST_DEFINE(NonAAFillRectOp) {
409177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    SkRect rect = GrTest::TestRect(random);
410177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    SkRect localRect = GrTest::TestRect(random);
411177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
412177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    SkMatrix localMatrix = GrTest::TestMatrix(random);
413177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    const GrUserStencilSettings* stencil = GrGetRandomStencil(random, context);
414177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    GrAAType aaType = GrAAType::kNone;
415177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    if (fsaaType == GrFSAAType::kUnifiedMSAA) {
416177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon        aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone;
417177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon    }
418baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    const SkRect* lr = random->nextBool() ? &localRect : nullptr;
419baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    const SkMatrix* lm = random->nextBool() ? &localMatrix : nullptr;
420baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    if (viewMatrix.hasPerspective() || (lm && lm->hasPerspective())) {
421baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType,
422baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon                                                stencil);
423baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    } else {
424baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType, stencil);
425baaf439eb5d08097d794f13800e5bf7ce8885f95Brian Salomon    }
426177266339c3aa6dda4fa2912af9eaa8e8206f78fBrian Salomon}
4270c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon
4280c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon#endif
429