blob: 1b76d4abfeefbfaa0beaac5e5ad597a543035d83 [file] [log] [blame]
joshualitt9c80b5f2015-08-13 10:05:51 -07001/*
Brian Salomonac70f842017-05-08 10:43:33 -04002 * Copyright 2017 Google Inc.
joshualitt9c80b5f2015-08-13 10:05:51 -07003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Brian Salomonac70f842017-05-08 10:43:33 -04008#include "GrAppliedClip.h"
joshualitt9c80b5f2015-08-13 10:05:51 -07009#include "GrColor.h"
10#include "GrDefaultGeoProcFactory.h"
Brian Salomon17726632017-05-12 14:09:46 -040011#include "GrDrawOpTest.h"
Brian Salomondad29232016-12-01 16:40:24 -050012#include "GrMeshDrawOp.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050013#include "GrOpFlushState.h"
joshualitt9c80b5f2015-08-13 10:05:51 -070014#include "GrPrimitiveProcessor.h"
joshualittae5b2c62015-08-19 08:48:41 -070015#include "GrQuad.h"
Brian Salomonbaaf4392017-06-15 09:59:23 -040016#include "GrRectOpFactory.h"
Brian Salomondad29232016-12-01 16:40:24 -050017#include "GrResourceProvider.h"
Brian Salomonac70f842017-05-08 10:43:33 -040018#include "GrSimpleMeshDrawOpHelper.h"
reeda39667c2016-08-22 06:39:49 -070019#include "SkMatrixPriv.h"
20
Brian Salomonac70f842017-05-08 10:43:33 -040021static const int kVertsPerRect = 4;
22static const int kIndicesPerRect = 6;
joshualitt2244c272015-08-21 10:33:15 -070023
Brian Salomon53e4c3c2016-12-21 11:38:53 -050024/** We always use per-vertex colors so that rects can be combined across color changes. Sometimes
joshualitt2244c272015-08-21 10:33:15 -070025 we have explicit local coords and sometimes not. We *could* always provide explicit local
26 coords and just duplicate the positions when the caller hasn't provided a local coord rect,
27 but we haven't seen a use case which frequently switches between local rect and no local
28 rect draws.
29
30 The vertex attrib order is always pos, color, [local coords].
31 */
Brian Salomon8c852be2017-01-04 10:44:42 -050032static sk_sp<GrGeometryProcessor> make_gp() {
robertphillips6abd1d12016-07-01 09:06:56 -070033 using namespace GrDefaultGeoProcFactory;
Brian Salomon3de0aee2017-01-29 09:34:17 -050034 return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
Brian Salomon8c852be2017-01-04 10:44:42 -050035 LocalCoords::kHasExplicit_Type, SkMatrix::I());
robertphillips6abd1d12016-07-01 09:06:56 -070036}
37
Brian Salomonac70f842017-05-08 10:43:33 -040038static sk_sp<GrGeometryProcessor> make_perspective_gp(const SkMatrix& viewMatrix,
39 bool hasExplicitLocalCoords,
40 const SkMatrix* localMatrix) {
41 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
42
43 using namespace GrDefaultGeoProcFactory;
44
45 // If we have perspective on the viewMatrix then we won't map on the CPU, nor will we map
46 // the local rect on the cpu (in case the localMatrix also has perspective).
47 // Otherwise, if we have a local rect, then we apply the localMatrix directly to the localRect
48 // to generate vertex local coords
49 if (viewMatrix.hasPerspective()) {
50 LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type
51 : LocalCoords::kUsePosition_Type,
52 localMatrix);
53 return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
54 Coverage::kSolid_Type, localCoords, viewMatrix);
55 } else if (hasExplicitLocalCoords) {
56 LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix);
57 return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
58 Coverage::kSolid_Type, localCoords, SkMatrix::I());
59 } else {
60 LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix);
61 return GrDefaultGeoProcFactory::MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type,
62 Coverage::kSolid_Type, localCoords,
63 viewMatrix);
64 }
65}
66
joshualitt2244c272015-08-21 10:33:15 -070067static void tesselate(intptr_t vertices,
68 size_t vertexStride,
69 GrColor color,
robertphillips6abd1d12016-07-01 09:06:56 -070070 const SkMatrix* viewMatrix,
joshualitt2244c272015-08-21 10:33:15 -070071 const SkRect& rect,
joshualitt8cce8f12015-08-26 06:23:39 -070072 const GrQuad* localQuad) {
joshualitt2244c272015-08-21 10:33:15 -070073 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices);
74
Brian Salomonbe3c1d22018-05-21 12:54:39 -040075 SkPointPriv::SetRectTriStrip(positions, rect, vertexStride);
joshualitt2244c272015-08-21 10:33:15 -070076
robertphillips6abd1d12016-07-01 09:06:56 -070077 if (viewMatrix) {
Brian Salomonac70f842017-05-08 10:43:33 -040078 SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerRect);
joshualitt8cce8f12015-08-26 06:23:39 -070079 }
80
81 // Setup local coords
joshualitt2244c272015-08-21 10:33:15 -070082 // TODO we should only do this if local coords are being read
joshualitt8cce8f12015-08-26 06:23:39 -070083 if (localQuad) {
joshualitt2244c272015-08-21 10:33:15 -070084 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
Brian Salomonac70f842017-05-08 10:43:33 -040085 for (int i = 0; i < kVertsPerRect; i++) {
Brian Salomon6a639042016-12-14 11:08:17 -050086 SkPoint* coords =
87 reinterpret_cast<SkPoint*>(vertices + kLocalOffset + i * vertexStride);
joshualitt8cce8f12015-08-26 06:23:39 -070088 *coords = localQuad->point(i);
joshualitt2244c272015-08-21 10:33:15 -070089 }
90 }
91
92 static const int kColorOffset = sizeof(SkPoint);
93 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset);
94 for (int j = 0; j < 4; ++j) {
95 *vertColor = color;
Brian Salomon6a639042016-12-14 11:08:17 -050096 vertColor = (GrColor*)((intptr_t)vertColor + vertexStride);
joshualitt2244c272015-08-21 10:33:15 -070097 }
98}
99
Brian Salomonac70f842017-05-08 10:43:33 -0400100namespace {
bsalomon08d14152016-06-30 12:45:18 -0700101
Brian Salomonac70f842017-05-08 10:43:33 -0400102class NonAAFillRectOp final : public GrMeshDrawOp {
103private:
104 using Helper = GrSimpleMeshDrawOpHelperWithStencil;
105
106public:
Robert Phillips7c525e62018-06-12 10:11:12 -0400107 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
108 GrPaint&& paint,
109 const SkMatrix& viewMatrix,
110 const SkRect& rect,
111 const SkRect* localRect,
112 const SkMatrix* localMatrix,
113 GrAAType aaType,
Brian Salomonac70f842017-05-08 10:43:33 -0400114 const GrUserStencilSettings* stencilSettings) {
115 SkASSERT(GrAAType::kCoverage != aaType);
Robert Phillips7c525e62018-06-12 10:11:12 -0400116 return Helper::FactoryHelper<NonAAFillRectOp>(context, std::move(paint), viewMatrix, rect,
117 localRect, localMatrix, aaType,
118 stencilSettings);
Brian Salomonac70f842017-05-08 10:43:33 -0400119 }
120
121 NonAAFillRectOp() = delete;
122
123 NonAAFillRectOp(const Helper::MakeArgs& args, GrColor color, const SkMatrix& viewMatrix,
124 const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix,
125 GrAAType aaType, const GrUserStencilSettings* stencilSettings)
126 : INHERITED(ClassID()), fHelper(args, aaType, stencilSettings) {
Chris Dalton1d616352017-05-31 12:51:23 -0600127
Brian Salomon6a639042016-12-14 11:08:17 -0500128 SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
bsalomon9d7f1842016-07-01 08:01:36 -0700129 RectInfo& info = fRects.push_back();
130 info.fColor = color;
131 info.fViewMatrix = viewMatrix;
132 info.fRect = rect;
133 if (localRect && localMatrix) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400134 info.fLocalQuad = GrQuad(*localRect, *localMatrix);
bsalomon9d7f1842016-07-01 08:01:36 -0700135 } else if (localRect) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400136 info.fLocalQuad = GrQuad(*localRect);
bsalomon9d7f1842016-07-01 08:01:36 -0700137 } else if (localMatrix) {
Brian Salomona33b67c2018-05-17 10:42:14 -0400138 info.fLocalQuad = GrQuad(rect, *localMatrix);
bsalomon9d7f1842016-07-01 08:01:36 -0700139 } else {
Brian Salomona33b67c2018-05-17 10:42:14 -0400140 info.fLocalQuad = GrQuad(rect);
bsalomon9d7f1842016-07-01 08:01:36 -0700141 }
bsalomon88cf17d2016-07-08 06:40:56 -0700142 this->setTransformedBounds(fRects[0].fRect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
bsalomon9d7f1842016-07-01 08:01:36 -0700143 }
bsalomon08d14152016-06-30 12:45:18 -0700144
Brian Salomon6a639042016-12-14 11:08:17 -0500145 const char* name() const override { return "NonAAFillRectOp"; }
bsalomon08d14152016-06-30 12:45:18 -0700146
Robert Phillipsf1748f52017-09-14 14:11:24 -0400147 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400148 fHelper.visitProxies(func);
149 }
150
bsalomon08d14152016-06-30 12:45:18 -0700151 SkString dumpInfo() const override {
152 SkString str;
Brian Salomonac70f842017-05-08 10:43:33 -0400153 str.append(GrMeshDrawOp::dumpInfo());
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500154 str.appendf("# combined: %d\n", fRects.count());
bsalomon9d7f1842016-07-01 08:01:36 -0700155 for (int i = 0; i < fRects.count(); ++i) {
156 const RectInfo& info = fRects[i];
Brian Salomon6a639042016-12-14 11:08:17 -0500157 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
158 info.fColor, info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight,
159 info.fRect.fBottom);
bsalomon08d14152016-06-30 12:45:18 -0700160 }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400161 str += fHelper.dumpInfo();
162 str += INHERITED::dumpInfo();
bsalomon08d14152016-06-30 12:45:18 -0700163 return str;
164 }
165
Brian Osman532b3f92018-07-11 10:02:07 -0400166 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400167 GrColor* color = &fRects.front().fColor;
Brian Osman532b3f92018-07-11 10:02:07 -0400168 return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
Brian Salomonac70f842017-05-08 10:43:33 -0400169 }
170
171 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
172
173 DEFINE_OP_CLASS_ID
174
bsalomon08d14152016-06-30 12:45:18 -0700175private:
Brian Salomon91326c32017-08-09 16:02:19 -0400176 void onPrepareDraws(Target* target) override {
Brian Salomon8c852be2017-01-04 10:44:42 -0500177 sk_sp<GrGeometryProcessor> gp = make_gp();
bsalomon08d14152016-06-30 12:45:18 -0700178 if (!gp) {
179 SkDebugf("Couldn't create GrGeometryProcessor\n");
180 return;
181 }
182
Brian Salomon92be2f72018-06-19 14:33:47 -0400183 static constexpr size_t kVertexStride =
184 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr);
185 SkASSERT(kVertexStride == gp->debugOnly_vertexStride());
186
Brian Salomonac70f842017-05-08 10:43:33 -0400187 int rectCount = fRects.count();
bsalomon08d14152016-06-30 12:45:18 -0700188
Brian Salomond28a79d2017-10-16 13:01:07 -0400189 sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
Chris Dalton3809bab2017-06-13 10:55:06 -0600190 PatternHelper helper(GrPrimitiveType::kTriangles);
Brian Salomon92be2f72018-06-19 14:33:47 -0400191 void* vertices = helper.init(target, kVertexStride, indexBuffer.get(), kVertsPerRect,
Chris Daltonbca46e22017-05-15 11:03:26 -0600192 kIndicesPerRect, rectCount);
bsalomon08d14152016-06-30 12:45:18 -0700193 if (!vertices || !indexBuffer) {
194 SkDebugf("Could not allocate vertices\n");
195 return;
196 }
197
Brian Salomonac70f842017-05-08 10:43:33 -0400198 for (int i = 0; i < rectCount; i++) {
Brian Salomon6a639042016-12-14 11:08:17 -0500199 intptr_t verts =
Brian Salomon92be2f72018-06-19 14:33:47 -0400200 reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * kVertexStride;
201 tesselate(verts, kVertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
bsalomon9d7f1842016-07-01 08:01:36 -0700202 fRects[i].fRect, &fRects[i].fLocalQuad);
bsalomon08d14152016-06-30 12:45:18 -0700203 }
Brian Salomon49348902018-06-26 09:12:38 -0400204 auto pipe = fHelper.makePipeline(target);
205 helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
bsalomon08d14152016-06-30 12:45:18 -0700206 }
207
Brian Salomon25a88092016-12-01 09:36:50 -0500208 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
Brian Salomon6a639042016-12-14 11:08:17 -0500209 NonAAFillRectOp* that = t->cast<NonAAFillRectOp>();
Brian Salomonac70f842017-05-08 10:43:33 -0400210 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
bsalomon08d14152016-06-30 12:45:18 -0700211 return false;
212 }
bsalomon9d7f1842016-07-01 08:01:36 -0700213 fRects.push_back_n(that->fRects.count(), that->fRects.begin());
bsalomon88cf17d2016-07-08 06:40:56 -0700214 this->joinBounds(*that);
bsalomon08d14152016-06-30 12:45:18 -0700215 return true;
216 }
217
bsalomon9d7f1842016-07-01 08:01:36 -0700218 struct RectInfo {
219 GrColor fColor;
220 SkMatrix fViewMatrix;
221 SkRect fRect;
222 GrQuad fLocalQuad;
223 };
224
Brian Salomonac70f842017-05-08 10:43:33 -0400225 Helper fHelper;
bsalomon9d7f1842016-07-01 08:01:36 -0700226 SkSTArray<1, RectInfo, true> fRects;
Brian Salomonac70f842017-05-08 10:43:33 -0400227 typedef GrMeshDrawOp INHERITED;
joshualitt2244c272015-08-21 10:33:15 -0700228};
229
Brian Salomonac70f842017-05-08 10:43:33 -0400230// We handle perspective in the local matrix or viewmatrix with special ops.
231class NonAAFillRectPerspectiveOp final : public GrMeshDrawOp {
232private:
233 using Helper = GrSimpleMeshDrawOpHelperWithStencil;
234
235public:
Robert Phillips7c525e62018-06-12 10:11:12 -0400236 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
237 GrPaint&& paint,
238 const SkMatrix& viewMatrix,
239 const SkRect& rect,
240 const SkRect* localRect,
241 const SkMatrix* localMatrix,
242 GrAAType aaType,
Brian Salomonac70f842017-05-08 10:43:33 -0400243 const GrUserStencilSettings* stencilSettings) {
244 SkASSERT(GrAAType::kCoverage != aaType);
Robert Phillips7c525e62018-06-12 10:11:12 -0400245 return Helper::FactoryHelper<NonAAFillRectPerspectiveOp>(context, std::move(paint),
246 viewMatrix, rect,
Brian Salomonac70f842017-05-08 10:43:33 -0400247 localRect, localMatrix, aaType,
248 stencilSettings);
249 }
250
251 NonAAFillRectPerspectiveOp() = delete;
252
253 NonAAFillRectPerspectiveOp(const Helper::MakeArgs& args, GrColor color,
254 const SkMatrix& viewMatrix, const SkRect& rect,
255 const SkRect* localRect, const SkMatrix* localMatrix,
256 GrAAType aaType, const GrUserStencilSettings* stencilSettings)
257 : INHERITED(ClassID())
258 , fHelper(args, aaType, stencilSettings)
259 , fViewMatrix(viewMatrix) {
260 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
261 RectInfo& info = fRects.push_back();
262 info.fColor = color;
263 info.fRect = rect;
264 fHasLocalRect = SkToBool(localRect);
265 fHasLocalMatrix = SkToBool(localMatrix);
266 if (fHasLocalMatrix) {
267 fLocalMatrix = *localMatrix;
268 }
269 if (fHasLocalRect) {
270 info.fLocalRect = *localRect;
271 }
272 this->setTransformedBounds(rect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
273 }
274
275 const char* name() const override { return "NonAAFillRectPerspectiveOp"; }
276
Robert Phillipsf1748f52017-09-14 14:11:24 -0400277 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400278 fHelper.visitProxies(func);
279 }
280
Brian Salomonac70f842017-05-08 10:43:33 -0400281 SkString dumpInfo() const override {
282 SkString str;
283 str.appendf("# combined: %d\n", fRects.count());
284 for (int i = 0; i < fRects.count(); ++i) {
Mike Klein1d746202018-01-25 17:32:51 -0500285 const RectInfo& geo = fRects[i];
Brian Salomonac70f842017-05-08 10:43:33 -0400286 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
287 geo.fColor, geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight,
288 geo.fRect.fBottom);
289 }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400290 str += fHelper.dumpInfo();
291 str += INHERITED::dumpInfo();
Brian Salomonac70f842017-05-08 10:43:33 -0400292 return str;
293 }
294
Brian Osman532b3f92018-07-11 10:02:07 -0400295 RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400296 GrColor* color = &fRects.front().fColor;
Brian Osman532b3f92018-07-11 10:02:07 -0400297 return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
Brian Salomonac70f842017-05-08 10:43:33 -0400298 }
299
300 FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
301
302 DEFINE_OP_CLASS_ID
303
304private:
Brian Salomon91326c32017-08-09 16:02:19 -0400305 void onPrepareDraws(Target* target) override {
Brian Salomonac70f842017-05-08 10:43:33 -0400306 sk_sp<GrGeometryProcessor> gp = make_perspective_gp(
307 fViewMatrix, fHasLocalRect, fHasLocalMatrix ? &fLocalMatrix : nullptr);
308 if (!gp) {
309 SkDebugf("Couldn't create GrGeometryProcessor\n");
310 return;
311 }
Brian Salomon92be2f72018-06-19 14:33:47 -0400312 size_t vertexStride = fHasLocalRect
313 ? sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
314 : sizeof(GrDefaultGeoProcFactory::PositionColorAttr);
315 SkASSERT(vertexStride == gp->debugOnly_vertexStride());
Brian Salomonac70f842017-05-08 10:43:33 -0400316
Brian Salomonac70f842017-05-08 10:43:33 -0400317 int rectCount = fRects.count();
318
Brian Salomond28a79d2017-10-16 13:01:07 -0400319 sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
Chris Dalton3809bab2017-06-13 10:55:06 -0600320 PatternHelper helper(GrPrimitiveType::kTriangles);
Chris Daltonbca46e22017-05-15 11:03:26 -0600321 void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
322 kIndicesPerRect, rectCount);
Brian Salomonac70f842017-05-08 10:43:33 -0400323 if (!vertices || !indexBuffer) {
324 SkDebugf("Could not allocate vertices\n");
325 return;
326 }
327
328 for (int i = 0; i < rectCount; i++) {
329 const RectInfo& info = fRects[i];
330 intptr_t verts =
331 reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
332 if (fHasLocalRect) {
333 GrQuad quad(info.fLocalRect);
334 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, &quad);
335 } else {
336 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, nullptr);
337 }
338 }
Brian Salomon49348902018-06-26 09:12:38 -0400339 auto pipe = fHelper.makePipeline(target);
340 helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
Brian Salomonac70f842017-05-08 10:43:33 -0400341 }
342
343 bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
344 NonAAFillRectPerspectiveOp* that = t->cast<NonAAFillRectPerspectiveOp>();
345 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
346 return false;
347 }
348
349 // We could combine across perspective vm changes if we really wanted to.
350 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
351 return false;
352 }
353 if (fHasLocalRect != that->fHasLocalRect) {
354 return false;
355 }
356 if (fHasLocalMatrix && !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
357 return false;
358 }
359
360 fRects.push_back_n(that->fRects.count(), that->fRects.begin());
361 this->joinBounds(*that);
362 return true;
363 }
364
365 struct RectInfo {
366 SkRect fRect;
367 GrColor fColor;
368 SkRect fLocalRect;
369 };
370
371 SkSTArray<1, RectInfo, true> fRects;
372 Helper fHelper;
373 bool fHasLocalMatrix;
374 bool fHasLocalRect;
375 SkMatrix fLocalMatrix;
376 SkMatrix fViewMatrix;
377
378 typedef GrMeshDrawOp INHERITED;
379};
380
381} // anonymous namespace
382
Brian Salomonbaaf4392017-06-15 09:59:23 -0400383namespace GrRectOpFactory {
bsalomonb8cbd202016-06-30 13:09:48 -0700384
Robert Phillips7c525e62018-06-12 10:11:12 -0400385std::unique_ptr<GrDrawOp> MakeNonAAFill(GrContext* context,
386 GrPaint&& paint,
387 const SkMatrix& viewMatrix,
388 const SkRect& rect,
389 GrAAType aaType,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400390 const GrUserStencilSettings* stencilSettings) {
391 if (viewMatrix.hasPerspective()) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400392 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
393 nullptr, nullptr, aaType, stencilSettings);
Brian Salomon1ec03f32017-06-14 09:49:26 -0400394 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400395 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, nullptr, nullptr,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400396 aaType, stencilSettings);
397 }
398}
399
Robert Phillips7c525e62018-06-12 10:11:12 -0400400std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix(
401 GrContext* context,
402 GrPaint&& paint,
403 const SkMatrix& viewMatrix,
404 const SkMatrix& localMatrix,
405 const SkRect& rect,
406 GrAAType aaType,
407 const GrUserStencilSettings* stencilSettings) {
408 if (viewMatrix.hasPerspective() || localMatrix.hasPerspective()) {
409 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
410 nullptr, &localMatrix, aaType, stencilSettings);
411 } else {
412 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, nullptr,
413 &localMatrix, aaType, stencilSettings);
414 }
415}
416
417std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrContext* context,
418 GrPaint&& paint,
419 const SkMatrix& viewMatrix,
420 const SkRect& rect,
421 const SkRect& localRect,
Brian Salomonbaaf4392017-06-15 09:59:23 -0400422 GrAAType aaType) {
423 if (viewMatrix.hasPerspective()) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400424 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
425 &localRect, nullptr, aaType, nullptr);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400426 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400427 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, &localRect,
428 nullptr, aaType, nullptr);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400429 }
430}
431
432} // namespace GrRectOpFactory
joshualitt9c80b5f2015-08-13 10:05:51 -0700433
434///////////////////////////////////////////////////////////////////////////////////////////////////
Brian Salomon17726632017-05-12 14:09:46 -0400435
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400436#if GR_TEST_UTILS
437
Brian Salomon17726632017-05-12 14:09:46 -0400438GR_DRAW_OP_TEST_DEFINE(NonAAFillRectOp) {
439 SkRect rect = GrTest::TestRect(random);
440 SkRect localRect = GrTest::TestRect(random);
441 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
442 SkMatrix localMatrix = GrTest::TestMatrix(random);
Brian Salomon17726632017-05-12 14:09:46 -0400443 const GrUserStencilSettings* stencil = GrGetRandomStencil(random, context);
444 GrAAType aaType = GrAAType::kNone;
445 if (fsaaType == GrFSAAType::kUnifiedMSAA) {
446 aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone;
447 }
Brian Salomonbaaf4392017-06-15 09:59:23 -0400448 const SkRect* lr = random->nextBool() ? &localRect : nullptr;
449 const SkMatrix* lm = random->nextBool() ? &localMatrix : nullptr;
450 if (viewMatrix.hasPerspective() || (lm && lm->hasPerspective())) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400451 return NonAAFillRectPerspectiveOp::Make(context, std::move(paint), viewMatrix, rect,
452 lr, lm, aaType, stencil);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400453 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400454 return NonAAFillRectOp::Make(context, std::move(paint), viewMatrix, rect,
455 lr, lm, aaType, stencil);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400456 }
Brian Salomon17726632017-05-12 14:09:46 -0400457}
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400458
459#endif