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

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

Issue 1301603004: GrAAFillRectBatch holds onto GrPipelineOptimizations (Closed) Base URL: https://skia.googlesource.com/skia.git@master
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 | « no previous file | 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 "GrBatchFlushState.h" 10 #include "GrBatchFlushState.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect , 44 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect ,
45 gAAFillRectIndexBufferKey); 45 gAAFillRectIndexBufferKey);
46 } 46 }
47 47
48 /* 48 /*
49 * AAFillRectBatch is templated to optionally allow the insertion of an addition al 49 * AAFillRectBatch is templated to optionally allow the insertion of an addition al
50 * attribute for explicit local coordinates. 50 * attribute for explicit local coordinates.
51 * To use this template, an implementation must define the following static func tions: 51 * To use this template, an implementation must define the following static func tions:
52 * A Geometry struct 52 * A Geometry struct
53 * 53 *
54 * bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs, 54 * bool CanCombine(const Geometry& mine, const Geometry& theirs,
55 * bool usesLocalCoords) 55 * const GrPipelineOptimizations&)
56 * 56 *
57 * GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() 57 * const GrGeometryProcessor* CreateGP(const Geometry& seedGeometry,
58 * const GrPipelineOptimizations& opts)
58 * 59 *
59 * bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage, 60 * Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
60 * bool usesLocalCoords) 61 * const GrPipelineOptimizations& opts)
61 *
62 * void FillInAttributes(intptr_t startVertex, size_t vertexStride,
63 * SkPoint* fan0Position, const Geometry&)
64 */ 62 */
65 template <typename Base> 63 template <typename Base>
66 class AAFillRectBatch : public GrVertexBatch { 64 class AAFillRectBatch : public GrVertexBatch {
67 public: 65 public:
68 typedef typename Base::Geometry Geometry; 66 typedef typename Base::Geometry Geometry;
69 67
70 static AAFillRectBatch* Create() { 68 static AAFillRectBatch* Create() {
71 return SkNEW(AAFillRectBatch); 69 return SkNEW(AAFillRectBatch);
72 } 70 }
73 71
74 const char* name() const override { return "AAFillRectBatch"; } 72 const char* name() const override { return "AAFillRectBatch"; }
75 73
76 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 74 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
77 // When this is called on a batch, there is only one geometry bundle 75 // When this is called on a batch, there is only one geometry bundle
78 out->setKnownFourComponents(fGeoData[0].fColor); 76 out->setKnownFourComponents(fGeoData[0].fColor);
79 } 77 }
80 78
81 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 79 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
82 out->setUnknownSingleComponent(); 80 out->setUnknownSingleComponent();
83 } 81 }
84 82
85 void initBatchTracker(const GrPipelineOptimizations& opt) override { 83 void initBatchTracker(const GrPipelineOptimizations& opt) override {
86 // Handle any color overrides
87 if (!opt.readsColor()) {
88 fGeoData[0].fColor = GrColor_ILLEGAL;
89 }
90 opt.getOverrideColorIfSet(&fGeoData[0].fColor); 84 opt.getOverrideColorIfSet(&fGeoData[0].fColor);
91 85 fOpts = opt;
92 // setup batch properties
93 fBatch.fColorIgnored = !opt.readsColor();
94 fBatch.fColor = fGeoData[0].fColor;
95 fBatch.fUsesLocalCoords = opt.readsLocalCoords();
96 fBatch.fCoverageIgnored = !opt.readsCoverage();
97 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
98 } 86 }
99 87
100 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 88 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
101 89
102 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which 90 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which
103 // is used to seed the batch with its initial geometry. After seeding, the client should call 91 // is used to seed the batch with its initial geometry. After seeding, the client should call
104 // init() so the Batch can initialize itself 92 // init() so the Batch can initialize itself
105 Geometry* geometry() { return &fGeoData[0]; } 93 Geometry* geometry() { return &fGeoData[0]; }
106 void init() { 94 void init() {
107 const Geometry& geo = fGeoData[0]; 95 const Geometry& geo = fGeoData[0];
108 this->setBounds(geo.fDevRect); 96 this->setBounds(geo.fDevRect);
109 } 97 }
110 98
111 private: 99 private:
112 AAFillRectBatch() { 100 AAFillRectBatch() {
113 this->initClassID<AAFillRectBatch<Base>>(); 101 this->initClassID<AAFillRectBatch<Base>>();
114 102
115 // Push back an initial geometry 103 // Push back an initial geometry
116 fGeoData.push_back(); 104 fGeoData.push_back();
117 } 105 }
118 106
119 GrColor color() const { return fBatch.fColor; }
120 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
121 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover age; }
122 bool colorIgnored() const { return fBatch.fColorIgnored; }
123 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
124 bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
125
126 void onPrepareDraws(Target* target) override { 107 void onPrepareDraws(Target* target) override {
127 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); 108 SkAutoTUnref<const GrGeometryProcessor> gp(Base::CreateGP(this->seedGeom etry(), fOpts));
128
129 SkAutoTUnref<const GrGeometryProcessor> gp(CreateFillRectGP(canTweakAlph aForCoverage,
130 this->viewMa trix(),
131 this->usesLo calCoords(),
132 Base::LocalC oordsType(),
133 this->covera geIgnored()));
134 if (!gp) { 109 if (!gp) {
135 SkDebugf("Couldn't create GrGeometryProcessor\n"); 110 SkDebugf("Couldn't create GrGeometryProcessor\n");
136 return; 111 return;
137 } 112 }
138 113
139 target->initDraw(gp, this->pipeline()); 114 target->initDraw(gp, this->pipeline());
140 115
141 size_t vertexStride = gp->getVertexStride(); 116 size_t vertexStride = gp->getVertexStride();
142 SkASSERT(Base::StrideCheck(vertexStride, canTweakAlphaForCoverage,
143 this->usesLocalCoords()));
144 int instanceCount = fGeoData.count(); 117 int instanceCount = fGeoData.count();
145 118
146 SkAutoTUnref<const GrIndexBuffer> indexBuffer(get_index_buffer(target->r esourceProvider())); 119 SkAutoTUnref<const GrIndexBuffer> indexBuffer(get_index_buffer(target->r esourceProvider()));
147 InstancedHelper helper; 120 InstancedHelper helper;
148 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS tride, 121 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS tride,
149 indexBuffer, kVertsPerAAFillRect, kIndicesP erAAFillRect, 122 indexBuffer, kVertsPerAAFillRect, kIndicesP erAAFillRect,
150 instanceCount); 123 instanceCount);
151 if (!vertices || !indexBuffer) { 124 if (!vertices || !indexBuffer) {
152 SkDebugf("Could not allocate vertices\n"); 125 SkDebugf("Could not allocate vertices\n");
153 return; 126 return;
154 } 127 }
155 128
156 for (int i = 0; i < instanceCount; i++) { 129 for (int i = 0; i < instanceCount; i++) {
157 this->generateAAFillRectGeometry(vertices, 130 intptr_t verts = reinterpret_cast<intptr_t>(vertices) +
158 i * kVertsPerAAFillRect * vertexStr ide, 131 i * kVertsPerAAFillRect * vertexStride;
159 vertexStride, 132 Base::Tesselate(verts, vertexStride, fGeoData[i], fOpts);
160 fGeoData[i],
161 canTweakAlphaForCoverage);
162 } 133 }
163 helper.recordDraw(target); 134 helper.recordDraw(target);
164 } 135 }
165 136
137 const Geometry& seedGeometry() const { return fGeoData[0]; }
138
166 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 139 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
167 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); 140 AAFillRectBatch* that = t->cast<AAFillRectBatch>();
168 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), 141 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(),
169 that->bounds(), caps)) { 142 that->bounds(), caps)) {
170 return false; 143 return false;
171 } 144 }
172 145
173 if (!Base::CanCombineLocalCoords(this->viewMatrix(), that->viewMatrix(), 146 if (!Base::CanCombine(this->seedGeometry(), that->seedGeometry(), fOpts) ) {
174 this->usesLocalCoords())) {
175 return false; 147 return false;
176 } 148 }
177 149
178 if (this->color() != that->color()) {
179 fBatch.fColor = GrColor_ILLEGAL;
180 }
181
182 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to 150 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to
183 // not tweaking 151 // not tweaking
184 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage() ) { 152 if (fOpts.canTweakAlphaForCoverage() && !that->fOpts.canTweakAlphaForCov erage()) {
185 fBatch.fCanTweakAlphaForCoverage = false; 153 fOpts = that->fOpts;
186 } 154 }
187 155
188 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; 156 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
189 this->joinBounds(that->bounds()); 157 this->joinBounds(that->bounds());
190 return true; 158 return true;
191 } 159 }
192 160
193 void generateAAFillRectGeometry(void* vertices, 161 GrPipelineOptimizations fOpts;
194 size_t offset, 162 SkSTArray<1, Geometry, true> fGeoData;
195 size_t vertexStride, 163 };
196 const Geometry& args,
197 bool tweakAlphaForCoverage) const {
198 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
199 164
200 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); 165 static const GrGeometryProcessor* create_fill_rect_gp(
201 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); 166 const SkMatrix& viewMatrix,
167 const GrPipelineOptimizations& opts,
168 GrDefaultGeoProcFactory::LocalCoords::Typ e localCoordsType) {
169 using namespace GrDefaultGeoProcFactory;
202 170
203 SkScalar inset = SkMinScalar(args.fDevRect.width(), SK_Scalar1); 171 Color color(Color::kAttribute_Type);
204 inset = SK_ScalarHalf * SkMinScalar(inset, args.fDevRect.height()); 172 Coverage::Type coverageType;
173 // TODO remove coverage if coverage is ignored
174 /*if (coverageIgnored) {
175 coverageType = Coverage::kNone_Type;
176 } else*/ if (opts.canTweakAlphaForCoverage()) {
177 coverageType = Coverage::kSolid_Type;
178 } else {
179 coverageType = Coverage::kAttribute_Type;
180 }
181 Coverage coverage(coverageType);
205 182
206 if (args.fViewMatrix.rectStaysRect()) { 183 // We assume the caller has inverted the viewmatrix
207 set_inset_fan(fan0Pos, vertexStride, args.fDevRect, -SK_ScalarHalf, -SK_ScalarHalf); 184 if (LocalCoords::kHasExplicit_Type == localCoordsType) {
208 set_inset_fan(fan1Pos, vertexStride, args.fDevRect, inset, inset); 185 LocalCoords localCoords(localCoordsType);
186 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkM atrix::I());
187 } else {
188 LocalCoords localCoords(opts.readsLocalCoords() ? localCoordsType :
189 LocalCoords::kUnused_T ype);
190 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
191 }
192 }
193
194 static void generate_aa_fill_rect_geometry(intptr_t verts,
195 size_t vertexStride,
196 GrColor color,
197 const SkMatrix& viewMatrix,
198 const SkRect& rect,
199 const SkRect& devRect,
200 const GrPipelineOptimizations& opts,
201 const SkMatrix* localMatrix) {
202 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
203 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
204
205 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
206 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
207
208 if (viewMatrix.rectStaysRect()) {
209 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Scalar Half);
210 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset);
211 } else {
212 // compute transformed (1, 0) and (0, 1) vectors
213 SkVector vec[2] = {
214 { viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] },
215 { viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY] }
216 };
217
218 vec[0].normalize();
219 vec[0].scale(SK_ScalarHalf);
220 vec[1].normalize();
221 vec[1].scale(SK_ScalarHalf);
222
223 // create the rotated rect
224 fan0Pos->setRectFan(rect.fLeft, rect.fTop,
225 rect.fRight, rect.fBottom, vertexStride);
226 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
227
228 // Now create the inset points and then outset the original
229 // rotated points
230
231 // TL
232 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
233 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1 ];
234 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
235 // BL
236 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
237 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1 ];
238 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
239 // BR
240 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
241 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1 ];
242 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
243 // TR
244 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
245 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1 ];
246 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
247 }
248
249 if (localMatrix) {
250 SkMatrix invViewMatrix;
251 if (!viewMatrix.invert(&invViewMatrix)) {
252 SkASSERT(false);
253 invViewMatrix = SkMatrix::I();
254 }
255 SkMatrix localCoordMatrix;
256 localCoordMatrix.setConcat(*localMatrix, invViewMatrix);
257 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) + sizeof(GrColor));
258 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
259 }
260
261 bool tweakAlphaForCoverage = opts.canTweakAlphaForCoverage();
262
263 // Make verts point to vertex color and then set all the color and coverage vertex attrs
264 // values.
265 verts += sizeof(SkPoint);
266
267 // The coverage offset is always the last vertex attribute
268 intptr_t coverageOffset = vertexStride - sizeof(GrColor) - sizeof(SkPoint);
269 for (int i = 0; i < 4; ++i) {
270 if (tweakAlphaForCoverage) {
271 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
209 } else { 272 } else {
210 // compute transformed (1, 0) and (0, 1) vectors 273 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
211 SkVector vec[2] = { 274 *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = 0;
212 { args.fViewMatrix[SkMatrix::kMScaleX], args.fViewMatrix[SkMatrix: :kMSkewY] },
213 { args.fViewMatrix[SkMatrix::kMSkewX], args.fViewMatrix[SkMatrix: :kMScaleY] }
214 };
215
216 vec[0].normalize();
217 vec[0].scale(SK_ScalarHalf);
218 vec[1].normalize();
219 vec[1].scale(SK_ScalarHalf);
220
221 // create the rotated rect
222 fan0Pos->setRectFan(args.fRect.fLeft, args.fRect.fTop,
223 args.fRect.fRight, args.fRect.fBottom, vertexStr ide);
224 args.fViewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
225
226 // Now create the inset points and then outset the original
227 // rotated points
228
229 // TL
230 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
231 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + v ec[1];
232 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[ 1];
233 // BL
234 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
235 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - v ec[1];
236 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[ 1];
237 // BR
238 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
239 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - v ec[1];
240 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[ 1];
241 // TR
242 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
243 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + v ec[1];
244 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[ 1];
245 }
246
247 Base::FillInAttributes(verts, vertexStride, fan0Pos, args);
248
249 // Make verts point to vertex color and then set all the color and cover age vertex attrs
250 // values.
251 verts += sizeof(SkPoint);
252
253 // The coverage offset is always the last vertex attribute
254 intptr_t coverageOffset = vertexStride - sizeof(GrColor) - sizeof(SkPoin t);
255 for (int i = 0; i < 4; ++i) {
256 if (tweakAlphaForCoverage) {
257 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
258 } else {
259 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fCo lor;
260 *reinterpret_cast<float*>(verts + i * vertexStride + coverageOff set) = 0;
261 }
262 }
263
264 int scale;
265 if (inset < SK_ScalarHalf) {
266 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)) ;
267 SkASSERT(scale >= 0 && scale <= 255);
268 } else {
269 scale = 0xff;
270 }
271
272 verts += 4 * vertexStride;
273
274 float innerCoverage = GrNormalizeByteToFloat(scale);
275 GrColor scaledColor = (0xff == scale) ? args.fColor : SkAlphaMulQ(args.f Color, scale);
276
277 for (int i = 0; i < 4; ++i) {
278 if (tweakAlphaForCoverage) {
279 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledCo lor;
280 } else {
281 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fCo lor;
282 *reinterpret_cast<float*>(verts + i * vertexStride +
283 coverageOffset) = innerCoverage;
284 }
285 } 275 }
286 } 276 }
287 277
288 static const GrGeometryProcessor* CreateFillRectGP( 278 int scale;
289 bool tweakAlphaForCoverage, 279 if (inset < SK_ScalarHalf) {
290 const SkMatrix& viewMatrix, 280 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
291 bool usesLocalCoords, 281 SkASSERT(scale >= 0 && scale <= 255);
292 GrDefaultGeoProcFactory::LocalCoords::T ype localCoordsType, 282 } else {
293 bool coverageIgnored) { 283 scale = 0xff;
294 using namespace GrDefaultGeoProcFactory; 284 }
295 285
296 Color color(Color::kAttribute_Type); 286 verts += 4 * vertexStride;
297 Coverage::Type coverageType; 287
298 // TODO remove coverage if coverage is ignored 288 float innerCoverage = GrNormalizeByteToFloat(scale);
299 /*if (coverageIgnored) { 289 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
300 coverageType = Coverage::kNone_Type; 290
301 } else*/ if (tweakAlphaForCoverage) { 291 for (int i = 0; i < 4; ++i) {
302 coverageType = Coverage::kSolid_Type; 292 if (tweakAlphaForCoverage) {
293 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
303 } else { 294 } else {
304 coverageType = Coverage::kAttribute_Type; 295 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
305 } 296 *reinterpret_cast<float*>(verts + i * vertexStride +
306 Coverage coverage(coverageType); 297 coverageOffset) = innerCoverage;
307
308 // We assume the caller has inverted the viewmatrix
309 if (LocalCoords::kHasExplicit_Type == localCoordsType) {
310 LocalCoords localCoords(localCoordsType);
311 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I());
312 } else {
313 LocalCoords localCoords(usesLocalCoords ? localCoordsType : LocalCoo rds::kUnused_Type);
314 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix );
315 } 298 }
316 } 299 }
317 300 }
318 struct BatchTracker {
319 GrColor fColor;
320 bool fUsesLocalCoords;
321 bool fColorIgnored;
322 bool fCoverageIgnored;
323 bool fCanTweakAlphaForCoverage;
324 };
325
326 BatchTracker fBatch;
327 SkSTArray<1, Geometry, true> fGeoData;
328 };
329 301
330 class AAFillRectBatchNoLocalMatrixImp { 302 class AAFillRectBatchNoLocalMatrixImp {
331 public: 303 public:
332 struct Geometry { 304 struct Geometry {
333 SkMatrix fViewMatrix; 305 SkMatrix fViewMatrix;
334 SkRect fRect; 306 SkRect fRect;
335 SkRect fDevRect; 307 SkRect fDevRect;
336 GrColor fColor; 308 GrColor fColor;
337 }; 309 };
338 310
339 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs, 311 inline static bool CanCombine(const Geometry& mine, const Geometry& theirs,
340 bool usesLocalCoords) { 312 const GrPipelineOptimizations& opts) {
341 // We apply the viewmatrix to the rect points on the cpu. However, if t he pipeline uses 313 // We apply the viewmatrix to the rect points on the cpu. However, if t he pipeline uses
342 // local coords then we won't be able to batch. We could actually uploa d the viewmatrix 314 // local coords then we won't be able to batch. We could actually uploa d the viewmatrix
343 // using vertex attributes in these cases, but haven't investigated that 315 // using vertex attributes in these cases, but haven't investigated that
344 return !usesLocalCoords || mine.cheapEqualTo(theirs); 316 return !opts.readsLocalCoords() || mine.fViewMatrix.cheapEqualTo(theirs. fViewMatrix);
345 } 317 }
346 318
347 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() { 319 inline static const GrGeometryProcessor* CreateGP(const Geometry& geo,
348 return GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type; 320 const GrPipelineOptimizati ons& opts) {
321 const GrGeometryProcessor* gp =
322 create_fill_rect_gp(geo.fViewMatrix, opts,
323 GrDefaultGeoProcFactory::LocalCoords::kUsePo sition_Type);
324
325 SkASSERT(opts.canTweakAlphaForCoverage() ?
326 gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi onColorAttr) :
327 gp->getVertexStride() ==
328 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAt tr));
329 return gp;
349 } 330 }
350 331
351 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCov erage, 332 inline static void Tesselate(intptr_t vertices, size_t vertexStride, const G eometry& geo,
352 bool usesLocalCoords) { 333 const GrPipelineOptimizations& opts) {
353 return canTweakAlphaForCoverage ? 334 generate_aa_fill_rect_geometry(vertices, vertexStride,
354 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr) : 335 geo.fColor, geo.fViewMatrix, geo.fRect, g eo.fDevRect, opts,
355 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo verageAttr); 336 NULL);
356 } 337 }
357
358 inline static void FillInAttributes(intptr_t, size_t, SkPoint*, const Geomet ry&) {}
359 }; 338 };
360 339
361 class AAFillRectBatchLocalMatrixImp { 340 class AAFillRectBatchLocalMatrixImp {
362 public: 341 public:
363 struct Geometry { 342 struct Geometry {
364 SkMatrix fViewMatrix; 343 SkMatrix fViewMatrix;
365 SkMatrix fLocalMatrix; 344 SkMatrix fLocalMatrix;
366 SkRect fRect; 345 SkRect fRect;
367 SkRect fDevRect; 346 SkRect fDevRect;
368 GrColor fColor; 347 GrColor fColor;
369 }; 348 };
370 349
371 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs, 350 inline static bool CanCombine(const Geometry& mine, const Geometry& theirs,
372 bool usesLocalCoords) { 351 const GrPipelineOptimizations&) {
373 return true; 352 return true;
374 } 353 }
375 354
376 inline static GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() { 355 inline static const GrGeometryProcessor* CreateGP(const Geometry& geo,
377 return GrDefaultGeoProcFactory::LocalCoords::kHasExplicit_Type; 356 const GrPipelineOptimizati ons& opts) {
357 const GrGeometryProcessor* gp =
358 create_fill_rect_gp(geo.fViewMatrix, opts,
359 GrDefaultGeoProcFactory::LocalCoords::kHasEx plicit_Type);
360
361 SkASSERT(opts.canTweakAlphaForCoverage() ?
362 gp->getVertexStride() ==
363 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoord Attr) :
364 gp->getVertexStride() ==
365 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoord Coverage));
366 return gp;
378 } 367 }
379 368
380 inline static bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCov erage, 369 inline static void Tesselate(intptr_t vertices, size_t vertexStride, const G eometry& geo,
381 bool usesLocalCoords) { 370 const GrPipelineOptimizations& opts) {
382 // Whomever created us should not have done so if there are no local coo rds 371 generate_aa_fill_rect_geometry(vertices, vertexStride,
383 return canTweakAlphaForCoverage ? 372 geo.fColor, geo.fViewMatrix, geo.fRect, g eo.fDevRect, opts,
384 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordAttr) : 373 &geo.fLocalMatrix);
385 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordCoverage);
386 }
387
388 inline static void FillInAttributes(intptr_t vertices, size_t vertexStride,
389 SkPoint* fan0Pos, const Geometry& args) {
390 SkMatrix invViewMatrix;
391 if (!args.fViewMatrix.invert(&invViewMatrix)) {
392 SkASSERT(false);
393 invViewMatrix = SkMatrix::I();
394 }
395 SkMatrix localCoordMatrix;
396 localCoordMatrix.setConcat(args.fLocalMatrix, invViewMatrix);
397 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(vertices + sizeof(SkPoint) + sizeof(GrColor));
398 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
399 } 374 }
400 }; 375 };
401 376
402 typedef AAFillRectBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalM atrix; 377 typedef AAFillRectBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalM atrix;
403 typedef AAFillRectBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatri x; 378 typedef AAFillRectBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatri x;
404 379
405 namespace GrAAFillRectBatch { 380 namespace GrAAFillRectBatch {
406 381
407 GrDrawBatch* Create(GrColor color, 382 GrDrawBatch* Create(GrColor color,
408 const SkMatrix& viewMatrix, 383 const SkMatrix& viewMatrix,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { 428 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) {
454 GrColor color = GrRandomColor(random); 429 GrColor color = GrRandomColor(random);
455 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); 430 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
456 SkMatrix localMatrix = GrTest::TestMatrix(random); 431 SkMatrix localMatrix = GrTest::TestMatrix(random);
457 SkRect rect = GrTest::TestRect(random); 432 SkRect rect = GrTest::TestRect(random);
458 SkRect devRect = GrTest::TestRect(random); 433 SkRect devRect = GrTest::TestRect(random);
459 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe ct); 434 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe ct);
460 } 435 }
461 436
462 #endif 437 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698