Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Side by Side Diff: src/gpu/batches/GrAAFillRectBatch.cpp

Issue 1290763002: Add GrAARectBatch which can handle a local matrix (Closed) Base URL: https://skia.googlesource.com/skia.git@explicitlocalcoordsbatch
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/batches/GrAAFillRectBatch.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "GrAAFillRectBatch.h" 8 #include "GrAAFillRectBatch.h"
9 9
10 #include "GrBatch.h" 10 #include "GrBatch.h"
11 #include "GrColor.h" 11 #include "GrColor.h"
12 #include "GrDefaultGeoProcFactory.h" 12 #include "GrDefaultGeoProcFactory.h"
13 #include "GrResourceKey.h" 13 #include "GrResourceKey.h"
14 #include "GrResourceProvider.h" 14 #include "GrResourceProvider.h"
15 #include "GrTypes.h" 15 #include "GrTypes.h"
16 #include "SkMatrix.h" 16 #include "SkMatrix.h"
17 #include "SkRect.h" 17 #include "SkRect.h"
18 18
19 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); 19 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
20 20
21 static void set_inset_fan(SkPoint* pts, size_t stride, 21 static void set_inset_fan(SkPoint* pts, size_t stride,
22 const SkRect& r, SkScalar dx, SkScalar dy) { 22 const SkRect& r, SkScalar dx, SkScalar dy) {
23 pts->setRectFan(r.fLeft + dx, r.fTop + dy, 23 pts->setRectFan(r.fLeft + dx, r.fTop + dy,
24 r.fRight - dx, r.fBottom - dy, stride); 24 r.fRight - dx, r.fBottom - dy, stride);
25 } 25 }
26 26
27 static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage , 27 template <typename Base>
robertphillips 2015/08/12 16:31:20 // This compiles b.c. ... ?
28 const SkMatrix& viewMatrix , 28 class AAFillRectBatch : public Base {
29 bool usesLocalCoords, 29 public:
30 bool coverageIgnored) { 30 typedef typename Base::Geometry Geometry;
31 using namespace GrDefaultGeoProcFactory;
32 31
33 Color color(Color::kAttribute_Type); 32 static AAFillRectBatch* Create() {
34 Coverage::Type coverageType; 33 return SkNEW(AAFillRectBatch);
35 // TODO remove coverage if coverage is ignored
36 /*if (coverageIgnored) {
37 coverageType = Coverage::kNone_Type;
38 } else*/ if (tweakAlphaForCoverage) {
39 coverageType = Coverage::kSolid_Type;
40 } else {
41 coverageType = Coverage::kAttribute_Type;
42 }
43 Coverage coverage(coverageType);
44 LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type :
45 LocalCoords::kUnused_Type);
46 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
47 }
48
49 class AAFillRectBatch : public GrBatch {
50 public:
51 struct Geometry {
52 GrColor fColor;
53 SkMatrix fViewMatrix;
54 SkRect fRect;
55 SkRect fDevRect;
56 };
57
58 static GrBatch* Create(GrColor color,
59 const SkMatrix& viewMatrix,
60 const SkRect& rect,
61 const SkRect& devRect) {
62 return SkNEW_ARGS(AAFillRectBatch, (color, viewMatrix, rect, devRect));
63 } 34 }
64 35
65 const char* name() const override { return "AAFillRectBatch"; } 36 const char* name() const override { return "AAFillRectBatch"; }
66 37
67 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 38 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
68 // When this is called on a batch, there is only one geometry bundle 39 // When this is called on a batch, there is only one geometry bundle
69 out->setKnownFourComponents(fGeoData[0].fColor); 40 out->setKnownFourComponents(fGeoData[0].fColor);
70 } 41 }
71 42
72 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 43 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
(...skipping 11 matching lines...) Expand all
84 fBatch.fColorIgnored = !opt.readsColor(); 55 fBatch.fColorIgnored = !opt.readsColor();
85 fBatch.fColor = fGeoData[0].fColor; 56 fBatch.fColor = fGeoData[0].fColor;
86 fBatch.fUsesLocalCoords = opt.readsLocalCoords(); 57 fBatch.fUsesLocalCoords = opt.readsLocalCoords();
87 fBatch.fCoverageIgnored = !opt.readsCoverage(); 58 fBatch.fCoverageIgnored = !opt.readsCoverage();
88 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); 59 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
89 } 60 }
90 61
91 void generateGeometry(GrBatchTarget* batchTarget) override { 62 void generateGeometry(GrBatchTarget* batchTarget) override {
92 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); 63 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
93 64
94 SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakA lphaForCoverage, 65 SkAutoTUnref<const GrGeometryProcessor> gp(CreateFillRectGP(canTweakAlph aForCoverage,
95 this->vie wMatrix(), 66 this->viewMa trix(),
96 this->use sLocalCoords(), 67 this->usesLo calCoords(),
robertphillips 2015/08/12 16:31:20 rm the 'this->' on the static method ?
97 this->cov erageIgnored())); 68 this->LocalC oordsType(),
69 this->covera geIgnored()));
98 if (!gp) { 70 if (!gp) {
99 SkDebugf("Couldn't create GrGeometryProcessor\n"); 71 SkDebugf("Couldn't create GrGeometryProcessor\n");
100 return; 72 return;
101 } 73 }
102 74
103 batchTarget->initDraw(gp, this->pipeline()); 75 batchTarget->initDraw(gp, this->pipeline());
104 76
105 size_t vertexStride = gp->getVertexStride(); 77 size_t vertexStride = gp->getVertexStride();
robertphillips 2015/08/12 16:31:20 same here ?
106 SkASSERT(canTweakAlphaForCoverage ? 78 SkASSERT(this->StrideCheck(vertexStride, canTweakAlphaForCoverage,
107 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) : 79 this->usesLocalCoords()));
108 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr));
109 int instanceCount = fGeoData.count(); 80 int instanceCount = fGeoData.count();
110 81
111 SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer( 82 SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer(
112 batchTarget->resourceProvider())); 83 batchTarget->resourceProvider()));
robertphillips 2015/08/12 16:31:20 Hmm .. a bit surprised we need the "typename Base:
113 InstancedHelper helper; 84 typename Base::InstancedHelper helper;
114 void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, ve rtexStride, 85 void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, ve rtexStride,
115 indexBuffer, kVertsPerAAFillRect, kIndicesP erAAFillRect, 86 indexBuffer, kVertsPerAAFillRect, kIndicesP erAAFillRect,
116 instanceCount); 87 instanceCount);
117 if (!vertices || !indexBuffer) { 88 if (!vertices || !indexBuffer) {
118 SkDebugf("Could not allocate vertices\n"); 89 SkDebugf("Could not allocate vertices\n");
119 return; 90 return;
120 } 91 }
121 92
122 for (int i = 0; i < instanceCount; i++) { 93 for (int i = 0; i < instanceCount; i++) {
123 const Geometry& args = fGeoData[i];
124 this->generateAAFillRectGeometry(vertices, 94 this->generateAAFillRectGeometry(vertices,
125 i * kVertsPerAAFillRect * vertexStr ide, 95 i * kVertsPerAAFillRect * vertexStr ide,
126 vertexStride, 96 vertexStride,
127 args.fColor, 97 fGeoData[i],
128 args.fViewMatrix,
129 args.fRect,
130 args.fDevRect,
131 canTweakAlphaForCoverage); 98 canTweakAlphaForCoverage);
132 } 99 }
133 100
134 helper.issueDraw(batchTarget); 101 helper.issueDraw(batchTarget);
135 } 102 }
136 103
137 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 104 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
138 105
106 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which
107 // is used to seed the batch with its initial geometry. After seeding, the client should call
108 // init() so the Batch can initialize itself
robertphillips 2015/08/12 16:31:20 "const Geometry& geometry() const" ? If not should
109 Geometry& geometry() { return fGeoData[0]; }
110 void init() {
111 const Geometry& geo = fGeoData[0];
112 this->setBounds(geo.fDevRect);
113 }
114
115
139 private: 116 private:
140 AAFillRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& rec t, 117 AAFillRectBatch() {
141 const SkRect& devRect) { 118 this->template initClassID<Base>();
142 this->initClassID<AAFillRectBatch>();
143 Geometry& geometry = fGeoData.push_back();
144 geometry.fRect = rect;
145 geometry.fViewMatrix = viewMatrix;
146 geometry.fDevRect = devRect;
147 geometry.fColor = color;
148 119
149 this->setBounds(geometry.fDevRect); 120 // Push back an initial geometry
121 fGeoData.push_back();
150 } 122 }
151 123
152 static const int kNumAAFillRectsInIndexBuffer = 256; 124 static const int kNumAAFillRectsInIndexBuffer = 256;
153 static const int kVertsPerAAFillRect = 8; 125 static const int kVertsPerAAFillRect = 8;
154 static const int kIndicesPerAAFillRect = 30; 126 static const int kIndicesPerAAFillRect = 30;
155 127
156 const GrIndexBuffer* getIndexBuffer(GrResourceProvider* resourceProvider) { 128 const GrIndexBuffer* getIndexBuffer(GrResourceProvider* resourceProvider) {
157 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); 129 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
158 130
159 static const uint16_t gFillAARectIdx[] = { 131 static const uint16_t gFillAARectIdx[] = {
(...skipping 15 matching lines...) Expand all
175 bool colorIgnored() const { return fBatch.fColorIgnored; } 147 bool colorIgnored() const { return fBatch.fColorIgnored; }
176 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 148 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
177 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } 149 bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
178 150
179 bool onCombineIfPossible(GrBatch* t) override { 151 bool onCombineIfPossible(GrBatch* t) override {
180 if (!this->pipeline()->isEqual(*t->pipeline())) { 152 if (!this->pipeline()->isEqual(*t->pipeline())) {
181 return false; 153 return false;
182 } 154 }
183 155
184 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); 156 AAFillRectBatch* that = t->cast<AAFillRectBatch>();
185 157 if (!this->onCanCombineLocalCoords(this->viewMatrix(), that->viewMatrix( ),
186 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 158 this->usesLocalCoords())) {
187 // We apply the viewmatrix to the rect points on the cpu. However, if t he pipeline uses
188 // local coords then we won't be able to batch. We could actually uploa d the viewmatrix
189 // using vertex attributes in these cases, but haven't investigated that
190 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi ewMatrix())) {
191 return false; 159 return false;
192 } 160 }
193 161
194 if (this->color() != that->color()) { 162 if (this->color() != that->color()) {
195 fBatch.fColor = GrColor_ILLEGAL; 163 fBatch.fColor = GrColor_ILLEGAL;
196 } 164 }
197 165
198 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to 166 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to
199 // not tweaking 167 // not tweaking
200 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage() ) { 168 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage() ) {
201 fBatch.fCanTweakAlphaForCoverage = false; 169 fBatch.fCanTweakAlphaForCoverage = false;
202 } 170 }
203 171
204 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; 172 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
205 this->joinBounds(that->bounds()); 173 this->joinBounds(that->bounds());
206 return true; 174 return true;
207 } 175 }
208 176
209 void generateAAFillRectGeometry(void* vertices, 177 void generateAAFillRectGeometry(void* vertices,
210 size_t offset, 178 size_t offset,
211 size_t vertexStride, 179 size_t vertexStride,
212 GrColor color, 180 const Geometry& args,
213 const SkMatrix& viewMatrix,
214 const SkRect& rect,
215 const SkRect& devRect,
216 bool tweakAlphaForCoverage) const { 181 bool tweakAlphaForCoverage) const {
217 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; 182 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
218 183
219 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); 184 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
220 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); 185 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
221 186
222 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); 187 SkScalar inset = SkMinScalar(args.fDevRect.width(), SK_Scalar1);
223 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); 188 inset = SK_ScalarHalf * SkMinScalar(inset, args.fDevRect.height());
224 189
225 if (viewMatrix.rectStaysRect()) { 190 if (args.fViewMatrix.rectStaysRect()) {
226 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Sc alarHalf); 191 set_inset_fan(fan0Pos, vertexStride, args.fDevRect, -SK_ScalarHalf, -SK_ScalarHalf);
227 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset); 192 set_inset_fan(fan1Pos, vertexStride, args.fDevRect, inset, inset);
228 } else { 193 } else {
229 // compute transformed (1, 0) and (0, 1) vectors 194 // compute transformed (1, 0) and (0, 1) vectors
230 SkVector vec[2] = { 195 SkVector vec[2] = {
231 { viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] }, 196 { args.fViewMatrix[SkMatrix::kMScaleX], args.fViewMatrix[SkMatrix: :kMSkewY] },
232 { viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY] } 197 { args.fViewMatrix[SkMatrix::kMSkewX], args.fViewMatrix[SkMatrix: :kMScaleY] }
233 }; 198 };
234 199
235 vec[0].normalize(); 200 vec[0].normalize();
236 vec[0].scale(SK_ScalarHalf); 201 vec[0].scale(SK_ScalarHalf);
237 vec[1].normalize(); 202 vec[1].normalize();
238 vec[1].scale(SK_ScalarHalf); 203 vec[1].scale(SK_ScalarHalf);
239 204
240 // create the rotated rect 205 // create the rotated rect
241 fan0Pos->setRectFan(rect.fLeft, rect.fTop, 206 fan0Pos->setRectFan(args.fRect.fLeft, args.fRect.fTop,
242 rect.fRight, rect.fBottom, vertexStride); 207 args.fRect.fRight, args.fRect.fBottom, vertexStr ide);
243 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4); 208 args.fViewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
244 209
245 // Now create the inset points and then outset the original 210 // Now create the inset points and then outset the original
246 // rotated points 211 // rotated points
247 212
248 // TL 213 // TL
249 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) = 214 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
250 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + v ec[1]; 215 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + v ec[1];
251 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[ 1]; 216 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[ 1];
252 // BL 217 // BL
253 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) = 218 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
254 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - v ec[1]; 219 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - v ec[1];
255 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[ 1]; 220 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[ 1];
256 // BR 221 // BR
257 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) = 222 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
258 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - v ec[1]; 223 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - v ec[1];
259 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[ 1]; 224 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[ 1];
260 // TR 225 // TR
261 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = 226 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
262 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + v ec[1]; 227 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + v ec[1];
263 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[ 1]; 228 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[ 1];
264 } 229 }
265 230
robertphillips 2015/08/12 16:31:20 rm "this->" ?
231 this->PostGenerateHook(verts, vertexStride, fan0Pos, args);
232
266 // Make verts point to vertex color and then set all the color and cover age vertex attrs 233 // Make verts point to vertex color and then set all the color and cover age vertex attrs
267 // values. 234 // values.
268 verts += sizeof(SkPoint); 235 verts += sizeof(SkPoint);
269 for (int i = 0; i < 4; ++i) { 236 for (int i = 0; i < 4; ++i) {
270 if (tweakAlphaForCoverage) { 237 if (tweakAlphaForCoverage) {
271 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; 238 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
272 } else { 239 } else {
273 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; 240 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fCo lor;
274 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrCo lor)) = 0; 241 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrCo lor)) = 0;
275 } 242 }
276 } 243 }
277 244
278 int scale; 245 int scale;
279 if (inset < SK_ScalarHalf) { 246 if (inset < SK_ScalarHalf) {
280 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)) ; 247 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)) ;
281 SkASSERT(scale >= 0 && scale <= 255); 248 SkASSERT(scale >= 0 && scale <= 255);
282 } else { 249 } else {
283 scale = 0xff; 250 scale = 0xff;
284 } 251 }
285 252
286 verts += 4 * vertexStride; 253 verts += 4 * vertexStride;
287 254
288 float innerCoverage = GrNormalizeByteToFloat(scale); 255 float innerCoverage = GrNormalizeByteToFloat(scale);
289 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale ); 256 GrColor scaledColor = (0xff == scale) ? args.fColor : SkAlphaMulQ(args.f Color, scale);
290 257
291 for (int i = 0; i < 4; ++i) { 258 for (int i = 0; i < 4; ++i) {
292 if (tweakAlphaForCoverage) { 259 if (tweakAlphaForCoverage) {
293 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledCo lor; 260 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledCo lor;
294 } else { 261 } else {
295 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; 262 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fCo lor;
296 *reinterpret_cast<float*>(verts + i * vertexStride + 263 *reinterpret_cast<float*>(verts + i * vertexStride +
297 sizeof(GrColor)) = innerCoverage; 264 sizeof(GrColor)) = innerCoverage;
298 } 265 }
299 } 266 }
300 } 267 }
301 268
269 static const GrGeometryProcessor* CreateFillRectGP(
270 bool tweakAlphaForCoverage,
271 const SkMatrix& viewMatrix,
272 bool usesLocalCoords,
273 GrDefaultGeoProcFactory::LocalCoords::T ype localCoordsType,
274 bool coverageIgnored) {
275 using namespace GrDefaultGeoProcFactory;
276
277 Color color(Color::kAttribute_Type);
278 Coverage::Type coverageType;
279 // TODO remove coverage if coverage is ignored
280 /*if (coverageIgnored) {
281 coverageType = Coverage::kNone_Type;
282 } else*/ if (tweakAlphaForCoverage) {
283 coverageType = Coverage::kSolid_Type;
284 } else {
285 coverageType = Coverage::kAttribute_Type;
286 }
287 Coverage coverage(coverageType);
288
289 // We assume the caller has inverted the viewmatrix
290 LocalCoords localCoords(usesLocalCoords ? localCoordsType : LocalCoords: :kUnused_Type);
291 if (LocalCoords::kHasExplicit_Type == localCoordsType) {
292 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I());
293 } else {
294 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix );
295 }
296 }
297
302 struct BatchTracker { 298 struct BatchTracker {
303 GrColor fColor; 299 GrColor fColor;
304 bool fUsesLocalCoords; 300 bool fUsesLocalCoords;
305 bool fColorIgnored; 301 bool fColorIgnored;
306 bool fCoverageIgnored; 302 bool fCoverageIgnored;
307 bool fCanTweakAlphaForCoverage; 303 bool fCanTweakAlphaForCoverage;
308 }; 304 };
309 305
310 BatchTracker fBatch; 306 BatchTracker fBatch;
311 SkSTArray<1, Geometry, true> fGeoData; 307 SkSTArray<1, Geometry, true> fGeoData;
312 }; 308 };
313 309
robertphillips 2015/08/12 16:31:20 Can we document somewhere what the two base classe
310 class AAFillRectBatchNoLocalMatrixImp : public GrBatch {
311 public:
312 struct Geometry {
313 SkMatrix fViewMatrix;
314 SkRect fRect;
315 SkRect fDevRect;
316 GrColor fColor;
317 };
318
319 protected:
robertphillips 2015/08/12 16:31:20 Is this supposed to be static ?
320 inline bool onCanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& th eirs,
321 bool usesLocalCoords) {
322 // We apply the viewmatrix to the rect points on the cpu. However, if t he pipeline uses
323 // local coords then we won't be able to batch. We could actually uploa d the viewmatrix
324 // using vertex attributes in these cases, but haven't investigated that
325 return !usesLocalCoords || mine.cheapEqualTo(theirs);
326 }
327
328 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
329 return GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type;
330 }
331
332 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCov erage,
333 bool usesLocalCoords) {
robertphillips 2015/08/12 16:31:19 SkASSERT(!usesLocalCoords); ?
joshualitt 2015/08/12 17:07:41 this guy can use local coords but he does so throu
334 return canTweakAlphaForCoverage ?
335 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) :
336 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr);
337 }
338
339 inline static void PostGenerateHook(intptr_t, size_t, SkPoint*, const Geomet ry&) {}
340 };
341
342 class AAFillRectBatchLocalMatrixImp : public GrBatch {
343 public:
344 struct Geometry {
345 SkMatrix fViewMatrix;
346 SkMatrix fLocalMatrix;
347 SkRect fRect;
348 SkRect fDevRect;
349 GrColor fColor;
350 };
351
352 protected:
353 inline bool onCanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& th eirs,
354 bool usesLocalCoords) {
355 return true;
356 }
357
358 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
359 return GrDefaultGeoProcFactory::LocalCoords::kHasExplicit_Type;
360 }
361
362 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCov erage,
363 bool usesLocalCoords) {
364 // Whomever created us should not have done so if there are no local coo rds
365 SkASSERT(usesLocalCoords);
366 return canTweakAlphaForCoverage ?
367 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordAttr) :
368 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordCoverage);
369 }
370
371 inline static void PostGenerateHook(intptr_t vertices, size_t vertexStride,
372 SkPoint* fan0Pos, const Geometry& args) {
373 SkMatrix invViewMatrix;
374 if (!args.fViewMatrix.invert(&invViewMatrix)) {
375 SkASSERT(false);
376 invViewMatrix = SkMatrix::I();
377 }
378 SkMatrix localCoordMatrix;
379 localCoordMatrix.setConcat(args.fLocalMatrix, invViewMatrix);
380 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(vertices + vertexStride - sizeof(SkPoint));
381 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
382 }
383 };
384
385 typedef AAFillRectBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalM atrix;
386 typedef AAFillRectBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatri x;
387
314 namespace GrAAFillRectBatch { 388 namespace GrAAFillRectBatch {
315 389
316 GrBatch* Create(GrColor color, 390 GrBatch* Create(GrColor color,
317 const SkMatrix& viewMatrix, 391 const SkMatrix& viewMatrix,
318 const SkRect& rect, 392 const SkRect& rect,
319 const SkRect& devRect) { 393 const SkRect& devRect) {
320 return AAFillRectBatch::Create(color, viewMatrix, rect, devRect); 394 AAFillRectBatchNoLocalMatrix* batch = AAFillRectBatchNoLocalMatrix::Create() ;
395 AAFillRectBatchNoLocalMatrix::Geometry& geo = batch->geometry();
396 geo.fColor = color;
397 geo.fViewMatrix = viewMatrix;
398 geo.fRect = rect;
399 geo.fDevRect = devRect;
400 batch->init();
401 return batch;
402 }
403
404 GrBatch* Create(GrColor color,
405 const SkMatrix& viewMatrix,
406 const SkMatrix& localMatrix,
407 const SkRect& rect,
408 const SkRect& devRect) {
409 AAFillRectBatchLocalMatrix* batch = AAFillRectBatchLocalMatrix::Create();
410 AAFillRectBatchLocalMatrix::Geometry& geo = batch->geometry();
411 geo.fColor = color;
412 geo.fViewMatrix = viewMatrix;
413 geo.fLocalMatrix = localMatrix;
414 geo.fRect = rect;
415 geo.fDevRect = devRect;
416 batch->init();
417 return batch;
321 } 418 }
322 419
323 }; 420 };
324 421
325 //////////////////////////////////////////////////////////////////////////////// /////////////////// 422 //////////////////////////////////////////////////////////////////////////////// ///////////////////
326 423
327 #ifdef GR_TEST_UTILS 424 #ifdef GR_TEST_UTILS
328 425
329 #include "GrBatchTest.h" 426 #include "GrBatchTest.h"
330 427
robertphillips 2015/08/12 16:31:20 Seems like we need to test both here.
331 BATCH_TEST_DEFINE(AAFillRectBatch) { 428 BATCH_TEST_DEFINE(AAFillRectBatch) {
332 GrColor color = GrRandomColor(random); 429 AAFillRectBatchNoLocalMatrix* batch = AAFillRectBatchNoLocalMatrix::Create() ;
333 SkMatrix viewMatrix = GrTest::TestMatrix(random); 430 AAFillRectBatchNoLocalMatrix::Geometry& geo = batch->geometry();
334 SkRect rect = GrTest::TestRect(random); 431 geo.fColor = GrRandomColor(random);
335 SkRect devRect = GrTest::TestRect(random); 432 geo.fViewMatrix = GrTest::TestMatrix(random);
336 return AAFillRectBatch::Create(color, viewMatrix, rect, devRect); 433 geo.fRect = GrTest::TestRect(random);
434 geo.fDevRect = GrTest::TestRect(random);
435 batch->init();
436 return batch;
337 } 437 }
338 438
339 #endif 439 #endif
OLDNEW
« no previous file with comments | « src/gpu/batches/GrAAFillRectBatch.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698