1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrAppliedClip.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrColor.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrDefaultGeoProcFactory.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrDrawOpTest.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrMeshDrawOp.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrOpFlushState.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrPrimitiveProcessor.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrQuad.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRectOpFactory.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceProvider.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrSimpleMeshDrawOpHelper.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMatrixPriv.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int kVertsPerRect = 4;
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int kIndicesPerRect = 6;
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** We always use per-vertex colors so that rects can be combined across color changes. Sometimes
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    we  have explicit local coords and sometimes not. We *could* always provide explicit local
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    coords and just duplicate the positions when the caller hasn't provided a local coord rect,
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    but we haven't seen a use case which frequently switches between local rect and no local
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rect draws.
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    The vertex attrib order is always pos, color, [local coords].
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<GrGeometryProcessor> make_gp() {
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    using namespace GrDefaultGeoProcFactory;
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                         LocalCoords::kHasExplicit_Type, SkMatrix::I());
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<GrGeometryProcessor> make_perspective_gp(const SkMatrix& viewMatrix,
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                      bool hasExplicitLocalCoords,
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                      const SkMatrix* localMatrix) {
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    using namespace GrDefaultGeoProcFactory;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // If we have perspective on the viewMatrix then we won't map on the CPU, nor will we map
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // the local rect on the cpu (in case the localMatrix also has perspective).
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Otherwise, if we have a local rect, then we apply the localMatrix directly to the localRect
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // to generate vertex local coords
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (viewMatrix.hasPerspective()) {
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                       : LocalCoords::kUsePosition_Type,
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                localMatrix);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                             Coverage::kSolid_Type, localCoords, viewMatrix);
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else if (hasExplicitLocalCoords) {
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix);
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                             Coverage::kSolid_Type, localCoords, SkMatrix::I());
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix);
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return GrDefaultGeoProcFactory::MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type,
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                           Coverage::kSolid_Type, localCoords,
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                           viewMatrix);
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void tesselate(intptr_t vertices,
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      size_t vertexStride,
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      GrColor color,
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const SkMatrix* viewMatrix,
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const SkRect& rect,
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const GrQuad* localQuad) {
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint* positions = reinterpret_cast<SkPoint*>(vertices);
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPointPriv::SetRectTriStrip(positions, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom,
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            vertexStride);
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (viewMatrix) {
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerRect);
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Setup local coords
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // TODO we should only do this if local coords are being read
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (localQuad) {
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kVertsPerRect; i++) {
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkPoint* coords =
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    reinterpret_cast<SkPoint*>(vertices + kLocalOffset + i * vertexStride);
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *coords = localQuad->point(i);
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kColorOffset = sizeof(SkPoint);
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset);
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int j = 0; j < 4; ++j) {
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        *vertColor = color;
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        vertColor = (GrColor*)((intptr_t)vertColor + vertexStride);
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace {
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass NonAAFillRectOp final : public GrMeshDrawOp {
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    using Helper = GrSimpleMeshDrawOpHelperWithStencil;
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          const SkRect& rect, const SkRect* localRect,
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          const SkMatrix* localMatrix, GrAAType aaType,
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          const GrUserStencilSettings* stencilSettings) {
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(GrAAType::kCoverage != aaType);
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return Helper::FactoryHelper<NonAAFillRectOp>(std::move(paint), viewMatrix, rect, localRect,
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                      localMatrix, aaType, stencilSettings);
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    NonAAFillRectOp() = delete;
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    NonAAFillRectOp(const Helper::MakeArgs& args, GrColor color, const SkMatrix& viewMatrix,
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix,
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    GrAAType aaType, const GrUserStencilSettings* stencilSettings)
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : INHERITED(ClassID()), fHelper(args, aaType, stencilSettings) {
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        RectInfo& info = fRects.push_back();
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info.fColor = color;
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info.fViewMatrix = viewMatrix;
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info.fRect = rect;
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (localRect && localMatrix) {
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            info.fLocalQuad.setFromMappedRect(*localRect, *localMatrix);
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (localRect) {
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            info.fLocalQuad.set(*localRect);
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (localMatrix) {
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            info.fLocalQuad.setFromMappedRect(rect, *localMatrix);
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            info.fLocalQuad.set(rect);
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setTransformedBounds(fRects[0].fRect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* name() const override { return "NonAAFillRectOp"; }
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void visitProxies(const VisitProxyFunc& func) const override {
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fHelper.visitProxies(func);
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString dumpInfo() const override {
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkString str;
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str.append(GrMeshDrawOp::dumpInfo());
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str.appendf("# combined: %d\n", fRects.count());
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < fRects.count(); ++i) {
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const RectInfo& info = fRects[i];
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        info.fColor, info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight,
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        info.fRect.fBottom);
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str += fHelper.dumpInfo();
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str += INHERITED::dumpInfo();
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return str;
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip,
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                GrPixelConfigIsClamped dstIsClamped) override {
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrColor* color = &fRects.front().fColor;
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fHelper.xpRequiresDstTexture(caps, clip, dstIsClamped,
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            GrProcessorAnalysisCoverage::kNone, color);
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DEFINE_OP_CLASS_ID
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onPrepareDraws(Target* target) override {
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrGeometryProcessor> gp = make_gp();
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!gp) {
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Couldn't create GrGeometryProcessor\n");
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(gp->getVertexStride() ==
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr));
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t vertexStride = gp->getVertexStride();
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int rectCount = fRects.count();
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        PatternHelper helper(GrPrimitiveType::kTriangles);
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     kIndicesPerRect, rectCount);
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!vertices || !indexBuffer) {
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Could not allocate vertices\n");
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < rectCount; i++) {
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            intptr_t verts =
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            tesselate(verts, vertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      fRects[i].fRect, &fRects[i].fLocalQuad);
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        NonAAFillRectOp* that = t->cast<NonAAFillRectOp>();
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRects.push_back_n(that->fRects.count(), that->fRects.begin());
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->joinBounds(*that);
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct RectInfo {
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrColor fColor;
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkMatrix fViewMatrix;
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect fRect;
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrQuad fLocalQuad;
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Helper fHelper;
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkSTArray<1, RectInfo, true> fRects;
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GrMeshDrawOp INHERITED;
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// We handle perspective in the local matrix or viewmatrix with special ops.
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass NonAAFillRectPerspectiveOp final : public GrMeshDrawOp {
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    using Helper = GrSimpleMeshDrawOpHelperWithStencil;
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          const SkRect& rect, const SkRect* localRect,
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          const SkMatrix* localMatrix, GrAAType aaType,
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          const GrUserStencilSettings* stencilSettings) {
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(GrAAType::kCoverage != aaType);
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return Helper::FactoryHelper<NonAAFillRectPerspectiveOp>(std::move(paint), viewMatrix, rect,
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                 localRect, localMatrix, aaType,
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                 stencilSettings);
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    NonAAFillRectPerspectiveOp() = delete;
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    NonAAFillRectPerspectiveOp(const Helper::MakeArgs& args, GrColor color,
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                               const SkMatrix& viewMatrix, const SkRect& rect,
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                               const SkRect* localRect, const SkMatrix* localMatrix,
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                               GrAAType aaType, const GrUserStencilSettings* stencilSettings)
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : INHERITED(ClassID())
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fHelper(args, aaType, stencilSettings)
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fViewMatrix(viewMatrix) {
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        RectInfo& info = fRects.push_back();
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info.fColor = color;
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info.fRect = rect;
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fHasLocalRect = SkToBool(localRect);
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fHasLocalMatrix = SkToBool(localMatrix);
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fHasLocalMatrix) {
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fLocalMatrix = *localMatrix;
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fHasLocalRect) {
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            info.fLocalRect = *localRect;
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setTransformedBounds(rect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* name() const override { return "NonAAFillRectPerspectiveOp"; }
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void visitProxies(const VisitProxyFunc& func) const override {
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fHelper.visitProxies(func);
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString dumpInfo() const override {
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkString str;
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str.appendf("# combined: %d\n", fRects.count());
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < fRects.count(); ++i) {
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const RectInfo& geo = fRects[i];
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        geo.fColor, geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight,
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        geo.fRect.fBottom);
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str += fHelper.dumpInfo();
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str += INHERITED::dumpInfo();
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return str;
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip,
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                GrPixelConfigIsClamped dstIsClamped) override {
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrColor* color = &fRects.front().fColor;
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fHelper.xpRequiresDstTexture(caps, clip, dstIsClamped,
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            GrProcessorAnalysisCoverage::kNone, color);
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DEFINE_OP_CLASS_ID
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onPrepareDraws(Target* target) override {
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrGeometryProcessor> gp = make_perspective_gp(
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fViewMatrix, fHasLocalRect, fHasLocalMatrix ? &fLocalMatrix : nullptr);
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!gp) {
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Couldn't create GrGeometryProcessor\n");
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fHasLocalRect
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         ? gp->getVertexStride() ==
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         : gp->getVertexStride() ==
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t vertexStride = gp->getVertexStride();
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int rectCount = fRects.count();
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        PatternHelper helper(GrPrimitiveType::kTriangles);
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     kIndicesPerRect, rectCount);
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!vertices || !indexBuffer) {
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("Could not allocate vertices\n");
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < rectCount; i++) {
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const RectInfo& info = fRects[i];
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            intptr_t verts =
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fHasLocalRect) {
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                GrQuad quad(info.fLocalRect);
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, &quad);
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, nullptr);
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        NonAAFillRectPerspectiveOp* that = t->cast<NonAAFillRectPerspectiveOp>();
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // We could combine across perspective vm changes if we really wanted to.
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fHasLocalRect != that->fHasLocalRect) {
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fHasLocalMatrix && !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fRects.push_back_n(that->fRects.count(), that->fRects.begin());
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->joinBounds(*that);
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct RectInfo {
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect fRect;
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrColor fColor;
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect fLocalRect;
363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkSTArray<1, RectInfo, true> fRects;
366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Helper fHelper;
367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fHasLocalMatrix;
368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fHasLocalRect;
369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrix fLocalMatrix;
370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrix fViewMatrix;
371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GrMeshDrawOp INHERITED;
373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}  // anonymous namespace
376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace GrRectOpFactory {
378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrDrawOp> MakeNonAAFill(GrPaint&& paint, const SkMatrix& viewMatrix,
380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        const SkRect& rect, GrAAType aaType,
381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        const GrUserStencilSettings* stencilSettings) {
382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (viewMatrix.hasPerspective()) {
383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr,
384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                nullptr, aaType, stencilSettings);
385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, nullptr, aaType,
387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     stencilSettings);
388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix(
392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrPaint&& paint, const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkRect& rect, GrAAType aaType, const GrUserStencilSettings* stencilSettings) {
394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (viewMatrix.hasPerspective() || localMatrix.hasPerspective()) {
395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr,
396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                &localMatrix, aaType, stencilSettings);
397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, &localMatrix,
399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     aaType, stencilSettings);
400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix,
404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                     const SkRect& rect, const SkRect& localRect,
405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                     GrAAType aaType) {
406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (viewMatrix.hasPerspective()) {
407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, &localRect,
408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                nullptr, aaType, nullptr);
409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, &localRect, nullptr,
411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     aaType, nullptr);
412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}  // namespace GrRectOpFactory
416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////////////////////////
418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_TEST_UTILS
420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGR_DRAW_OP_TEST_DEFINE(NonAAFillRectOp) {
422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect rect = GrTest::TestRect(random);
423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect localRect = GrTest::TestRect(random);
424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrix localMatrix = GrTest::TestMatrix(random);
426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const GrUserStencilSettings* stencil = GrGetRandomStencil(random, context);
427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrAAType aaType = GrAAType::kNone;
428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fsaaType == GrFSAAType::kUnifiedMSAA) {
429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone;
430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkRect* lr = random->nextBool() ? &localRect : nullptr;
432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkMatrix* lm = random->nextBool() ? &localMatrix : nullptr;
433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (viewMatrix.hasPerspective() || (lm && lm->hasPerspective())) {
434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType,
435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                stencil);
436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    } else {
437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType, stencil);
438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
442