blob: 94cc5ce635397eda7a6d3a16684874703d8ebd13 [file] [log] [blame]
joshualitt9ff64252015-08-10 09:03:51 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrAAFillRectBatch.h"
9
joshualitt37eb1842015-08-12 06:36:57 -070010#include "GrColor.h"
joshualitt9ff64252015-08-10 09:03:51 -070011#include "GrDefaultGeoProcFactory.h"
12#include "GrResourceKey.h"
13#include "GrResourceProvider.h"
joshualitt37eb1842015-08-12 06:36:57 -070014#include "GrTypes.h"
bsalomon16b99132015-08-13 14:55:50 -070015#include "GrVertexBatch.h"
joshualitt37eb1842015-08-12 06:36:57 -070016#include "SkMatrix.h"
17#include "SkRect.h"
joshualitt9ff64252015-08-10 09:03:51 -070018
19GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
20
21static void set_inset_fan(SkPoint* pts, size_t stride,
22 const SkRect& r, SkScalar dx, SkScalar dy) {
23 pts->setRectFan(r.fLeft + dx, r.fTop + dy,
24 r.fRight - dx, r.fBottom - dy, stride);
25}
26
joshualitt27801bf2015-08-12 12:52:47 -070027static const int kNumAAFillRectsInIndexBuffer = 256;
28static const int kVertsPerAAFillRect = 8;
29static const int kIndicesPerAAFillRect = 30;
30
31const GrIndexBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
32 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
33
34 static const uint16_t gFillAARectIdx[] = {
35 0, 1, 5, 5, 4, 0,
36 1, 2, 6, 6, 5, 1,
37 2, 3, 7, 7, 6, 2,
38 3, 0, 4, 4, 7, 3,
39 4, 5, 6, 6, 7, 4,
40 };
41 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect);
42 return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx,
43 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect,
44 gAAFillRectIndexBufferKey);
45}
46
joshualitt147dc062015-08-12 11:51:46 -070047/*
48 * AAFillRectBatch is templated to optionally allow the insertion of an additional
49 * attribute for explicit local coordinates.
50 * To use this template, an implementation must define the following static functions:
51 * A Geometry struct
52 *
53 * bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs,
54 * bool usesLocalCoords)
55 *
56 * GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType()
57 *
58 * bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage,
59 * bool usesLocalCoords)
60 *
61 * void FillInAttributes(intptr_t startVertex, size_t vertexStride,
62 * SkPoint* fan0Position, const Geometry&)
63 */
64template <typename Base>
bsalomonabd30f52015-08-13 13:34:48 -070065class AAFillRectBatch : public GrVertexBatch {
joshualitt37eb1842015-08-12 06:36:57 -070066public:
joshualitt147dc062015-08-12 11:51:46 -070067 typedef typename Base::Geometry Geometry;
joshualitt9ff64252015-08-10 09:03:51 -070068
joshualitt147dc062015-08-12 11:51:46 -070069 static AAFillRectBatch* Create() {
70 return SkNEW(AAFillRectBatch);
joshualitt9ff64252015-08-10 09:03:51 -070071 }
72
joshualitt37eb1842015-08-12 06:36:57 -070073 const char* name() const override { return "AAFillRectBatch"; }
joshualitt9ff64252015-08-10 09:03:51 -070074
joshualitt37eb1842015-08-12 06:36:57 -070075 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
76 // When this is called on a batch, there is only one geometry bundle
77 out->setKnownFourComponents(fGeoData[0].fColor);
joshualitt9ff64252015-08-10 09:03:51 -070078 }
79
joshualitt37eb1842015-08-12 06:36:57 -070080 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
81 out->setUnknownSingleComponent();
joshualitt9ff64252015-08-10 09:03:51 -070082 }
83
joshualitt37eb1842015-08-12 06:36:57 -070084 void initBatchTracker(const GrPipelineOptimizations& opt) override {
85 // Handle any color overrides
86 if (!opt.readsColor()) {
87 fGeoData[0].fColor = GrColor_ILLEGAL;
88 }
89 opt.getOverrideColorIfSet(&fGeoData[0].fColor);
90
91 // setup batch properties
92 fBatch.fColorIgnored = !opt.readsColor();
93 fBatch.fColor = fGeoData[0].fColor;
94 fBatch.fUsesLocalCoords = opt.readsLocalCoords();
95 fBatch.fCoverageIgnored = !opt.readsCoverage();
96 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
joshualitt9ff64252015-08-10 09:03:51 -070097 }
98
joshualitt37eb1842015-08-12 06:36:57 -070099 void generateGeometry(GrBatchTarget* batchTarget) override {
100 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
joshualitt9ff64252015-08-10 09:03:51 -0700101
joshualitt147dc062015-08-12 11:51:46 -0700102 SkAutoTUnref<const GrGeometryProcessor> gp(CreateFillRectGP(canTweakAlphaForCoverage,
103 this->viewMatrix(),
104 this->usesLocalCoords(),
105 Base::LocalCoordsType(),
106 this->coverageIgnored()));
joshualitt37eb1842015-08-12 06:36:57 -0700107 if (!gp) {
108 SkDebugf("Couldn't create GrGeometryProcessor\n");
109 return;
110 }
joshualitt9ff64252015-08-10 09:03:51 -0700111
joshualitt37eb1842015-08-12 06:36:57 -0700112 batchTarget->initDraw(gp, this->pipeline());
joshualitt9ff64252015-08-10 09:03:51 -0700113
joshualitt37eb1842015-08-12 06:36:57 -0700114 size_t vertexStride = gp->getVertexStride();
joshualitt147dc062015-08-12 11:51:46 -0700115 SkASSERT(Base::StrideCheck(vertexStride, canTweakAlphaForCoverage,
116 this->usesLocalCoords()));
joshualitt37eb1842015-08-12 06:36:57 -0700117 int instanceCount = fGeoData.count();
joshualitt9ff64252015-08-10 09:03:51 -0700118
joshualitt27801bf2015-08-12 12:52:47 -0700119 SkAutoTUnref<const GrIndexBuffer> indexBuffer(get_index_buffer(
joshualitt37eb1842015-08-12 06:36:57 -0700120 batchTarget->resourceProvider()));
121 InstancedHelper helper;
122 void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, vertexStride,
123 indexBuffer, kVertsPerAAFillRect, kIndicesPerAAFillRect,
124 instanceCount);
125 if (!vertices || !indexBuffer) {
126 SkDebugf("Could not allocate vertices\n");
127 return;
128 }
129
130 for (int i = 0; i < instanceCount; i++) {
joshualitt37eb1842015-08-12 06:36:57 -0700131 this->generateAAFillRectGeometry(vertices,
132 i * kVertsPerAAFillRect * vertexStride,
133 vertexStride,
joshualitt147dc062015-08-12 11:51:46 -0700134 fGeoData[i],
joshualitt37eb1842015-08-12 06:36:57 -0700135 canTweakAlphaForCoverage);
136 }
joshualitt37eb1842015-08-12 06:36:57 -0700137 helper.issueDraw(batchTarget);
138 }
139
140 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
141
joshualitt147dc062015-08-12 11:51:46 -0700142 // to avoid even the initial copy of the struct, we have a getter for the first item which
143 // is used to seed the batch with its initial geometry. After seeding, the client should call
144 // init() so the Batch can initialize itself
145 Geometry* geometry() { return &fGeoData[0]; }
146 void init() {
147 const Geometry& geo = fGeoData[0];
148 this->setBounds(geo.fDevRect);
149 }
joshualitt37eb1842015-08-12 06:36:57 -0700150
joshualitt147dc062015-08-12 11:51:46 -0700151
152private:
153 AAFillRectBatch() {
154 this->initClassID<AAFillRectBatch<Base>>();
155
156 // Push back an initial geometry
157 fGeoData.push_back();
joshualitt37eb1842015-08-12 06:36:57 -0700158 }
159
joshualitt37eb1842015-08-12 06:36:57 -0700160 GrColor color() const { return fBatch.fColor; }
161 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
162 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; }
163 bool colorIgnored() const { return fBatch.fColorIgnored; }
164 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
165 bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
166
bsalomonc3021ed2015-08-12 11:28:11 -0700167 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
bsalomonabd30f52015-08-13 13:34:48 -0700168 AAFillRectBatch* that = t->cast<AAFillRectBatch>();
169 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
170 that->bounds(), caps)) {
joshualitt37eb1842015-08-12 06:36:57 -0700171 return false;
172 }
173
joshualitt147dc062015-08-12 11:51:46 -0700174 if (!Base::CanCombineLocalCoords(this->viewMatrix(), that->viewMatrix(),
175 this->usesLocalCoords())) {
joshualitt37eb1842015-08-12 06:36:57 -0700176 return false;
177 }
178
179 if (this->color() != that->color()) {
180 fBatch.fColor = GrColor_ILLEGAL;
181 }
182
183 // In the event of two batches, one who can tweak, one who cannot, we just fall back to
184 // not tweaking
185 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) {
186 fBatch.fCanTweakAlphaForCoverage = false;
187 }
188
189 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
190 this->joinBounds(that->bounds());
191 return true;
192 }
193
194 void generateAAFillRectGeometry(void* vertices,
195 size_t offset,
196 size_t vertexStride,
joshualitt147dc062015-08-12 11:51:46 -0700197 const Geometry& args,
joshualitt37eb1842015-08-12 06:36:57 -0700198 bool tweakAlphaForCoverage) const {
199 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
200
201 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
202 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
203
joshualitt147dc062015-08-12 11:51:46 -0700204 SkScalar inset = SkMinScalar(args.fDevRect.width(), SK_Scalar1);
205 inset = SK_ScalarHalf * SkMinScalar(inset, args.fDevRect.height());
joshualitt37eb1842015-08-12 06:36:57 -0700206
joshualitt147dc062015-08-12 11:51:46 -0700207 if (args.fViewMatrix.rectStaysRect()) {
208 set_inset_fan(fan0Pos, vertexStride, args.fDevRect, -SK_ScalarHalf, -SK_ScalarHalf);
209 set_inset_fan(fan1Pos, vertexStride, args.fDevRect, inset, inset);
joshualitt9ff64252015-08-10 09:03:51 -0700210 } else {
joshualitt37eb1842015-08-12 06:36:57 -0700211 // compute transformed (1, 0) and (0, 1) vectors
212 SkVector vec[2] = {
joshualitt147dc062015-08-12 11:51:46 -0700213 { args.fViewMatrix[SkMatrix::kMScaleX], args.fViewMatrix[SkMatrix::kMSkewY] },
214 { args.fViewMatrix[SkMatrix::kMSkewX], args.fViewMatrix[SkMatrix::kMScaleY] }
joshualitt37eb1842015-08-12 06:36:57 -0700215 };
216
217 vec[0].normalize();
218 vec[0].scale(SK_ScalarHalf);
219 vec[1].normalize();
220 vec[1].scale(SK_ScalarHalf);
221
222 // create the rotated rect
joshualitt40ac15a2015-08-14 08:45:39 -0700223 fan0Pos->setRectFan(args.fRect.fLeft, args.fRect.fTop,
224 args.fRect.fRight, args.fRect.fBottom, vertexStride);
225 args.fViewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
joshualitt37eb1842015-08-12 06:36:57 -0700226
227 // Now create the inset points and then outset the original
228 // rotated points
229
230 // TL
231 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
232 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1];
233 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
234 // BL
235 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
236 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1];
237 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
238 // BR
239 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
240 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1];
241 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
242 // TR
243 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
244 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1];
245 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
246 }
247
joshualitt147dc062015-08-12 11:51:46 -0700248 Base::FillInAttributes(verts, vertexStride, fan0Pos, args);
249
joshualitt37eb1842015-08-12 06:36:57 -0700250 // Make verts point to vertex color and then set all the color and coverage vertex attrs
251 // values.
252 verts += sizeof(SkPoint);
253 for (int i = 0; i < 4; ++i) {
254 if (tweakAlphaForCoverage) {
255 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
256 } else {
joshualitt147dc062015-08-12 11:51:46 -0700257 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor;
joshualitt37eb1842015-08-12 06:36:57 -0700258 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 0;
259 }
260 }
261
262 int scale;
263 if (inset < SK_ScalarHalf) {
264 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
265 SkASSERT(scale >= 0 && scale <= 255);
266 } else {
267 scale = 0xff;
268 }
269
270 verts += 4 * vertexStride;
271
272 float innerCoverage = GrNormalizeByteToFloat(scale);
joshualitt147dc062015-08-12 11:51:46 -0700273 GrColor scaledColor = (0xff == scale) ? args.fColor : SkAlphaMulQ(args.fColor, scale);
joshualitt37eb1842015-08-12 06:36:57 -0700274
275 for (int i = 0; i < 4; ++i) {
276 if (tweakAlphaForCoverage) {
277 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
278 } else {
joshualitt147dc062015-08-12 11:51:46 -0700279 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor;
joshualitt37eb1842015-08-12 06:36:57 -0700280 *reinterpret_cast<float*>(verts + i * vertexStride +
281 sizeof(GrColor)) = innerCoverage;
282 }
joshualitt9ff64252015-08-10 09:03:51 -0700283 }
284 }
285
joshualitt147dc062015-08-12 11:51:46 -0700286 static const GrGeometryProcessor* CreateFillRectGP(
287 bool tweakAlphaForCoverage,
288 const SkMatrix& viewMatrix,
289 bool usesLocalCoords,
290 GrDefaultGeoProcFactory::LocalCoords::Type localCoordsType,
291 bool coverageIgnored) {
292 using namespace GrDefaultGeoProcFactory;
293
294 Color color(Color::kAttribute_Type);
295 Coverage::Type coverageType;
296 // TODO remove coverage if coverage is ignored
297 /*if (coverageIgnored) {
298 coverageType = Coverage::kNone_Type;
299 } else*/ if (tweakAlphaForCoverage) {
300 coverageType = Coverage::kSolid_Type;
301 } else {
302 coverageType = Coverage::kAttribute_Type;
303 }
304 Coverage coverage(coverageType);
305
306 // We assume the caller has inverted the viewmatrix
joshualitt147dc062015-08-12 11:51:46 -0700307 if (LocalCoords::kHasExplicit_Type == localCoordsType) {
joshualitt27801bf2015-08-12 12:52:47 -0700308 LocalCoords localCoords(localCoordsType);
joshualitt147dc062015-08-12 11:51:46 -0700309 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I());
310 } else {
joshualitt27801bf2015-08-12 12:52:47 -0700311 LocalCoords localCoords(usesLocalCoords ? localCoordsType : LocalCoords::kUnused_Type);
joshualitt147dc062015-08-12 11:51:46 -0700312 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
313 }
314 }
315
joshualitt37eb1842015-08-12 06:36:57 -0700316 struct BatchTracker {
317 GrColor fColor;
318 bool fUsesLocalCoords;
319 bool fColorIgnored;
320 bool fCoverageIgnored;
321 bool fCanTweakAlphaForCoverage;
322 };
joshualitt9ff64252015-08-10 09:03:51 -0700323
joshualitt37eb1842015-08-12 06:36:57 -0700324 BatchTracker fBatch;
325 SkSTArray<1, Geometry, true> fGeoData;
326};
joshualitt9ff64252015-08-10 09:03:51 -0700327
joshualitt147dc062015-08-12 11:51:46 -0700328class AAFillRectBatchNoLocalMatrixImp {
329public:
330 struct Geometry {
331 SkMatrix fViewMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700332 SkRect fRect;
joshualitt147dc062015-08-12 11:51:46 -0700333 SkRect fDevRect;
334 GrColor fColor;
335 };
336
337 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs,
338 bool usesLocalCoords) {
339 // We apply the viewmatrix to the rect points on the cpu. However, if the pipeline uses
340 // local coords then we won't be able to batch. We could actually upload the viewmatrix
341 // using vertex attributes in these cases, but haven't investigated that
342 return !usesLocalCoords || mine.cheapEqualTo(theirs);
343 }
344
345 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
346 return GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type;
347 }
348
349 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage,
350 bool usesLocalCoords) {
351 return canTweakAlphaForCoverage ?
352 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
353 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr);
354 }
355
356 inline static void FillInAttributes(intptr_t, size_t, SkPoint*, const Geometry&) {}
357};
358
359class AAFillRectBatchLocalMatrixImp {
360public:
361 struct Geometry {
362 SkMatrix fViewMatrix;
363 SkMatrix fLocalMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700364 SkRect fRect;
joshualitt147dc062015-08-12 11:51:46 -0700365 SkRect fDevRect;
366 GrColor fColor;
367 };
368
369 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs,
370 bool usesLocalCoords) {
371 return true;
372 }
373
374 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
375 return GrDefaultGeoProcFactory::LocalCoords::kHasExplicit_Type;
376 }
377
378 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage,
379 bool usesLocalCoords) {
380 // Whomever created us should not have done so if there are no local coords
joshualitt147dc062015-08-12 11:51:46 -0700381 return canTweakAlphaForCoverage ?
382 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
383 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage);
384 }
385
386 inline static void FillInAttributes(intptr_t vertices, size_t vertexStride,
387 SkPoint* fan0Pos, const Geometry& args) {
388 SkMatrix invViewMatrix;
389 if (!args.fViewMatrix.invert(&invViewMatrix)) {
390 SkASSERT(false);
391 invViewMatrix = SkMatrix::I();
392 }
393 SkMatrix localCoordMatrix;
394 localCoordMatrix.setConcat(args.fLocalMatrix, invViewMatrix);
395 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(vertices + vertexStride - sizeof(SkPoint));
396 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
397 }
398};
399
400typedef AAFillRectBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalMatrix;
401typedef AAFillRectBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatrix;
402
joshualitt37eb1842015-08-12 06:36:57 -0700403namespace GrAAFillRectBatch {
joshualitt9ff64252015-08-10 09:03:51 -0700404
bsalomonabd30f52015-08-13 13:34:48 -0700405GrDrawBatch* Create(GrColor color,
406 const SkMatrix& viewMatrix,
407 const SkRect& rect,
408 const SkRect& devRect) {
joshualitt147dc062015-08-12 11:51:46 -0700409 AAFillRectBatchNoLocalMatrix* batch = AAFillRectBatchNoLocalMatrix::Create();
410 AAFillRectBatchNoLocalMatrix::Geometry& geo = *batch->geometry();
411 geo.fColor = color;
412 geo.fViewMatrix = viewMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700413 geo.fRect = rect;
joshualitt147dc062015-08-12 11:51:46 -0700414 geo.fDevRect = devRect;
415 batch->init();
416 return batch;
417}
418
bsalomonabd30f52015-08-13 13:34:48 -0700419GrDrawBatch* Create(GrColor color,
420 const SkMatrix& viewMatrix,
421 const SkMatrix& localMatrix,
422 const SkRect& rect,
423 const SkRect& devRect) {
joshualitt147dc062015-08-12 11:51:46 -0700424 AAFillRectBatchLocalMatrix* batch = AAFillRectBatchLocalMatrix::Create();
425 AAFillRectBatchLocalMatrix::Geometry& geo = *batch->geometry();
426 geo.fColor = color;
427 geo.fViewMatrix = viewMatrix;
428 geo.fLocalMatrix = localMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700429 geo.fRect = rect;
joshualitt147dc062015-08-12 11:51:46 -0700430 geo.fDevRect = devRect;
431 batch->init();
432 return batch;
joshualitt9ff64252015-08-10 09:03:51 -0700433}
434
joshualitt37eb1842015-08-12 06:36:57 -0700435};
436
joshualitt9ff64252015-08-10 09:03:51 -0700437///////////////////////////////////////////////////////////////////////////////////////////////////
438
439#ifdef GR_TEST_UTILS
440
441#include "GrBatchTest.h"
442
bsalomonabd30f52015-08-13 13:34:48 -0700443DRAW_BATCH_TEST_DEFINE(AAFillRectBatch) {
joshualitt090ae8e2015-08-14 09:01:21 -0700444 GrColor color = GrRandomColor(random);
445 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
446 SkRect rect = GrTest::TestRect(random);
447 SkRect devRect = GrTest::TestRect(random);
448 return GrAAFillRectBatch::Create(color, viewMatrix, rect, devRect);
joshualitt147dc062015-08-12 11:51:46 -0700449}
450
bsalomonabd30f52015-08-13 13:34:48 -0700451DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) {
joshualitt090ae8e2015-08-14 09:01:21 -0700452 GrColor color = GrRandomColor(random);
453 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
454 SkMatrix localMatrix = GrTest::TestMatrix(random);
455 SkRect rect = GrTest::TestRect(random);
456 SkRect devRect = GrTest::TestRect(random);
457 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRect);
joshualitt9ff64252015-08-10 09:03:51 -0700458}
459
460#endif