OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrBWFillRectBatch.h" | 8 #include "GrBWFillRectBatch.h" |
9 | 9 |
10 #include "GrBatchTarget.h" | 10 #include "GrBatchTarget.h" |
11 #include "GrColor.h" | 11 #include "GrColor.h" |
12 #include "GrDefaultGeoProcFactory.h" | 12 #include "GrDefaultGeoProcFactory.h" |
13 #include "GrPrimitiveProcessor.h" | 13 #include "GrPrimitiveProcessor.h" |
14 #include "GrVertexBatch.h" | 14 #include "GrVertexBatch.h" |
15 | 15 |
16 class GrBatchTarget; | 16 class GrBatchTarget; |
17 class SkMatrix; | 17 class SkMatrix; |
18 struct SkRect; | 18 struct SkRect; |
19 | 19 |
20 /* | |
21 * BWFillRectBatch is templated to optionally allow the insertion of an addition al | |
22 * attribute for explicit local coordinates and also to handle an optional local Matrix | |
23 * To use this template, an implementation must define the following static func tions: | |
24 * A Geometry struct | |
25 * | |
26 * bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs, | |
27 * bool usesLocalCoords) | |
28 * | |
29 * GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() | |
30 * | |
31 * bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage, | |
32 * bool usesLocalCoords) | |
33 * | |
34 * void FillInAttributes(intptr_t startVertex, size_t vertexStride, | |
35 * SkPoint* fan0Position, const Geometry&) | |
36 * | |
37 * const GrGeometryProcessor* CreateGP(const Geometry& geo, | |
38 * const GrDefaultGeoProcFactory::Color& color, | |
39 * const GrDefaultGeoProcFactory::Covera ge& coverage) | |
40 */ | |
41 template <typename Base> | |
bsalomon
2015/08/14 14:37:48
I don't Base is a good a name for the template par
| |
20 class BWFillRectBatch : public GrVertexBatch { | 42 class BWFillRectBatch : public GrVertexBatch { |
21 public: | 43 public: |
22 struct Geometry { | 44 typedef typename Base::Geometry Geometry; |
23 SkMatrix fViewMatrix; | |
24 SkRect fRect; | |
25 SkRect fLocalRect; | |
26 SkMatrix fLocalMatrix; | |
27 GrColor fColor; | |
28 bool fHasLocalRect; | |
29 bool fHasLocalMatrix; | |
30 }; | |
31 | 45 |
32 static GrDrawBatch* Create(const Geometry& geometry) { | 46 static BWFillRectBatch* Create() { |
33 return SkNEW_ARGS(BWFillRectBatch, (geometry)); | 47 return SkNEW(BWFillRectBatch); |
34 } | 48 } |
35 | 49 |
36 const char* name() const override { return "RectBatch"; } | 50 const char* name() const override { return "RectBatch"; } |
37 | 51 |
38 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 52 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
39 // When this is called on a batch, there is only one geometry bundle | 53 // When this is called on a batch, there is only one geometry bundle |
40 out->setKnownFourComponents(fGeoData[0].fColor); | 54 out->setKnownFourComponents(fGeoData[0].fColor); |
41 } | 55 } |
42 | 56 |
43 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 57 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
44 out->setKnownSingleComponent(0xff); | 58 out->setKnownSingleComponent(0xff); |
45 } | 59 } |
46 | 60 |
47 void initBatchTracker(const GrPipelineOptimizations& init) override { | 61 void initBatchTracker(const GrPipelineOptimizations& init) override { |
48 // Handle any color overrides | 62 // Handle any color overrides |
49 if (!init.readsColor()) { | 63 if (!init.readsColor()) { |
50 fGeoData[0].fColor = GrColor_ILLEGAL; | 64 fGeoData[0].fColor = GrColor_ILLEGAL; |
51 } | 65 } |
52 init.getOverrideColorIfSet(&fGeoData[0].fColor); | 66 init.getOverrideColorIfSet(&fGeoData[0].fColor); |
53 | 67 |
54 // setup batch properties | 68 // setup batch properties |
55 fBatch.fColorIgnored = !init.readsColor(); | 69 fBatch.fColorIgnored = !init.readsColor(); |
56 fBatch.fColor = fGeoData[0].fColor; | 70 fBatch.fColor = fGeoData[0].fColor; |
57 fBatch.fUsesLocalCoords = init.readsLocalCoords(); | 71 fBatch.fUsesLocalCoords = init.readsLocalCoords(); |
58 fBatch.fCoverageIgnored = !init.readsCoverage(); | 72 fBatch.fCoverageIgnored = !init.readsCoverage(); |
59 } | 73 } |
60 | 74 |
61 void generateGeometry(GrBatchTarget* batchTarget) override { | 75 void generateGeometry(GrBatchTarget* batchTarget) override { |
62 SkAutoTUnref<const GrGeometryProcessor> gp(this->createRectGP()); | 76 SkAutoTUnref<const GrGeometryProcessor> gp(this->createGP(fGeoData[0])); |
63 if (!gp) { | 77 if (!gp) { |
64 SkDebugf("Could not create GrGeometryProcessor\n"); | 78 SkDebugf("Could not create GrGeometryProcessor\n"); |
65 return; | 79 return; |
66 } | 80 } |
67 | 81 |
68 batchTarget->initDraw(gp, this->pipeline()); | 82 batchTarget->initDraw(gp, this->pipeline()); |
69 | 83 |
70 int instanceCount = fGeoData.count(); | 84 int instanceCount = fGeoData.count(); |
71 size_t vertexStride = gp->getVertexStride(); | 85 size_t vertexStride = gp->getVertexStride(); |
72 SkASSERT(this->hasLocalRect() ? | 86 SkASSERT(Base::StrideCheck(vertexStride)); |
73 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordAttr) : | |
74 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr)); | |
75 QuadHelper helper; | 87 QuadHelper helper; |
76 void* vertices = helper.init(batchTarget, vertexStride, instanceCount); | 88 void* vertices = helper.init(batchTarget, vertexStride, instanceCount); |
77 | 89 |
78 if (!vertices) { | 90 if (!vertices) { |
79 return; | 91 return; |
80 } | 92 } |
81 | 93 |
82 for (int i = 0; i < instanceCount; i++) { | 94 for (int i = 0; i < instanceCount; i++) { |
83 const Geometry& geom = fGeoData[i]; | 95 const Geometry& geom = fGeoData[i]; |
84 | 96 |
85 intptr_t offset = reinterpret_cast<intptr_t>(vertices) + | 97 intptr_t offset = reinterpret_cast<intptr_t>(vertices) + |
86 kVerticesPerQuad * i * vertexStride; | 98 kVerticesPerQuad * i * vertexStride; |
87 SkPoint* positions = reinterpret_cast<SkPoint*>(offset); | 99 SkPoint* positions = reinterpret_cast<SkPoint*>(offset); |
88 | 100 |
89 positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop, | 101 positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop, |
90 geom.fRect.fRight, geom.fRect.fBottom, vertexS tride); | 102 geom.fRect.fRight, geom.fRect.fBottom, vertexS tride); |
robertphillips
2015/08/14 14:42:57
space before '(' ?
| |
103 // TODO we are mapping the rect twice(three times in the GrDrawConte xt::drawRect case) | |
91 geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerti cesPerQuad); | 104 geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerti cesPerQuad); |
92 | 105 |
93 // TODO we should only do this if local coords are being read | 106 Base::FillInAttributes(offset, vertexStride, geom); |
94 if (geom.fHasLocalRect) { | |
95 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor ); | |
96 SkPoint* coords = reinterpret_cast<SkPoint*>(offset + kLocalOffs et); | |
97 coords->setRectFan(geom.fLocalRect.fLeft, geom.fLocalRect.fTop, | |
98 geom.fLocalRect.fRight, geom.fLocalRect.fBott om, | |
99 vertexStride); | |
100 if (geom.fHasLocalMatrix) { | |
101 geom.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPerQuad); | |
102 } | |
103 } | |
104 | 107 |
105 static const int kColorOffset = sizeof(SkPoint); | 108 static const int kColorOffset = sizeof(SkPoint); |
106 GrColor* vertColor = reinterpret_cast<GrColor*>(offset + kColorOffse t); | 109 GrColor* vertColor = reinterpret_cast<GrColor*>(offset + kColorOffse t); |
107 for (int j = 0; j < 4; ++j) { | 110 for (int j = 0; j < 4; ++j) { |
108 *vertColor = geom.fColor; | 111 *vertColor = geom.fColor; |
109 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); | 112 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); |
110 } | 113 } |
111 } | 114 } |
112 | 115 |
113 helper.issueDraw(batchTarget); | 116 helper.issueDraw(batchTarget); |
114 } | 117 } |
115 | 118 |
116 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 119 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
117 | 120 |
121 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which | |
122 // is used to seed the batch with its initial geometry. After seeding, the client should call | |
123 // init() so the Batch can initialize itself | |
124 Geometry* geometry() { return &fGeoData[0]; } | |
125 void init() { | |
126 const Geometry& geo = fGeoData[0]; | |
127 geo.fViewMatrix.mapRect(&fBounds, geo.fRect); | |
128 } | |
129 | |
118 private: | 130 private: |
119 BWFillRectBatch(const Geometry& geometry) { | 131 BWFillRectBatch() { |
120 this->initClassID<BWFillRectBatch>(); | 132 this->initClassID<BWFillRectBatch<Base>>(); |
121 fGeoData.push_back(geometry); | 133 fGeoData.push_back(); |
122 | |
123 fBounds = geometry.fRect; | |
124 geometry.fViewMatrix.mapRect(&fBounds); | |
125 } | 134 } |
126 | 135 |
127 GrColor color() const { return fBatch.fColor; } | 136 GrColor color() const { return fBatch.fColor; } |
128 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 137 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
129 bool colorIgnored() const { return fBatch.fColorIgnored; } | 138 bool colorIgnored() const { return fBatch.fColorIgnored; } |
130 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 139 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
131 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; } | |
132 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; } | |
133 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; } | |
134 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } | 140 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } |
135 | 141 |
136 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 142 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
137 BWFillRectBatch* that = t->cast<BWFillRectBatch>(); | 143 BWFillRectBatch* that = t->cast<BWFillRectBatch>(); |
138 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), | 144 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), |
139 that->bounds(), caps)) { | 145 that->bounds(), caps)) { |
140 return false; | 146 return false; |
141 } | 147 } |
142 | 148 |
143 if (this->hasLocalRect() != that->hasLocalRect()) { | 149 if (!Base::CanCombineLocalCoords(this->viewMatrix(), that->viewMatrix(), |
150 this->usesLocalCoords())) { | |
144 return false; | 151 return false; |
145 } | 152 } |
146 | 153 |
147 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | |
148 if (!this->hasLocalRect() && this->usesLocalCoords()) { | |
149 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { | |
150 return false; | |
151 } | |
152 | |
153 if (this->hasLocalMatrix() != that->hasLocalMatrix()) { | |
154 return false; | |
155 } | |
156 | |
157 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that ->localMatrix())) { | |
158 return false; | |
159 } | |
160 } | |
161 | |
162 if (this->color() != that->color()) { | 154 if (this->color() != that->color()) { |
163 fBatch.fColor = GrColor_ILLEGAL; | 155 fBatch.fColor = GrColor_ILLEGAL; |
164 } | 156 } |
165 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; | 157 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; |
166 this->joinBounds(that->bounds()); | 158 this->joinBounds(that->bounds()); |
167 return true; | 159 return true; |
168 } | 160 } |
169 | 161 |
170 | 162 |
171 /** We always use per-vertex colors so that rects can be batched across colo r changes. Sometimes | 163 /** We always use per-vertex colors so that rects can be batched across colo r changes. Sometimes |
172 we have explicit local coords and sometimes not. We *could* always prov ide explicit local | 164 we have explicit local coords and sometimes not. We *could* always prov ide explicit local |
173 coords and just duplicate the positions when the caller hasn't provided a local coord rect, | 165 coords and just duplicate the positions when the caller hasn't provided a local coord rect, |
174 but we haven't seen a use case which frequently switches between local r ect and no local | 166 but we haven't seen a use case which frequently switches between local r ect and no local |
175 rect draws. | 167 rect draws. |
176 | 168 |
177 The color param is used to determine whether the opaque hint can be set on the draw state. | 169 The color param is used to determine whether the opaque hint can be set on the draw state. |
178 The caller must populate the vertex colors itself. | 170 The caller must populate the vertex colors itself. |
179 | 171 |
180 The vertex attrib order is always pos, color, [local coords]. | 172 The vertex attrib order is always pos, color, [local coords]. |
181 */ | 173 */ |
182 const GrGeometryProcessor* createRectGP() const { | 174 const GrGeometryProcessor* createGP(const Geometry& geo) const { |
183 using namespace GrDefaultGeoProcFactory; | 175 using namespace GrDefaultGeoProcFactory; |
184 Color color(Color::kAttribute_Type); | 176 Color color(Color::kAttribute_Type); |
185 Coverage coverage(this->coverageIgnored() ? Coverage::kNone_Type : Cover age::kSolid_Type); | 177 Coverage coverage(this->coverageIgnored() ? Coverage::kNone_Type : Cover age::kSolid_Type); |
186 | 178 |
187 // if we have a local rect, then we apply the localMatrix directly to th e localRect to | 179 return Base::CreateGP(geo, color, coverage); |
188 // generate vertex local coords | |
189 if (this->hasLocalRect()) { | |
190 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); | |
191 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I()); | |
192 } else { | |
193 LocalCoords localCoords(LocalCoords::kUsePosition_Type, | |
194 this->hasLocalMatrix() ? &this->localMatrix( ) : NULL); | |
195 return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage , localCoords, | |
196 this->viewMatri x()); | |
197 } | |
198 } | 180 } |
199 | 181 |
200 struct BatchTracker { | 182 struct BatchTracker { |
201 GrColor fColor; | 183 GrColor fColor; |
202 bool fUsesLocalCoords; | 184 bool fUsesLocalCoords; |
203 bool fColorIgnored; | 185 bool fColorIgnored; |
204 bool fCoverageIgnored; | 186 bool fCoverageIgnored; |
205 }; | 187 }; |
206 | 188 |
207 BatchTracker fBatch; | 189 BatchTracker fBatch; |
208 SkSTArray<1, Geometry, true> fGeoData; | 190 SkSTArray<1, Geometry, true> fGeoData; |
209 }; | 191 }; |
210 | 192 |
193 /* | |
194 * Right now we have 4 variants of BWFillRect. BWFillRect with no local matrix or local rect, | |
bsalomon
2015/08/14 14:37:48
Maybe write this as bullets? Kind of hard to follo
| |
195 * BWFillRect who has a uniform localMatrix, BWFillRect who has a localRect, and a BWFillRect who | |
196 * applies its localMatrix to its localRect | |
robertphillips
2015/08/14 14:42:57
// These classes are created by having two levels
| |
197 */ | |
198 template <class Base> | |
199 class GrBWFillRectBatchNoLocalRectImp : public Base { | |
200 public: | |
201 typedef typename Base::Geometry Geometry; | |
202 | |
203 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs, | |
204 bool usesLocalCoords) { | |
205 // We apply the viewmatrix to the rect points on the cpu. However, if t he pipeline uses | |
206 // local coords then we won't be able to batch. We could actually uploa d the viewmatrix | |
207 // using vertex attributes in these cases, but haven't investigated that | |
208 return !usesLocalCoords || mine.cheapEqualTo(theirs); | |
209 } | |
210 | |
211 inline static bool StrideCheck(size_t vertexStride) { | |
212 return vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr ); | |
213 } | |
214 | |
215 inline static void FillInAttributes(intptr_t vertices, size_t vertexStride, | |
robertphillips
2015/08/14 14:42:57
We don't have to invoke "Base::OnFillInAttributes(
| |
216 const Geometry& args) {} | |
217 }; | |
218 | |
219 template <class Base> | |
220 class GrBWFillRectBatchLocalRectImp { | |
221 public: | |
222 typedef typename Base::Geometry Geometry; | |
223 | |
224 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs, | |
225 bool usesLocalCoords) { | |
robertphillips
2015/08/14 14:42:57
// We can always combine b.c. ...
?
| |
226 return true; | |
227 } | |
228 | |
229 inline static const GrGeometryProcessor* CreateGP( | |
230 const Geometry& geo, | |
231 const GrDefaultGeoProcFactory::C olor& color, | |
232 const GrDefaultGeoProcFactory::C overage& coverage) { | |
233 using namespace GrDefaultGeoProcFactory; | |
234 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); | |
235 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkM atrix::I()); | |
236 } | |
237 | |
238 inline static bool StrideCheck(size_t vertexStride) { | |
239 return vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLoca lCoordAttr); | |
240 } | |
241 | |
242 inline static void FillInAttributes(intptr_t vertices, size_t vertexStride, | |
243 const Geometry& args) { | |
244 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); | |
245 SkPoint* coords = reinterpret_cast<SkPoint*>(vertices + kLocalOffset); | |
246 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop, | |
247 args.fLocalRect.fRight, args.fLocalRect.fBottom, | |
248 vertexStride); | |
249 Base::OnFillInAttributes(coords, vertexStride, args); | |
250 } | |
251 }; | |
252 | |
253 class BWFillRectBatchSimpleImp { | |
254 public: | |
255 struct Geometry { | |
256 SkMatrix fViewMatrix; | |
257 SkRect fRect; | |
258 GrColor fColor; | |
259 }; | |
260 | |
261 inline static const GrGeometryProcessor* CreateGP( | |
262 const Geometry& geo, | |
263 const GrDefaultGeoProcFactory::C olor& color, | |
264 const GrDefaultGeoProcFactory::C overage& coverage) { | |
265 using namespace GrDefaultGeoProcFactory; | |
266 LocalCoords localCoords(LocalCoords::kUsePosition_Type); | |
267 return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage, lo calCoords, | |
268 geo.fViewMatrix); | |
269 } | |
270 }; | |
271 | |
272 class BWFillRectBatchLocalMatrixImp { | |
273 public: | |
274 struct Geometry { | |
275 SkMatrix fViewMatrix; | |
276 SkMatrix fLocalMatrix; | |
277 SkRect fRect; | |
278 GrColor fColor; | |
279 }; | |
280 | |
281 inline static const GrGeometryProcessor* CreateGP( | |
282 const Geometry& geo, | |
283 const GrDefaultGeoProcFactory::C olor& color, | |
284 const GrDefaultGeoProcFactory::C overage& coverage) { | |
285 using namespace GrDefaultGeoProcFactory; | |
286 LocalCoords localCoords(LocalCoords::kUsePosition_Type, &geo.fLocalMatri x); | |
287 return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage, lo calCoords, | |
288 geo.fViewMatrix); | |
289 } | |
290 }; | |
291 | |
292 class BWFillRectBatchLocalRectImp { | |
293 public: | |
294 struct Geometry { | |
295 SkMatrix fViewMatrix; | |
296 SkRect fRect; | |
297 SkRect fLocalRect; | |
298 GrColor fColor; | |
299 }; | |
300 inline static void OnFillInAttributes(SkPoint* coords, size_t vertexStride, | |
robertphillips
2015/08/14 14:42:57
call base class ?
| |
301 const Geometry& args) {} | |
302 }; | |
303 | |
304 class BWFillRectBatchLocalMatrixLocalRectImp { | |
305 public: | |
306 struct Geometry { | |
307 SkMatrix fViewMatrix; | |
308 SkMatrix fLocalMatrix; | |
309 SkRect fRect; | |
310 SkRect fLocalRect; | |
311 GrColor fColor; | |
312 }; | |
313 inline static void OnFillInAttributes(SkPoint* coords, size_t vertexStride, | |
314 const Geometry& args) { | |
315 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPer Quad); | |
316 } | |
317 static const int kVerticesPerQuad = 4; | |
318 }; | |
319 | |
320 | |
321 typedef BWFillRectBatch<GrBWFillRectBatchNoLocalRectImp<BWFillRectBatchSimpleImp >> BWFillRectBatchSimple; | |
322 typedef BWFillRectBatch<GrBWFillRectBatchNoLocalRectImp<BWFillRectBatchLocalMatr ixImp>> BWFillRectBatchLocalMatrix; | |
323 typedef BWFillRectBatch<GrBWFillRectBatchLocalRectImp<BWFillRectBatchLocalRectIm p>> BWFillRectBatchLocalRect; | |
324 typedef BWFillRectBatch<GrBWFillRectBatchLocalRectImp<BWFillRectBatchLocalMatrix LocalRectImp>> BWFillRectBatchLocalMatrixLocalRect; | |
325 | |
211 namespace GrBWFillRectBatch { | 326 namespace GrBWFillRectBatch { |
212 GrDrawBatch* Create(GrColor color, | 327 GrDrawBatch* Create(GrColor color, |
213 const SkMatrix& viewMatrix, | 328 const SkMatrix& viewMatrix, |
214 const SkRect& rect, | 329 const SkRect& rect, |
215 const SkRect* localRect, | 330 const SkRect* localRect, |
216 const SkMatrix* localMatrix) { | 331 const SkMatrix* localMatrix) { |
217 BWFillRectBatch::Geometry geometry; | 332 // TODO bubble these up as separate calls |
218 geometry.fColor = color; | 333 if (localRect && localMatrix) { |
219 geometry.fViewMatrix = viewMatrix; | 334 BWFillRectBatchLocalMatrixLocalRect* batch = BWFillRectBatchLocalMatrixL ocalRect::Create(); |
220 geometry.fRect = rect; | 335 BWFillRectBatchLocalMatrixLocalRect::Geometry& geo = *batch->geometry(); |
221 | 336 geo.fColor = color; |
222 if (localRect) { | 337 geo.fViewMatrix = viewMatrix; |
223 geometry.fHasLocalRect = true; | 338 geo.fLocalMatrix = *localMatrix; |
224 geometry.fLocalRect = *localRect; | 339 geo.fRect = rect; |
340 geo.fLocalRect = *localRect; | |
341 batch->init(); | |
342 return batch; | |
343 } else if (localRect) { | |
344 BWFillRectBatchLocalRect* batch = BWFillRectBatchLocalRect::Create(); | |
345 BWFillRectBatchLocalRect::Geometry& geo = *batch->geometry(); | |
346 geo.fColor = color; | |
347 geo.fViewMatrix = viewMatrix; | |
348 geo.fRect = rect; | |
349 geo.fLocalRect = *localRect; | |
350 batch->init(); | |
351 return batch; | |
352 } else if (localMatrix) { | |
353 BWFillRectBatchLocalMatrix* batch = BWFillRectBatchLocalMatrix::Create() ; | |
354 BWFillRectBatchLocalMatrix::Geometry& geo = *batch->geometry(); | |
355 geo.fColor = color; | |
356 geo.fViewMatrix = viewMatrix; | |
357 geo.fLocalMatrix = *localMatrix; | |
358 geo.fRect = rect; | |
359 batch->init(); | |
360 return batch; | |
225 } else { | 361 } else { |
226 geometry.fHasLocalRect = false; | 362 BWFillRectBatchSimple* batch = BWFillRectBatchSimple::Create(); |
363 BWFillRectBatchSimple::Geometry& geo = *batch->geometry(); | |
364 geo.fColor = color; | |
365 geo.fViewMatrix = viewMatrix; | |
366 geo.fRect = rect; | |
367 batch->init(); | |
368 return batch; | |
227 } | 369 } |
228 | |
229 if (localMatrix) { | |
230 geometry.fHasLocalMatrix = true; | |
231 geometry.fLocalMatrix = *localMatrix; | |
232 } else { | |
233 geometry.fHasLocalMatrix = false; | |
234 } | |
235 | |
236 return BWFillRectBatch::Create(geometry); | |
237 } | 370 } |
238 }; | 371 }; |
239 | 372 |
240 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 373 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
241 | 374 |
242 #ifdef GR_TEST_UTILS | 375 #ifdef GR_TEST_UTILS |
243 | 376 |
244 #include "GrBatchTest.h" | 377 #include "GrBatchTest.h" |
245 | 378 |
246 DRAW_BATCH_TEST_DEFINE(RectBatch) { | 379 DRAW_BATCH_TEST_DEFINE(RectBatch) { |
247 BWFillRectBatch::Geometry geometry; | 380 GrColor color = GrRandomColor(random); |
248 geometry.fColor = GrRandomColor(random); | 381 SkRect rect = GrTest::TestRect(random); |
382 SkRect localRect = GrTest::TestRect(random); | |
383 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | |
384 SkMatrix localMatrix = GrTest::TestMatrix(random); | |
249 | 385 |
250 geometry.fRect = GrTest::TestRect(random); | 386 bool hasLocalRect = random->nextBool(); |
251 geometry.fHasLocalRect = random->nextBool(); | 387 bool hasLocalMatrix = random->nextBool(); |
252 | 388 return GrBWFillRectBatch::Create(color, viewMatrix, rect, hasLocalRect ? &lo calRect : nullptr, |
253 if (geometry.fHasLocalRect) { | 389 hasLocalMatrix ? &localMatrix : nullptr); |
254 geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); | |
255 geometry.fLocalRect = GrTest::TestRect(random); | |
256 } else { | |
257 geometry.fViewMatrix = GrTest::TestMatrix(random); | |
258 } | |
259 | |
260 geometry.fHasLocalMatrix = random->nextBool(); | |
261 if (geometry.fHasLocalMatrix) { | |
262 geometry.fLocalMatrix = GrTest::TestMatrix(random); | |
263 } | |
264 | |
265 return BWFillRectBatch::Create(geometry); | |
266 } | 390 } |
267 | 391 |
268 #endif | 392 #endif |
OLD | NEW |