blob: 098c6bdae49e6060172bc2b5f80b0c09e8592faa [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
bsalomon75398562015-08-17 12:55:38 -070010#include "GrBatchFlushState.h"
joshualitt37eb1842015-08-12 06:36:57 -070011#include "GrColor.h"
joshualitt9ff64252015-08-10 09:03:51 -070012#include "GrDefaultGeoProcFactory.h"
13#include "GrResourceKey.h"
14#include "GrResourceProvider.h"
joshualitt37eb1842015-08-12 06:36:57 -070015#include "GrTypes.h"
bsalomon16b99132015-08-13 14:55:50 -070016#include "GrVertexBatch.h"
joshualitt37eb1842015-08-12 06:36:57 -070017#include "SkMatrix.h"
18#include "SkRect.h"
joshualitt9ff64252015-08-10 09:03:51 -070019
20GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
21
22static void set_inset_fan(SkPoint* pts, size_t stride,
23 const SkRect& r, SkScalar dx, SkScalar dy) {
24 pts->setRectFan(r.fLeft + dx, r.fTop + dy,
25 r.fRight - dx, r.fBottom - dy, stride);
26}
27
joshualitt27801bf2015-08-12 12:52:47 -070028static const int kNumAAFillRectsInIndexBuffer = 256;
29static const int kVertsPerAAFillRect = 8;
30static const int kIndicesPerAAFillRect = 30;
31
32const GrIndexBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
33 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
34
35 static const uint16_t gFillAARectIdx[] = {
36 0, 1, 5, 5, 4, 0,
37 1, 2, 6, 6, 5, 1,
38 2, 3, 7, 7, 6, 2,
39 3, 0, 4, 4, 7, 3,
40 4, 5, 6, 6, 7, 4,
41 };
42 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect);
43 return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx,
44 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect,
45 gAAFillRectIndexBufferKey);
46}
47
joshualitt147dc062015-08-12 11:51:46 -070048/*
49 * AAFillRectBatch is templated to optionally allow the insertion of an additional
50 * attribute for explicit local coordinates.
51 * To use this template, an implementation must define the following static functions:
52 * A Geometry struct
53 *
54 * bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs,
55 * bool usesLocalCoords)
56 *
57 * GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType()
58 *
59 * bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage,
60 * bool usesLocalCoords)
61 *
62 * void FillInAttributes(intptr_t startVertex, size_t vertexStride,
63 * SkPoint* fan0Position, const Geometry&)
64 */
65template <typename Base>
bsalomonabd30f52015-08-13 13:34:48 -070066class AAFillRectBatch : public GrVertexBatch {
joshualitt37eb1842015-08-12 06:36:57 -070067public:
joshualitt147dc062015-08-12 11:51:46 -070068 typedef typename Base::Geometry Geometry;
joshualitt9ff64252015-08-10 09:03:51 -070069
joshualitt147dc062015-08-12 11:51:46 -070070 static AAFillRectBatch* Create() {
71 return SkNEW(AAFillRectBatch);
joshualitt9ff64252015-08-10 09:03:51 -070072 }
73
joshualitt37eb1842015-08-12 06:36:57 -070074 const char* name() const override { return "AAFillRectBatch"; }
joshualitt9ff64252015-08-10 09:03:51 -070075
joshualitt37eb1842015-08-12 06:36:57 -070076 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
77 // When this is called on a batch, there is only one geometry bundle
78 out->setKnownFourComponents(fGeoData[0].fColor);
joshualitt9ff64252015-08-10 09:03:51 -070079 }
80
joshualitt37eb1842015-08-12 06:36:57 -070081 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
82 out->setUnknownSingleComponent();
joshualitt9ff64252015-08-10 09:03:51 -070083 }
84
joshualitt37eb1842015-08-12 06:36:57 -070085 void initBatchTracker(const GrPipelineOptimizations& opt) override {
86 // Handle any color overrides
87 if (!opt.readsColor()) {
88 fGeoData[0].fColor = GrColor_ILLEGAL;
89 }
90 opt.getOverrideColorIfSet(&fGeoData[0].fColor);
91
92 // setup batch properties
93 fBatch.fColorIgnored = !opt.readsColor();
94 fBatch.fColor = fGeoData[0].fColor;
95 fBatch.fUsesLocalCoords = opt.readsLocalCoords();
96 fBatch.fCoverageIgnored = !opt.readsCoverage();
97 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
joshualitt9ff64252015-08-10 09:03:51 -070098 }
99
bsalomon75398562015-08-17 12:55:38 -0700100 void onPrepareDraws(Target* target) override {
joshualitt37eb1842015-08-12 06:36:57 -0700101 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
joshualitt9ff64252015-08-10 09:03:51 -0700102
joshualitt147dc062015-08-12 11:51:46 -0700103 SkAutoTUnref<const GrGeometryProcessor> gp(CreateFillRectGP(canTweakAlphaForCoverage,
104 this->viewMatrix(),
105 this->usesLocalCoords(),
106 Base::LocalCoordsType(),
107 this->coverageIgnored()));
joshualitt37eb1842015-08-12 06:36:57 -0700108 if (!gp) {
109 SkDebugf("Couldn't create GrGeometryProcessor\n");
110 return;
111 }
joshualitt9ff64252015-08-10 09:03:51 -0700112
bsalomon75398562015-08-17 12:55:38 -0700113 target->initDraw(gp, this->pipeline());
joshualitt9ff64252015-08-10 09:03:51 -0700114
joshualitt37eb1842015-08-12 06:36:57 -0700115 size_t vertexStride = gp->getVertexStride();
joshualitt147dc062015-08-12 11:51:46 -0700116 SkASSERT(Base::StrideCheck(vertexStride, canTweakAlphaForCoverage,
117 this->usesLocalCoords()));
joshualitt37eb1842015-08-12 06:36:57 -0700118 int instanceCount = fGeoData.count();
joshualitt9ff64252015-08-10 09:03:51 -0700119
bsalomon75398562015-08-17 12:55:38 -0700120 SkAutoTUnref<const GrIndexBuffer> indexBuffer(get_index_buffer(target->resourceProvider()));
joshualitt37eb1842015-08-12 06:36:57 -0700121 InstancedHelper helper;
bsalomon75398562015-08-17 12:55:38 -0700122 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
joshualitt37eb1842015-08-12 06:36:57 -0700123 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 }
bsalomon75398562015-08-17 12:55:38 -0700137 helper.recordDraw(target);
joshualitt37eb1842015-08-12 06:36:57 -0700138 }
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);
joshualitta61c8172015-08-17 10:51:22 -0700253
254 // The coverage offset is always the last vertex attribute
255 intptr_t coverageOffset = vertexStride - sizeof(GrColor) - sizeof(SkPoint);
joshualitt37eb1842015-08-12 06:36:57 -0700256 for (int i = 0; i < 4; ++i) {
257 if (tweakAlphaForCoverage) {
258 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
259 } else {
joshualitt147dc062015-08-12 11:51:46 -0700260 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor;
joshualitta61c8172015-08-17 10:51:22 -0700261 *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = 0;
joshualitt37eb1842015-08-12 06:36:57 -0700262 }
263 }
264
265 int scale;
266 if (inset < SK_ScalarHalf) {
267 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
268 SkASSERT(scale >= 0 && scale <= 255);
269 } else {
270 scale = 0xff;
271 }
272
273 verts += 4 * vertexStride;
274
275 float innerCoverage = GrNormalizeByteToFloat(scale);
joshualitt147dc062015-08-12 11:51:46 -0700276 GrColor scaledColor = (0xff == scale) ? args.fColor : SkAlphaMulQ(args.fColor, scale);
joshualitt37eb1842015-08-12 06:36:57 -0700277
278 for (int i = 0; i < 4; ++i) {
279 if (tweakAlphaForCoverage) {
280 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
281 } else {
joshualitt147dc062015-08-12 11:51:46 -0700282 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor;
joshualitt37eb1842015-08-12 06:36:57 -0700283 *reinterpret_cast<float*>(verts + i * vertexStride +
joshualitta61c8172015-08-17 10:51:22 -0700284 coverageOffset) = innerCoverage;
joshualitt37eb1842015-08-12 06:36:57 -0700285 }
joshualitt9ff64252015-08-10 09:03:51 -0700286 }
287 }
288
joshualitt147dc062015-08-12 11:51:46 -0700289 static const GrGeometryProcessor* CreateFillRectGP(
290 bool tweakAlphaForCoverage,
291 const SkMatrix& viewMatrix,
292 bool usesLocalCoords,
293 GrDefaultGeoProcFactory::LocalCoords::Type localCoordsType,
294 bool coverageIgnored) {
295 using namespace GrDefaultGeoProcFactory;
296
297 Color color(Color::kAttribute_Type);
298 Coverage::Type coverageType;
299 // TODO remove coverage if coverage is ignored
300 /*if (coverageIgnored) {
301 coverageType = Coverage::kNone_Type;
302 } else*/ if (tweakAlphaForCoverage) {
303 coverageType = Coverage::kSolid_Type;
304 } else {
305 coverageType = Coverage::kAttribute_Type;
306 }
307 Coverage coverage(coverageType);
308
309 // We assume the caller has inverted the viewmatrix
joshualitt147dc062015-08-12 11:51:46 -0700310 if (LocalCoords::kHasExplicit_Type == localCoordsType) {
joshualitt27801bf2015-08-12 12:52:47 -0700311 LocalCoords localCoords(localCoordsType);
joshualitt147dc062015-08-12 11:51:46 -0700312 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I());
313 } else {
joshualitt27801bf2015-08-12 12:52:47 -0700314 LocalCoords localCoords(usesLocalCoords ? localCoordsType : LocalCoords::kUnused_Type);
joshualitt147dc062015-08-12 11:51:46 -0700315 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
316 }
317 }
318
joshualitt37eb1842015-08-12 06:36:57 -0700319 struct BatchTracker {
320 GrColor fColor;
321 bool fUsesLocalCoords;
322 bool fColorIgnored;
323 bool fCoverageIgnored;
324 bool fCanTweakAlphaForCoverage;
325 };
joshualitt9ff64252015-08-10 09:03:51 -0700326
joshualitt37eb1842015-08-12 06:36:57 -0700327 BatchTracker fBatch;
328 SkSTArray<1, Geometry, true> fGeoData;
329};
joshualitt9ff64252015-08-10 09:03:51 -0700330
joshualitt147dc062015-08-12 11:51:46 -0700331class AAFillRectBatchNoLocalMatrixImp {
332public:
333 struct Geometry {
334 SkMatrix fViewMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700335 SkRect fRect;
joshualitt147dc062015-08-12 11:51:46 -0700336 SkRect fDevRect;
337 GrColor fColor;
338 };
339
340 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs,
341 bool usesLocalCoords) {
342 // We apply the viewmatrix to the rect points on the cpu. However, if the pipeline uses
343 // local coords then we won't be able to batch. We could actually upload the viewmatrix
344 // using vertex attributes in these cases, but haven't investigated that
345 return !usesLocalCoords || mine.cheapEqualTo(theirs);
346 }
347
348 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
349 return GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type;
350 }
351
352 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage,
353 bool usesLocalCoords) {
354 return canTweakAlphaForCoverage ?
355 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
356 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr);
357 }
358
359 inline static void FillInAttributes(intptr_t, size_t, SkPoint*, const Geometry&) {}
360};
361
362class AAFillRectBatchLocalMatrixImp {
363public:
364 struct Geometry {
365 SkMatrix fViewMatrix;
366 SkMatrix fLocalMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700367 SkRect fRect;
joshualitt147dc062015-08-12 11:51:46 -0700368 SkRect fDevRect;
369 GrColor fColor;
370 };
371
372 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs,
373 bool usesLocalCoords) {
374 return true;
375 }
376
377 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
378 return GrDefaultGeoProcFactory::LocalCoords::kHasExplicit_Type;
379 }
380
381 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage,
382 bool usesLocalCoords) {
383 // Whomever created us should not have done so if there are no local coords
joshualitt147dc062015-08-12 11:51:46 -0700384 return canTweakAlphaForCoverage ?
385 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
386 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage);
387 }
388
389 inline static void FillInAttributes(intptr_t vertices, size_t vertexStride,
390 SkPoint* fan0Pos, const Geometry& args) {
391 SkMatrix invViewMatrix;
392 if (!args.fViewMatrix.invert(&invViewMatrix)) {
393 SkASSERT(false);
394 invViewMatrix = SkMatrix::I();
395 }
396 SkMatrix localCoordMatrix;
397 localCoordMatrix.setConcat(args.fLocalMatrix, invViewMatrix);
joshualitta61c8172015-08-17 10:51:22 -0700398 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(vertices + sizeof(SkPoint) + sizeof(GrColor));
joshualitt147dc062015-08-12 11:51:46 -0700399 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
400 }
401};
402
403typedef AAFillRectBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalMatrix;
404typedef AAFillRectBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatrix;
405
joshualitt37eb1842015-08-12 06:36:57 -0700406namespace GrAAFillRectBatch {
joshualitt9ff64252015-08-10 09:03:51 -0700407
bsalomonabd30f52015-08-13 13:34:48 -0700408GrDrawBatch* Create(GrColor color,
409 const SkMatrix& viewMatrix,
410 const SkRect& rect,
411 const SkRect& devRect) {
joshualitt147dc062015-08-12 11:51:46 -0700412 AAFillRectBatchNoLocalMatrix* batch = AAFillRectBatchNoLocalMatrix::Create();
413 AAFillRectBatchNoLocalMatrix::Geometry& geo = *batch->geometry();
414 geo.fColor = color;
415 geo.fViewMatrix = viewMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700416 geo.fRect = rect;
joshualitt147dc062015-08-12 11:51:46 -0700417 geo.fDevRect = devRect;
418 batch->init();
419 return batch;
420}
421
bsalomonabd30f52015-08-13 13:34:48 -0700422GrDrawBatch* Create(GrColor color,
423 const SkMatrix& viewMatrix,
424 const SkMatrix& localMatrix,
425 const SkRect& rect,
426 const SkRect& devRect) {
joshualitt147dc062015-08-12 11:51:46 -0700427 AAFillRectBatchLocalMatrix* batch = AAFillRectBatchLocalMatrix::Create();
428 AAFillRectBatchLocalMatrix::Geometry& geo = *batch->geometry();
429 geo.fColor = color;
430 geo.fViewMatrix = viewMatrix;
431 geo.fLocalMatrix = localMatrix;
joshualitt40ac15a2015-08-14 08:45:39 -0700432 geo.fRect = rect;
joshualitt147dc062015-08-12 11:51:46 -0700433 geo.fDevRect = devRect;
434 batch->init();
435 return batch;
joshualitt9ff64252015-08-10 09:03:51 -0700436}
437
joshualitt37eb1842015-08-12 06:36:57 -0700438};
439
joshualitt9ff64252015-08-10 09:03:51 -0700440///////////////////////////////////////////////////////////////////////////////////////////////////
441
442#ifdef GR_TEST_UTILS
443
444#include "GrBatchTest.h"
445
bsalomonabd30f52015-08-13 13:34:48 -0700446DRAW_BATCH_TEST_DEFINE(AAFillRectBatch) {
joshualitt090ae8e2015-08-14 09:01:21 -0700447 GrColor color = GrRandomColor(random);
448 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
449 SkRect rect = GrTest::TestRect(random);
450 SkRect devRect = GrTest::TestRect(random);
451 return GrAAFillRectBatch::Create(color, viewMatrix, rect, devRect);
joshualitt147dc062015-08-12 11:51:46 -0700452}
453
bsalomonabd30f52015-08-13 13:34:48 -0700454DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) {
joshualitt090ae8e2015-08-14 09:01:21 -0700455 GrColor color = GrRandomColor(random);
456 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
457 SkMatrix localMatrix = GrTest::TestMatrix(random);
458 SkRect rect = GrTest::TestRect(random);
459 SkRect devRect = GrTest::TestRect(random);
460 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRect);
joshualitt9ff64252015-08-10 09:03:51 -0700461}
462
463#endif