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

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: rebase 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 /*
28 const SkMatrix& viewMatrix , 28 * AAFillRectBatch is templated to optionally allow the insertion of an addition al
29 bool usesLocalCoords, 29 * attribute for explicit local coordinates.
30 bool coverageIgnored) { 30 * To use this template, an implementation must define the following static func tions:
31 using namespace GrDefaultGeoProcFactory; 31 * A Geometry struct
32 32 *
33 Color color(Color::kAttribute_Type); 33 * bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs,
34 Coverage::Type coverageType; 34 * bool usesLocalCoords)
35 // TODO remove coverage if coverage is ignored 35 *
36 /*if (coverageIgnored) { 36 * GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType()
37 coverageType = Coverage::kNone_Type; 37 *
38 } else*/ if (tweakAlphaForCoverage) { 38 * bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage,
39 coverageType = Coverage::kSolid_Type; 39 * bool usesLocalCoords)
40 } else { 40 *
41 coverageType = Coverage::kAttribute_Type; 41 * void FillInAttributes(intptr_t startVertex, size_t vertexStride,
42 } 42 * SkPoint* fan0Position, const Geometry&)
43 Coverage coverage(coverageType); 43 */
44 LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type : 44 template <typename Base>
45 LocalCoords::kUnused_Type);
46 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
47 }
48
49 class AAFillRectBatch : public GrBatch { 45 class AAFillRectBatch : public GrBatch {
50 public: 46 public:
51 struct Geometry { 47 typedef typename Base::Geometry Geometry;
52 GrColor fColor;
53 SkMatrix fViewMatrix;
54 SkRect fRect;
55 SkRect fDevRect;
56 };
57 48
58 static GrBatch* Create(GrColor color, 49 static AAFillRectBatch* Create() {
59 const SkMatrix& viewMatrix, 50 return SkNEW(AAFillRectBatch);
60 const SkRect& rect,
61 const SkRect& devRect) {
62 return SkNEW_ARGS(AAFillRectBatch, (color, viewMatrix, rect, devRect));
63 } 51 }
64 52
65 const char* name() const override { return "AAFillRectBatch"; } 53 const char* name() const override { return "AAFillRectBatch"; }
66 54
67 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 55 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
68 // When this is called on a batch, there is only one geometry bundle 56 // When this is called on a batch, there is only one geometry bundle
69 out->setKnownFourComponents(fGeoData[0].fColor); 57 out->setKnownFourComponents(fGeoData[0].fColor);
70 } 58 }
71 59
72 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 60 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
(...skipping 11 matching lines...) Expand all
84 fBatch.fColorIgnored = !opt.readsColor(); 72 fBatch.fColorIgnored = !opt.readsColor();
85 fBatch.fColor = fGeoData[0].fColor; 73 fBatch.fColor = fGeoData[0].fColor;
86 fBatch.fUsesLocalCoords = opt.readsLocalCoords(); 74 fBatch.fUsesLocalCoords = opt.readsLocalCoords();
87 fBatch.fCoverageIgnored = !opt.readsCoverage(); 75 fBatch.fCoverageIgnored = !opt.readsCoverage();
88 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); 76 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
89 } 77 }
90 78
91 void generateGeometry(GrBatchTarget* batchTarget) override { 79 void generateGeometry(GrBatchTarget* batchTarget) override {
92 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); 80 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
93 81
94 SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakA lphaForCoverage, 82 SkAutoTUnref<const GrGeometryProcessor> gp(CreateFillRectGP(canTweakAlph aForCoverage,
95 this->vie wMatrix(), 83 this->viewMa trix(),
96 this->use sLocalCoords(), 84 this->usesLo calCoords(),
97 this->cov erageIgnored())); 85 Base::LocalC oordsType(),
86 this->covera geIgnored()));
98 if (!gp) { 87 if (!gp) {
99 SkDebugf("Couldn't create GrGeometryProcessor\n"); 88 SkDebugf("Couldn't create GrGeometryProcessor\n");
100 return; 89 return;
101 } 90 }
102 91
103 batchTarget->initDraw(gp, this->pipeline()); 92 batchTarget->initDraw(gp, this->pipeline());
104 93
105 size_t vertexStride = gp->getVertexStride(); 94 size_t vertexStride = gp->getVertexStride();
106 SkASSERT(canTweakAlphaForCoverage ? 95 SkASSERT(Base::StrideCheck(vertexStride, canTweakAlphaForCoverage,
107 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) : 96 this->usesLocalCoords()));
108 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr));
109 int instanceCount = fGeoData.count(); 97 int instanceCount = fGeoData.count();
110 98
111 SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer( 99 SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer(
112 batchTarget->resourceProvider())); 100 batchTarget->resourceProvider()));
113 InstancedHelper helper; 101 InstancedHelper helper;
114 void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, ve rtexStride, 102 void* vertices = helper.init(batchTarget, kTriangles_GrPrimitiveType, ve rtexStride,
115 indexBuffer, kVertsPerAAFillRect, kIndicesP erAAFillRect, 103 indexBuffer, kVertsPerAAFillRect, kIndicesP erAAFillRect,
116 instanceCount); 104 instanceCount);
117 if (!vertices || !indexBuffer) { 105 if (!vertices || !indexBuffer) {
118 SkDebugf("Could not allocate vertices\n"); 106 SkDebugf("Could not allocate vertices\n");
119 return; 107 return;
120 } 108 }
121 109
122 for (int i = 0; i < instanceCount; i++) { 110 for (int i = 0; i < instanceCount; i++) {
123 const Geometry& args = fGeoData[i];
124 this->generateAAFillRectGeometry(vertices, 111 this->generateAAFillRectGeometry(vertices,
125 i * kVertsPerAAFillRect * vertexStr ide, 112 i * kVertsPerAAFillRect * vertexStr ide,
126 vertexStride, 113 vertexStride,
127 args.fColor, 114 fGeoData[i],
128 args.fViewMatrix,
129 args.fRect,
130 args.fDevRect,
131 canTweakAlphaForCoverage); 115 canTweakAlphaForCoverage);
132 } 116 }
133 helper.issueDraw(batchTarget); 117 helper.issueDraw(batchTarget);
134 } 118 }
135 119
136 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 120 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
137 121
122 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which
123 // is used to seed the batch with its initial geometry. After seeding, the client should call
124 // init() so the Batch can initialize itself
125 Geometry* geometry() { return &fGeoData[0]; }
126 void init() {
127 const Geometry& geo = fGeoData[0];
128 this->setBounds(geo.fDevRect);
129 }
130
131
138 private: 132 private:
139 AAFillRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& rec t, 133 AAFillRectBatch() {
140 const SkRect& devRect) { 134 this->initClassID<AAFillRectBatch<Base>>();
141 this->initClassID<AAFillRectBatch>();
142 Geometry& geometry = fGeoData.push_back();
143 geometry.fRect = rect;
144 geometry.fViewMatrix = viewMatrix;
145 geometry.fDevRect = devRect;
146 geometry.fColor = color;
147 135
148 this->setBounds(geometry.fDevRect); 136 // Push back an initial geometry
137 fGeoData.push_back();
149 } 138 }
150 139
151 static const int kNumAAFillRectsInIndexBuffer = 256; 140 static const int kNumAAFillRectsInIndexBuffer = 256;
152 static const int kVertsPerAAFillRect = 8; 141 static const int kVertsPerAAFillRect = 8;
153 static const int kIndicesPerAAFillRect = 30; 142 static const int kIndicesPerAAFillRect = 30;
154 143
155 const GrIndexBuffer* getIndexBuffer(GrResourceProvider* resourceProvider) { 144 const GrIndexBuffer* getIndexBuffer(GrResourceProvider* resourceProvider) {
156 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); 145 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
157 146
158 static const uint16_t gFillAARectIdx[] = { 147 static const uint16_t gFillAARectIdx[] = {
(...skipping 16 matching lines...) Expand all
175 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 164 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
176 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } 165 bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
177 166
178 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 167 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
179 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *t->pipel ine(), t->bounds(), 168 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *t->pipel ine(), t->bounds(),
180 caps)) { 169 caps)) {
181 return false; 170 return false;
182 } 171 }
183 172
184 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); 173 AAFillRectBatch* that = t->cast<AAFillRectBatch>();
185 174 if (!Base::CanCombineLocalCoords(this->viewMatrix(), that->viewMatrix(),
186 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 175 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; 176 return false;
192 } 177 }
193 178
194 if (this->color() != that->color()) { 179 if (this->color() != that->color()) {
195 fBatch.fColor = GrColor_ILLEGAL; 180 fBatch.fColor = GrColor_ILLEGAL;
196 } 181 }
197 182
198 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to 183 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to
199 // not tweaking 184 // not tweaking
200 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage() ) { 185 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage() ) {
201 fBatch.fCanTweakAlphaForCoverage = false; 186 fBatch.fCanTweakAlphaForCoverage = false;
202 } 187 }
203 188
204 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; 189 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
205 this->joinBounds(that->bounds()); 190 this->joinBounds(that->bounds());
206 return true; 191 return true;
207 } 192 }
208 193
209 void generateAAFillRectGeometry(void* vertices, 194 void generateAAFillRectGeometry(void* vertices,
210 size_t offset, 195 size_t offset,
211 size_t vertexStride, 196 size_t vertexStride,
212 GrColor color, 197 const Geometry& args,
213 const SkMatrix& viewMatrix,
214 const SkRect& rect,
215 const SkRect& devRect,
216 bool tweakAlphaForCoverage) const { 198 bool tweakAlphaForCoverage) const {
217 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; 199 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
218 200
219 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); 201 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
220 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); 202 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
221 203
222 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); 204 SkScalar inset = SkMinScalar(args.fDevRect.width(), SK_Scalar1);
223 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); 205 inset = SK_ScalarHalf * SkMinScalar(inset, args.fDevRect.height());
224 206
225 if (viewMatrix.rectStaysRect()) { 207 if (args.fViewMatrix.rectStaysRect()) {
226 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Sc alarHalf); 208 set_inset_fan(fan0Pos, vertexStride, args.fDevRect, -SK_ScalarHalf, -SK_ScalarHalf);
227 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset); 209 set_inset_fan(fan1Pos, vertexStride, args.fDevRect, inset, inset);
228 } else { 210 } else {
229 // compute transformed (1, 0) and (0, 1) vectors 211 // compute transformed (1, 0) and (0, 1) vectors
230 SkVector vec[2] = { 212 SkVector vec[2] = {
231 { viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] }, 213 { args.fViewMatrix[SkMatrix::kMScaleX], args.fViewMatrix[SkMatrix: :kMSkewY] },
232 { viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY] } 214 { args.fViewMatrix[SkMatrix::kMSkewX], args.fViewMatrix[SkMatrix: :kMScaleY] }
233 }; 215 };
234 216
235 vec[0].normalize(); 217 vec[0].normalize();
236 vec[0].scale(SK_ScalarHalf); 218 vec[0].scale(SK_ScalarHalf);
237 vec[1].normalize(); 219 vec[1].normalize();
238 vec[1].scale(SK_ScalarHalf); 220 vec[1].scale(SK_ScalarHalf);
239 221
240 // create the rotated rect 222 // create the rotated rect
241 fan0Pos->setRectFan(rect.fLeft, rect.fTop, 223 fan0Pos->setRectFan(args.fRect.fLeft, args.fRect.fTop,
242 rect.fRight, rect.fBottom, vertexStride); 224 args.fRect.fRight, args.fRect.fBottom, vertexStr ide);
243 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4); 225 args.fViewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
244 226
245 // Now create the inset points and then outset the original 227 // Now create the inset points and then outset the original
246 // rotated points 228 // rotated points
247 229
248 // TL 230 // TL
249 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) = 231 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
250 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + v ec[1]; 232 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + v ec[1];
251 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[ 1]; 233 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[ 1];
252 // BL 234 // BL
253 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) = 235 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
254 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - v ec[1]; 236 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - v ec[1];
255 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[ 1]; 237 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[ 1];
256 // BR 238 // BR
257 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) = 239 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
258 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - v ec[1]; 240 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - v ec[1];
259 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[ 1]; 241 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[ 1];
260 // TR 242 // TR
261 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = 243 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
262 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + v ec[1]; 244 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + v ec[1];
263 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[ 1]; 245 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[ 1];
264 } 246 }
265 247
248 Base::FillInAttributes(verts, vertexStride, fan0Pos, args);
249
266 // Make verts point to vertex color and then set all the color and cover age vertex attrs 250 // Make verts point to vertex color and then set all the color and cover age vertex attrs
267 // values. 251 // values.
268 verts += sizeof(SkPoint); 252 verts += sizeof(SkPoint);
269 for (int i = 0; i < 4; ++i) { 253 for (int i = 0; i < 4; ++i) {
270 if (tweakAlphaForCoverage) { 254 if (tweakAlphaForCoverage) {
271 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; 255 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
272 } else { 256 } else {
273 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; 257 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fCo lor;
274 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrCo lor)) = 0; 258 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrCo lor)) = 0;
275 } 259 }
276 } 260 }
277 261
278 int scale; 262 int scale;
279 if (inset < SK_ScalarHalf) { 263 if (inset < SK_ScalarHalf) {
280 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)) ; 264 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)) ;
281 SkASSERT(scale >= 0 && scale <= 255); 265 SkASSERT(scale >= 0 && scale <= 255);
282 } else { 266 } else {
283 scale = 0xff; 267 scale = 0xff;
284 } 268 }
285 269
286 verts += 4 * vertexStride; 270 verts += 4 * vertexStride;
287 271
288 float innerCoverage = GrNormalizeByteToFloat(scale); 272 float innerCoverage = GrNormalizeByteToFloat(scale);
289 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale ); 273 GrColor scaledColor = (0xff == scale) ? args.fColor : SkAlphaMulQ(args.f Color, scale);
290 274
291 for (int i = 0; i < 4; ++i) { 275 for (int i = 0; i < 4; ++i) {
292 if (tweakAlphaForCoverage) { 276 if (tweakAlphaForCoverage) {
293 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledCo lor; 277 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledCo lor;
294 } else { 278 } else {
295 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; 279 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fCo lor;
296 *reinterpret_cast<float*>(verts + i * vertexStride + 280 *reinterpret_cast<float*>(verts + i * vertexStride +
297 sizeof(GrColor)) = innerCoverage; 281 sizeof(GrColor)) = innerCoverage;
298 } 282 }
299 } 283 }
300 } 284 }
301 285
286 static const GrGeometryProcessor* CreateFillRectGP(
287 bool tweakAlphaForCoverage,
288 const SkMatrix& viewMatrix,
289 bool usesLocalCoords,
290 GrDefaultGeoProcFactory::LocalCoords::T ype 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
307 LocalCoords localCoords(usesLocalCoords ? localCoordsType : LocalCoords: :kUnused_Type);
308 if (LocalCoords::kHasExplicit_Type == localCoordsType) {
309 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I());
310 } else {
311 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix );
312 }
313 }
314
302 struct BatchTracker { 315 struct BatchTracker {
303 GrColor fColor; 316 GrColor fColor;
304 bool fUsesLocalCoords; 317 bool fUsesLocalCoords;
305 bool fColorIgnored; 318 bool fColorIgnored;
306 bool fCoverageIgnored; 319 bool fCoverageIgnored;
307 bool fCanTweakAlphaForCoverage; 320 bool fCanTweakAlphaForCoverage;
308 }; 321 };
309 322
310 BatchTracker fBatch; 323 BatchTracker fBatch;
311 SkSTArray<1, Geometry, true> fGeoData; 324 SkSTArray<1, Geometry, true> fGeoData;
312 }; 325 };
313 326
327 class AAFillRectBatchNoLocalMatrixImp {
328 public:
329 struct Geometry {
330 SkMatrix fViewMatrix;
331 SkRect fRect;
332 SkRect fDevRect;
333 GrColor fColor;
334 };
335
336 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs,
337 bool usesLocalCoords) {
338 // We apply the viewmatrix to the rect points on the cpu. However, if t he pipeline uses
339 // local coords then we won't be able to batch. We could actually uploa d the viewmatrix
340 // using vertex attributes in these cases, but haven't investigated that
341 return !usesLocalCoords || mine.cheapEqualTo(theirs);
342 }
343
344 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
345 return GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type;
346 }
347
348 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCov erage,
349 bool usesLocalCoords) {
350 return canTweakAlphaForCoverage ?
351 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) :
352 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr);
353 }
354
355 inline static void FillInAttributes(intptr_t, size_t, SkPoint*, const Geomet ry&) {}
356 };
357
358 class AAFillRectBatchLocalMatrixImp {
359 public:
360 struct Geometry {
361 SkMatrix fViewMatrix;
362 SkMatrix fLocalMatrix;
363 SkRect fRect;
364 SkRect fDevRect;
365 GrColor fColor;
366 };
367
368 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs,
369 bool usesLocalCoords) {
370 return true;
371 }
372
373 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() {
374 return GrDefaultGeoProcFactory::LocalCoords::kHasExplicit_Type;
375 }
376
377 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCov erage,
378 bool usesLocalCoords) {
379 // Whomever created us should not have done so if there are no local coo rds
380 SkASSERT(usesLocalCoords);
381 return canTweakAlphaForCoverage ?
382 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordAttr) :
383 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordCoverage);
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
400 typedef AAFillRectBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalM atrix;
401 typedef AAFillRectBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatri x;
402
314 namespace GrAAFillRectBatch { 403 namespace GrAAFillRectBatch {
315 404
316 GrBatch* Create(GrColor color, 405 GrBatch* Create(GrColor color,
317 const SkMatrix& viewMatrix, 406 const SkMatrix& viewMatrix,
318 const SkRect& rect, 407 const SkRect& rect,
319 const SkRect& devRect) { 408 const SkRect& devRect) {
320 return AAFillRectBatch::Create(color, viewMatrix, rect, devRect); 409 AAFillRectBatchNoLocalMatrix* batch = AAFillRectBatchNoLocalMatrix::Create() ;
410 AAFillRectBatchNoLocalMatrix::Geometry& geo = *batch->geometry();
411 geo.fColor = color;
412 geo.fViewMatrix = viewMatrix;
413 geo.fRect = rect;
414 geo.fDevRect = devRect;
415 batch->init();
416 return batch;
417 }
418
419 GrBatch* Create(GrColor color,
420 const SkMatrix& viewMatrix,
421 const SkMatrix& localMatrix,
422 const SkRect& rect,
423 const SkRect& devRect) {
424 AAFillRectBatchLocalMatrix* batch = AAFillRectBatchLocalMatrix::Create();
425 AAFillRectBatchLocalMatrix::Geometry& geo = *batch->geometry();
426 geo.fColor = color;
427 geo.fViewMatrix = viewMatrix;
428 geo.fLocalMatrix = localMatrix;
429 geo.fRect = rect;
430 geo.fDevRect = devRect;
431 batch->init();
432 return batch;
321 } 433 }
322 434
323 }; 435 };
324 436
325 //////////////////////////////////////////////////////////////////////////////// /////////////////// 437 //////////////////////////////////////////////////////////////////////////////// ///////////////////
326 438
327 #ifdef GR_TEST_UTILS 439 #ifdef GR_TEST_UTILS
328 440
329 #include "GrBatchTest.h" 441 #include "GrBatchTest.h"
330 442
331 BATCH_TEST_DEFINE(AAFillRectBatch) { 443 BATCH_TEST_DEFINE(AAFillRectBatch) {
332 GrColor color = GrRandomColor(random); 444 AAFillRectBatchNoLocalMatrix* batch = AAFillRectBatchNoLocalMatrix::Create() ;
333 SkMatrix viewMatrix = GrTest::TestMatrix(random); 445 AAFillRectBatchNoLocalMatrix::Geometry& geo = *batch->geometry();
334 SkRect rect = GrTest::TestRect(random); 446 geo.fColor = GrRandomColor(random);
335 SkRect devRect = GrTest::TestRect(random); 447 geo.fViewMatrix = GrTest::TestMatrix(random);
336 return AAFillRectBatch::Create(color, viewMatrix, rect, devRect); 448 geo.fRect = GrTest::TestRect(random);
449 geo.fDevRect = GrTest::TestRect(random);
450 batch->init();
451 return batch;
452 }
453
454 BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) {
455 AAFillRectBatchLocalMatrix* batch = AAFillRectBatchLocalMatrix::Create();
456 AAFillRectBatchLocalMatrix::Geometry& geo = *batch->geometry();
457 geo.fColor = GrRandomColor(random);
458 geo.fViewMatrix = GrTest::TestMatrix(random);
459 geo.fLocalMatrix = GrTest::TestMatrix(random);
460 geo.fRect = GrTest::TestRect(random);
461 geo.fDevRect = GrTest::TestRect(random);
462 batch->init();
463 return batch;
337 } 464 }
338 465
339 #endif 466 #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