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

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