OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrAARectRenderer.h" | 8 #include "GrAARectRenderer.h" |
9 #include "GrBatch.h" | 9 #include "GrBatch.h" |
10 #include "GrBatchTarget.h" | 10 #include "GrBatchTarget.h" |
11 #include "GrBatchTest.h" | 11 #include "GrBatchTest.h" |
12 #include "GrBufferAllocPool.h" | 12 #include "GrBufferAllocPool.h" |
13 #include "GrContext.h" | 13 #include "GrContext.h" |
14 #include "GrDefaultGeoProcFactory.h" | 14 #include "GrDefaultGeoProcFactory.h" |
15 #include "GrGeometryProcessor.h" | 15 #include "GrGeometryProcessor.h" |
| 16 #include "GrGpu.h" |
16 #include "GrInvariantOutput.h" | 17 #include "GrInvariantOutput.h" |
17 #include "GrResourceKey.h" | 18 #include "GrVertexBuffer.h" |
18 #include "GrResourceProvider.h" | |
19 #include "GrTestUtils.h" | 19 #include "GrTestUtils.h" |
20 #include "GrVertexBuffer.h" | |
21 #include "SkColorPriv.h" | 20 #include "SkColorPriv.h" |
22 #include "gl/GrGLProcessor.h" | 21 #include "gl/GrGLProcessor.h" |
23 #include "gl/GrGLGeometryProcessor.h" | 22 #include "gl/GrGLGeometryProcessor.h" |
24 #include "gl/builders/GrGLProgramBuilder.h" | 23 #include "gl/builders/GrGLProgramBuilder.h" |
25 | 24 |
26 /////////////////////////////////////////////////////////////////////////////// | 25 /////////////////////////////////////////////////////////////////////////////// |
27 | 26 |
28 static void set_inset_fan(SkPoint* pts, size_t stride, | 27 static void set_inset_fan(SkPoint* pts, size_t stride, |
29 const SkRect& r, SkScalar dx, SkScalar dy) { | 28 const SkRect& r, SkScalar dx, SkScalar dy) { |
30 pts->setRectFan(r.fLeft + dx, r.fTop + dy, | 29 pts->setRectFan(r.fLeft + dx, r.fTop + dy, |
31 r.fRight - dx, r.fBottom - dy, stride); | 30 r.fRight - dx, r.fBottom - dy, stride); |
32 } | 31 } |
33 | 32 |
| 33 static const uint16_t gFillAARectIdx[] = { |
| 34 0, 1, 5, 5, 4, 0, |
| 35 1, 2, 6, 6, 5, 1, |
| 36 2, 3, 7, 7, 6, 2, |
| 37 3, 0, 4, 4, 7, 3, |
| 38 4, 5, 6, 6, 7, 4, |
| 39 }; |
| 40 |
| 41 static const int kIndicesPerAAFillRect = SK_ARRAY_COUNT(gFillAARectIdx); |
| 42 static const int kVertsPerAAFillRect = 8; |
| 43 static const int kNumAAFillRectsInIndexBuffer = 256; |
| 44 |
34 static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage
, | 45 static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage
, |
35 const SkMatrix& localMatri
x) { | 46 const SkMatrix& localMatri
x) { |
36 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; | 47 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; |
37 const GrGeometryProcessor* gp; | 48 const GrGeometryProcessor* gp; |
38 if (tweakAlphaForCoverage) { | 49 if (tweakAlphaForCoverage) { |
39 gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I()
, localMatrix, | 50 gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I()
, localMatrix, |
40 false, 0xff); | 51 false, 0xff); |
41 } else { | 52 } else { |
42 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; | 53 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; |
43 gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I()
, localMatrix, | 54 gp = GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I()
, localMatrix, |
44 false, 0xff); | 55 false, 0xff); |
45 } | 56 } |
46 return gp; | 57 return gp; |
47 } | 58 } |
48 | 59 |
49 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); | |
50 | |
51 class AAFillRectBatch : public GrBatch { | 60 class AAFillRectBatch : public GrBatch { |
52 public: | 61 public: |
53 struct Geometry { | 62 struct Geometry { |
54 GrColor fColor; | 63 GrColor fColor; |
55 SkMatrix fViewMatrix; | 64 SkMatrix fViewMatrix; |
56 SkRect fRect; | 65 SkRect fRect; |
57 SkRect fDevRect; | 66 SkRect fDevRect; |
58 }; | 67 }; |
59 | 68 |
60 static GrBatch* Create(const Geometry& geometry) { | 69 static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexB
uffer) { |
61 return SkNEW_ARGS(AAFillRectBatch, (geometry)); | 70 return SkNEW_ARGS(AAFillRectBatch, (geometry, indexBuffer)); |
62 } | 71 } |
63 | 72 |
64 const char* name() const override { return "AAFillRectBatch"; } | 73 const char* name() const override { return "AAFillRectBatch"; } |
65 | 74 |
66 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 75 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
67 // When this is called on a batch, there is only one geometry bundle | 76 // When this is called on a batch, there is only one geometry bundle |
68 out->setKnownFourComponents(fGeoData[0].fColor); | 77 out->setKnownFourComponents(fGeoData[0].fColor); |
69 } | 78 } |
70 | 79 |
71 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 80 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 // TODO this is hacky, but the only way we have to initialize the GP is
to use the | 114 // TODO this is hacky, but the only way we have to initialize the GP is
to use the |
106 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 115 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
107 // everywhere we can remove this nastiness | 116 // everywhere we can remove this nastiness |
108 GrPipelineInfo init; | 117 GrPipelineInfo init; |
109 init.fColorIgnored = fBatch.fColorIgnored; | 118 init.fColorIgnored = fBatch.fColorIgnored; |
110 init.fOverrideColor = GrColor_ILLEGAL; | 119 init.fOverrideColor = GrColor_ILLEGAL; |
111 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 120 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
112 init.fUsesLocalCoords = this->usesLocalCoords(); | 121 init.fUsesLocalCoords = this->usesLocalCoords(); |
113 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 122 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
114 | 123 |
115 SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer( | 124 size_t vertexStride = gp->getVertexStride(); |
116 batchTarget->resourceProvider())); | |
117 | 125 |
118 size_t vertexStride = gp->getVertexStride(); | |
119 SkASSERT(canTweakAlphaForCoverage ? | 126 SkASSERT(canTweakAlphaForCoverage ? |
120 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr) : | 127 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr) : |
121 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo
verageAttr)); | 128 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo
verageAttr)); |
| 129 |
122 int instanceCount = fGeoData.count(); | 130 int instanceCount = fGeoData.count(); |
123 int vertexCount = kVertsPerAAFillRect * instanceCount; | 131 int vertexCount = kVertsPerAAFillRect * instanceCount; |
| 132 |
124 const GrVertexBuffer* vertexBuffer; | 133 const GrVertexBuffer* vertexBuffer; |
125 int firstVertex; | 134 int firstVertex; |
| 135 |
126 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 136 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
127 vertexCount, | 137 vertexCount, |
128 &vertexBuffer, | 138 &vertexBuffer, |
129 &firstVertex); | 139 &firstVertex); |
130 | 140 |
131 if (!vertices || !indexBuffer) { | 141 if (!vertices) { |
132 SkDebugf("Could not allocate vertices\n"); | 142 SkDebugf("Could not allocate vertices\n"); |
133 return; | 143 return; |
134 } | 144 } |
135 | 145 |
136 for (int i = 0; i < instanceCount; i++) { | 146 for (int i = 0; i < instanceCount; i++) { |
137 const Geometry& args = fGeoData[i]; | 147 const Geometry& args = fGeoData[i]; |
138 this->generateAAFillRectGeometry(vertices, | 148 this->generateAAFillRectGeometry(vertices, |
139 i * kVertsPerAAFillRect * vertexStr
ide, | 149 i * kVertsPerAAFillRect * vertexStr
ide, |
140 vertexStride, | 150 vertexStride, |
141 args.fColor, | 151 args.fColor, |
142 args.fViewMatrix, | 152 args.fViewMatrix, |
143 args.fRect, | 153 args.fRect, |
144 args.fDevRect, | 154 args.fDevRect, |
145 canTweakAlphaForCoverage); | 155 canTweakAlphaForCoverage); |
146 } | 156 } |
147 | 157 |
148 GrDrawTarget::DrawInfo drawInfo; | 158 GrDrawTarget::DrawInfo drawInfo; |
149 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | 159 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
150 drawInfo.setStartVertex(0); | 160 drawInfo.setStartVertex(0); |
151 drawInfo.setStartIndex(0); | 161 drawInfo.setStartIndex(0); |
152 drawInfo.setVerticesPerInstance(kVertsPerAAFillRect); | 162 drawInfo.setVerticesPerInstance(kVertsPerAAFillRect); |
153 drawInfo.setIndicesPerInstance(kIndicesPerAAFillRect); | 163 drawInfo.setIndicesPerInstance(kIndicesPerAAFillRect); |
154 drawInfo.adjustStartVertex(firstVertex); | 164 drawInfo.adjustStartVertex(firstVertex); |
155 drawInfo.setVertexBuffer(vertexBuffer); | 165 drawInfo.setVertexBuffer(vertexBuffer); |
156 drawInfo.setIndexBuffer(indexBuffer); | 166 drawInfo.setIndexBuffer(fIndexBuffer); |
157 | 167 |
158 int maxInstancesPerDraw = kNumAAFillRectsInIndexBuffer; | 168 int maxInstancesPerDraw = kNumAAFillRectsInIndexBuffer; |
159 | 169 |
160 while (instanceCount) { | 170 while (instanceCount) { |
161 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | 171 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
162 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | 172 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
163 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | 173 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
164 | 174 |
165 batchTarget->draw(drawInfo); | 175 batchTarget->draw(drawInfo); |
166 | 176 |
167 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 177 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
168 instanceCount -= drawInfo.instanceCount(); | 178 instanceCount -= drawInfo.instanceCount(); |
169 } | 179 } |
170 } | 180 } |
171 | 181 |
172 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 182 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
173 | 183 |
174 private: | 184 private: |
175 AAFillRectBatch(const Geometry& geometry) { | 185 AAFillRectBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer) |
| 186 : fIndexBuffer(indexBuffer) { |
176 this->initClassID<AAFillRectBatch>(); | 187 this->initClassID<AAFillRectBatch>(); |
177 fGeoData.push_back(geometry); | 188 fGeoData.push_back(geometry); |
178 | 189 |
179 this->setBounds(geometry.fDevRect); | 190 this->setBounds(geometry.fDevRect); |
180 } | 191 } |
181 | 192 |
182 static const int kNumAAFillRectsInIndexBuffer = 256; | |
183 static const int kVertsPerAAFillRect = 8; | |
184 static const int kIndicesPerAAFillRect = 30; | |
185 | |
186 const GrIndexBuffer* getIndexBuffer(GrResourceProvider* resourceProvider) { | |
187 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); | |
188 | |
189 static const uint16_t gFillAARectIdx[] = { | |
190 0, 1, 5, 5, 4, 0, | |
191 1, 2, 6, 6, 5, 1, | |
192 2, 3, 7, 7, 6, 2, | |
193 3, 0, 4, 4, 7, 3, | |
194 4, 5, 6, 6, 7, 4, | |
195 }; | |
196 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect
); | |
197 return resourceProvider->refOrCreateInstancedIndexBuffer(gFillAARectIdx, | |
198 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFill
Rect, | |
199 gAAFillRectIndexBufferKey); | |
200 } | |
201 | |
202 GrColor color() const { return fBatch.fColor; } | 193 GrColor color() const { return fBatch.fColor; } |
203 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 194 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
204 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } | 195 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } |
205 bool colorIgnored() const { return fBatch.fColorIgnored; } | 196 bool colorIgnored() const { return fBatch.fColorIgnored; } |
206 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 197 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
207 | 198 |
208 bool onCombineIfPossible(GrBatch* t) override { | 199 bool onCombineIfPossible(GrBatch* t) override { |
209 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); | 200 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); |
210 | 201 |
211 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | 202 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 317 |
327 struct BatchTracker { | 318 struct BatchTracker { |
328 GrColor fColor; | 319 GrColor fColor; |
329 bool fUsesLocalCoords; | 320 bool fUsesLocalCoords; |
330 bool fColorIgnored; | 321 bool fColorIgnored; |
331 bool fCoverageIgnored; | 322 bool fCoverageIgnored; |
332 bool fCanTweakAlphaForCoverage; | 323 bool fCanTweakAlphaForCoverage; |
333 }; | 324 }; |
334 | 325 |
335 BatchTracker fBatch; | 326 BatchTracker fBatch; |
| 327 const GrIndexBuffer* fIndexBuffer; |
336 SkSTArray<1, Geometry, true> fGeoData; | 328 SkSTArray<1, Geometry, true> fGeoData; |
337 }; | 329 }; |
338 | 330 |
339 namespace { | 331 namespace { |
340 // Should the coverage be multiplied into the color attrib or use a separate att
rib. | 332 // Should the coverage be multiplied into the color attrib or use a separate att
rib. |
341 enum CoverageAttribType { | 333 enum CoverageAttribType { |
342 kUseColor_CoverageAttribType, | 334 kUseColor_CoverageAttribType, |
343 kUseCoverage_CoverageAttribType, | 335 kUseCoverage_CoverageAttribType, |
344 }; | 336 }; |
345 } | 337 } |
346 | 338 |
| 339 void GrAARectRenderer::reset() { |
| 340 SkSafeSetNull(fAAFillRectIndexBuffer); |
| 341 SkSafeSetNull(fAAMiterStrokeRectIndexBuffer); |
| 342 SkSafeSetNull(fAABevelStrokeRectIndexBuffer); |
| 343 } |
| 344 |
| 345 static const uint16_t gMiterStrokeAARectIdx[] = { |
| 346 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, |
| 347 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, |
| 348 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, |
| 349 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, |
| 350 |
| 351 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, |
| 352 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, |
| 353 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, |
| 354 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, |
| 355 |
| 356 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, |
| 357 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, |
| 358 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, |
| 359 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, |
| 360 }; |
| 361 |
| 362 static const int kIndicesPerMiterStrokeRect = SK_ARRAY_COUNT(gMiterStrokeAARectI
dx); |
| 363 static const int kVertsPerMiterStrokeRect = 16; |
| 364 static const int kNumMiterStrokeRectsInIndexBuffer = 256; |
| 365 |
| 366 /** |
| 367 * As in miter-stroke, index = a + b, and a is the current index, b is the shift |
| 368 * from the first index. The index layout: |
| 369 * outer AA line: 0~3, 4~7 |
| 370 * outer edge: 8~11, 12~15 |
| 371 * inner edge: 16~19 |
| 372 * inner AA line: 20~23 |
| 373 * Following comes a bevel-stroke rect and its indices: |
| 374 * |
| 375 * 4 7 |
| 376 * ********************************* |
| 377 * * ______________________________ * |
| 378 * * / 12 15 \ * |
| 379 * * / \ * |
| 380 * 0 * |8 16_____________________19 11 | * 3 |
| 381 * * | | | | * |
| 382 * * | | **************** | | * |
| 383 * * | | * 20 23 * | | * |
| 384 * * | | * * | | * |
| 385 * * | | * 21 22 * | | * |
| 386 * * | | **************** | | * |
| 387 * * | |____________________| | * |
| 388 * 1 * |9 17 18 10| * 2 |
| 389 * * \ / * |
| 390 * * \13 __________________________14/ * |
| 391 * * * |
| 392 * ********************************** |
| 393 * 5 6 |
| 394 */ |
| 395 static const uint16_t gBevelStrokeAARectIdx[] = { |
| 396 // Draw outer AA, from outer AA line to outer edge, shift is 0. |
| 397 0 + 0, 1 + 0, 9 + 0, 9 + 0, 8 + 0, 0 + 0, |
| 398 1 + 0, 5 + 0, 13 + 0, 13 + 0, 9 + 0, 1 + 0, |
| 399 5 + 0, 6 + 0, 14 + 0, 14 + 0, 13 + 0, 5 + 0, |
| 400 6 + 0, 2 + 0, 10 + 0, 10 + 0, 14 + 0, 6 + 0, |
| 401 2 + 0, 3 + 0, 11 + 0, 11 + 0, 10 + 0, 2 + 0, |
| 402 3 + 0, 7 + 0, 15 + 0, 15 + 0, 11 + 0, 3 + 0, |
| 403 7 + 0, 4 + 0, 12 + 0, 12 + 0, 15 + 0, 7 + 0, |
| 404 4 + 0, 0 + 0, 8 + 0, 8 + 0, 12 + 0, 4 + 0, |
| 405 |
| 406 // Draw the stroke, from outer edge to inner edge, shift is 8. |
| 407 0 + 8, 1 + 8, 9 + 8, 9 + 8, 8 + 8, 0 + 8, |
| 408 1 + 8, 5 + 8, 9 + 8, |
| 409 5 + 8, 6 + 8, 10 + 8, 10 + 8, 9 + 8, 5 + 8, |
| 410 6 + 8, 2 + 8, 10 + 8, |
| 411 2 + 8, 3 + 8, 11 + 8, 11 + 8, 10 + 8, 2 + 8, |
| 412 3 + 8, 7 + 8, 11 + 8, |
| 413 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8, |
| 414 4 + 8, 0 + 8, 8 + 8, |
| 415 |
| 416 // Draw the inner AA, from inner edge to inner AA line, shift is 16. |
| 417 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16, |
| 418 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16, |
| 419 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16, |
| 420 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16, |
| 421 }; |
| 422 |
| 423 static const int kIndicesPerBevelStrokeRect = SK_ARRAY_COUNT(gBevelStrokeAARectI
dx); |
| 424 static const int kVertsPerBevelStrokeRect = 24; |
| 425 static const int kNumBevelStrokeRectsInIndexBuffer = 256; |
| 426 |
| 427 static int aa_stroke_rect_index_count(bool miterStroke) { |
| 428 return miterStroke ? SK_ARRAY_COUNT(gMiterStrokeAARectIdx) : |
| 429 SK_ARRAY_COUNT(gBevelStrokeAARectIdx); |
| 430 } |
| 431 |
| 432 static GrIndexBuffer* setup_aa_stroke_rect_indexbuffer(GrIndexBuffer** aaMiterSt
rokeRectIndexBuffer, |
| 433 GrIndexBuffer** aaBevelSt
rokeRectIndexBuffer, |
| 434 GrGpu* gpu, |
| 435 bool miterStroke) { |
| 436 if (miterStroke) { |
| 437 if (!*aaMiterStrokeRectIndexBuffer) { |
| 438 *aaMiterStrokeRectIndexBuffer = |
| 439 gpu->createInstancedIndexBuffer(gMiterStrokeAARectIdx, |
| 440 kIndicesPerMiterStrokeRect, |
| 441 kNumMiterStrokeRectsInIndexB
uffer, |
| 442 kVertsPerMiterStrokeRect); |
| 443 } |
| 444 return *aaMiterStrokeRectIndexBuffer; |
| 445 } else { |
| 446 if (!*aaBevelStrokeRectIndexBuffer) { |
| 447 *aaBevelStrokeRectIndexBuffer = |
| 448 gpu->createInstancedIndexBuffer(gBevelStrokeAARectIdx, |
| 449 kIndicesPerBevelStrokeRect, |
| 450 kNumBevelStrokeRectsInIndexB
uffer, |
| 451 kVertsPerBevelStrokeRect); |
| 452 } |
| 453 return *aaBevelStrokeRectIndexBuffer; |
| 454 } |
| 455 } |
| 456 |
347 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, | 457 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, |
348 GrPipelineBuilder* pipelineBuilder, | 458 GrPipelineBuilder* pipelineBuilder, |
349 GrColor color, | 459 GrColor color, |
350 const SkMatrix& viewMatrix, | 460 const SkMatrix& viewMatrix, |
351 const SkRect& rect, | 461 const SkRect& rect, |
352 const SkRect& devRect) { | 462 const SkRect& devRect) { |
| 463 if (!fAAFillRectIndexBuffer) { |
| 464 fAAFillRectIndexBuffer = fGpu->createInstancedIndexBuffer(gFillAARectIdx
, |
| 465 kIndicesPerAAF
illRect, |
| 466 kNumAAFillRect
sInIndexBuffer, |
| 467 kVertsPerAAFil
lRect); |
| 468 } |
| 469 |
| 470 if (!fAAFillRectIndexBuffer) { |
| 471 SkDebugf("Unable to create index buffer\n"); |
| 472 return; |
| 473 } |
| 474 |
353 AAFillRectBatch::Geometry geometry; | 475 AAFillRectBatch::Geometry geometry; |
354 geometry.fRect = rect; | 476 geometry.fRect = rect; |
355 geometry.fViewMatrix = viewMatrix; | 477 geometry.fViewMatrix = viewMatrix; |
356 geometry.fDevRect = devRect; | 478 geometry.fDevRect = devRect; |
357 geometry.fColor = color; | 479 geometry.fColor = color; |
358 | 480 |
359 | 481 SkAutoTUnref<GrBatch> batch(AAFillRectBatch::Create(geometry, fAAFillRectInd
exBuffer)); |
360 SkAutoTUnref<GrBatch> batch(AAFillRectBatch::Create(geometry)); | |
361 target->drawBatch(pipelineBuilder, batch); | 482 target->drawBatch(pipelineBuilder, batch); |
362 } | 483 } |
363 | 484 |
364 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 485 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |
365 GrPipelineBuilder* pipelineBuilder, | 486 GrPipelineBuilder* pipelineBuilder, |
366 GrColor color, | 487 GrColor color, |
367 const SkMatrix& viewMatrix, | 488 const SkMatrix& viewMatrix, |
368 const SkRect& rect, | 489 const SkRect& rect, |
369 const SkRect& devRect, | 490 const SkRect& devRect, |
370 const SkStrokeRec& stroke) { | 491 const SkStrokeRec& stroke) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 // edge, while vertex number of inner edge is 4, the same as miter-stroke. | 537 // edge, while vertex number of inner edge is 4, the same as miter-stroke. |
417 if (!miterStroke) { | 538 if (!miterStroke) { |
418 devOutside.inset(0, ry); | 539 devOutside.inset(0, ry); |
419 devOutsideAssist.outset(0, ry); | 540 devOutsideAssist.outset(0, ry); |
420 } | 541 } |
421 | 542 |
422 this->geometryStrokeAARect(target, pipelineBuilder, color, viewMatrix, devOu
tside, | 543 this->geometryStrokeAARect(target, pipelineBuilder, color, viewMatrix, devOu
tside, |
423 devOutsideAssist, devInside, miterStroke); | 544 devOutsideAssist, devInside, miterStroke); |
424 } | 545 } |
425 | 546 |
426 GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); | |
427 GR_DECLARE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); | |
428 | |
429 class AAStrokeRectBatch : public GrBatch { | 547 class AAStrokeRectBatch : public GrBatch { |
430 public: | 548 public: |
431 // TODO support AA rotated stroke rects by copying around view matrices | 549 // TODO support AA rotated stroke rects by copying around view matrices |
432 struct Geometry { | 550 struct Geometry { |
433 GrColor fColor; | 551 GrColor fColor; |
434 SkRect fDevOutside; | 552 SkRect fDevOutside; |
435 SkRect fDevOutsideAssist; | 553 SkRect fDevOutsideAssist; |
436 SkRect fDevInside; | 554 SkRect fDevInside; |
437 bool fMiterStroke; | 555 bool fMiterStroke; |
438 }; | 556 }; |
439 | 557 |
440 static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix)
{ | 558 static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix, |
441 return SkNEW_ARGS(AAStrokeRectBatch, (geometry, viewMatrix)); | 559 const GrIndexBuffer* indexBuffer) { |
| 560 return SkNEW_ARGS(AAStrokeRectBatch, (geometry, viewMatrix, indexBuffer)
); |
442 } | 561 } |
443 | 562 |
444 const char* name() const override { return "AAStrokeRect"; } | 563 const char* name() const override { return "AAStrokeRect"; } |
445 | 564 |
446 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 565 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
447 // When this is called on a batch, there is only one geometry bundle | 566 // When this is called on a batch, there is only one geometry bundle |
448 out->setKnownFourComponents(fGeoData[0].fColor); | 567 out->setKnownFourComponents(fGeoData[0].fColor); |
449 } | 568 } |
450 | 569 |
451 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 570 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
(...skipping 26 matching lines...) Expand all Loading... |
478 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix))
{ | 597 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix))
{ |
479 SkDebugf("Cannot invert\n"); | 598 SkDebugf("Cannot invert\n"); |
480 return; | 599 return; |
481 } | 600 } |
482 | 601 |
483 SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakA
lphaForCoverage, | 602 SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakA
lphaForCoverage, |
484 localMatr
ix)); | 603 localMatr
ix)); |
485 | 604 |
486 batchTarget->initDraw(gp, pipeline); | 605 batchTarget->initDraw(gp, pipeline); |
487 | 606 |
488 const SkAutoTUnref<const GrIndexBuffer> indexBuffer( | |
489 GetIndexBuffer(batchTarget->resourceProvider(), this->miterStroke())
); | |
490 | |
491 // TODO this is hacky, but the only way we have to initialize the GP is
to use the | 607 // TODO this is hacky, but the only way we have to initialize the GP is
to use the |
492 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 608 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
493 // everywhere we can remove this nastiness | 609 // everywhere we can remove this nastiness |
494 GrPipelineInfo init; | 610 GrPipelineInfo init; |
495 init.fColorIgnored = fBatch.fColorIgnored; | 611 init.fColorIgnored = fBatch.fColorIgnored; |
496 init.fOverrideColor = GrColor_ILLEGAL; | 612 init.fOverrideColor = GrColor_ILLEGAL; |
497 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 613 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
498 init.fUsesLocalCoords = this->usesLocalCoords(); | 614 init.fUsesLocalCoords = this->usesLocalCoords(); |
499 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 615 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
500 | 616 |
501 size_t vertexStride = gp->getVertexStride(); | 617 size_t vertexStride = gp->getVertexStride(); |
502 | 618 |
503 SkASSERT(canTweakAlphaForCoverage ? | 619 SkASSERT(canTweakAlphaForCoverage ? |
504 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr) : | 620 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr) : |
505 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo
verageAttr)); | 621 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo
verageAttr)); |
| 622 |
506 int innerVertexNum = 4; | 623 int innerVertexNum = 4; |
507 int outerVertexNum = this->miterStroke() ? 4 : 8; | 624 int outerVertexNum = this->miterStroke() ? 4 : 8; |
508 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; | 625 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; |
509 | 626 |
510 int instanceCount = fGeoData.count(); | 627 int instanceCount = fGeoData.count(); |
511 int vertexCount = totalVertexNum * instanceCount; | 628 int vertexCount = totalVertexNum * instanceCount; |
512 | 629 |
513 const GrVertexBuffer* vertexBuffer; | 630 const GrVertexBuffer* vertexBuffer; |
514 int firstVertex; | 631 int firstVertex; |
515 | 632 |
516 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 633 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
517 vertexCount, | 634 vertexCount, |
518 &vertexBuffer, | 635 &vertexBuffer, |
519 &firstVertex); | 636 &firstVertex); |
520 | 637 |
521 if (!vertices || !indexBuffer) { | 638 if (!vertices) { |
522 SkDebugf("Could not allocate vertices\n"); | 639 SkDebugf("Could not allocate vertices\n"); |
523 return; | 640 return; |
524 } | 641 } |
525 | 642 |
526 for (int i = 0; i < instanceCount; i++) { | 643 for (int i = 0; i < instanceCount; i++) { |
527 const Geometry& args = fGeoData[i]; | 644 const Geometry& args = fGeoData[i]; |
528 this->generateAAStrokeRectGeometry(vertices, | 645 this->generateAAStrokeRectGeometry(vertices, |
529 i * totalVertexNum * vertexStride
, | 646 i * totalVertexNum * vertexStride
, |
530 vertexStride, | 647 vertexStride, |
531 outerVertexNum, | 648 outerVertexNum, |
532 innerVertexNum, | 649 innerVertexNum, |
533 args.fColor, | 650 args.fColor, |
534 args.fDevOutside, | 651 args.fDevOutside, |
535 args.fDevOutsideAssist, | 652 args.fDevOutsideAssist, |
536 args.fDevInside, | 653 args.fDevInside, |
537 args.fMiterStroke, | 654 args.fMiterStroke, |
538 canTweakAlphaForCoverage); | 655 canTweakAlphaForCoverage); |
539 } | 656 } |
540 int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIn
dexCnt; | 657 |
541 GrDrawTarget::DrawInfo drawInfo; | 658 GrDrawTarget::DrawInfo drawInfo; |
542 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | 659 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
543 drawInfo.setStartVertex(0); | 660 drawInfo.setStartVertex(0); |
544 drawInfo.setStartIndex(0); | 661 drawInfo.setStartIndex(0); |
545 drawInfo.setVerticesPerInstance(totalVertexNum); | 662 drawInfo.setVerticesPerInstance(totalVertexNum); |
546 drawInfo.setIndicesPerInstance(indicesPerInstance); | 663 drawInfo.setIndicesPerInstance(aa_stroke_rect_index_count(this->miterStr
oke())); |
547 drawInfo.adjustStartVertex(firstVertex); | 664 drawInfo.adjustStartVertex(firstVertex); |
548 drawInfo.setVertexBuffer(vertexBuffer); | 665 drawInfo.setVertexBuffer(vertexBuffer); |
549 drawInfo.setIndexBuffer(indexBuffer); | 666 drawInfo.setIndexBuffer(fIndexBuffer); |
550 | 667 |
551 int maxInstancesPerDraw = this->miterStroke() ? kNumMiterRectsInIndexBuf
fer : | 668 int maxInstancesPerDraw = kNumBevelStrokeRectsInIndexBuffer; |
552 kNumBevelRectsInIndexBuf
fer; | |
553 | 669 |
554 while (instanceCount) { | 670 while (instanceCount) { |
555 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | 671 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
556 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | 672 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
557 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | 673 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
558 | 674 |
559 batchTarget->draw(drawInfo); | 675 batchTarget->draw(drawInfo); |
560 | 676 |
561 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 677 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
562 instanceCount -= drawInfo.instanceCount(); | 678 instanceCount -= drawInfo.instanceCount(); |
563 } | 679 } |
564 } | 680 } |
565 | 681 |
566 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 682 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
567 | 683 |
568 private: | 684 private: |
569 AAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix) { | 685 AAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix, |
| 686 const GrIndexBuffer* indexBuffer) |
| 687 : fIndexBuffer(indexBuffer) { |
570 this->initClassID<AAStrokeRectBatch>(); | 688 this->initClassID<AAStrokeRectBatch>(); |
571 fBatch.fViewMatrix = viewMatrix; | 689 fBatch.fViewMatrix = viewMatrix; |
572 fGeoData.push_back(geometry); | 690 fGeoData.push_back(geometry); |
573 | 691 |
574 // If we have miterstroke then we inset devOutside and outset devOutside
Assist, so we need | 692 // If we have miterstroke then we inset devOutside and outset devOutside
Assist, so we need |
575 // the join for proper bounds | 693 // the join for proper bounds |
576 fBounds = geometry.fDevOutside; | 694 fBounds = geometry.fDevOutside; |
577 fBounds.join(geometry.fDevOutsideAssist); | 695 fBounds.join(geometry.fDevOutsideAssist); |
578 } | 696 } |
579 | 697 |
580 | |
581 static const int kMiterIndexCnt = 3 * 24; | |
582 static const int kMiterVertexCnt = 16; | |
583 static const int kNumMiterRectsInIndexBuffer = 256; | |
584 | |
585 static const int kBevelIndexCnt = 48 + 36 + 24; | |
586 static const int kBevelVertexCnt = 24; | |
587 static const int kNumBevelRectsInIndexBuffer = 256; | |
588 | |
589 static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvi
der, | |
590 bool miterStroke) { | |
591 | |
592 if (miterStroke) { | |
593 static const uint16_t gMiterIndices[] = { | |
594 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, | |
595 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, | |
596 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, | |
597 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, | |
598 | |
599 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, | |
600 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, | |
601 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, | |
602 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, | |
603 | |
604 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, | |
605 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, | |
606 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, | |
607 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, | |
608 }; | |
609 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gMiterIndices) == kMiterIndexCnt); | |
610 GR_DEFINE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); | |
611 return resourceProvider->refOrCreateInstancedIndexBuffer(gMiterIndic
es, | |
612 kMiterIndexCnt, kNumMiterRectsInIndexBuffer, kMiterVertexCnt, | |
613 gMiterIndexBufferKey); | |
614 } else { | |
615 /** | |
616 * As in miter-stroke, index = a + b, and a is the current index, b
is the shift | |
617 * from the first index. The index layout: | |
618 * outer AA line: 0~3, 4~7 | |
619 * outer edge: 8~11, 12~15 | |
620 * inner edge: 16~19 | |
621 * inner AA line: 20~23 | |
622 * Following comes a bevel-stroke rect and its indices: | |
623 * | |
624 * 4 7 | |
625 * ********************************* | |
626 * * ______________________________ * | |
627 * * / 12 15 \ * | |
628 * * / \ * | |
629 * 0 * |8 16_____________________19 11 | * 3 | |
630 * * | | | | * | |
631 * * | | **************** | | * | |
632 * * | | * 20 23 * | | * | |
633 * * | | * * | | * | |
634 * * | | * 21 22 * | | * | |
635 * * | | **************** | | * | |
636 * * | |____________________| | * | |
637 * 1 * |9 17 18 10| * 2 | |
638 * * \ / * | |
639 * * \13 __________________________14/ * | |
640 * * * | |
641 * ********************************** | |
642 * 5 6 | |
643 */ | |
644 static const uint16_t gBevelIndices[] = { | |
645 // Draw outer AA, from outer AA line to outer edge, shift is 0. | |
646 0 + 0, 1 + 0, 9 + 0, 9 + 0, 8 + 0, 0 + 0, | |
647 1 + 0, 5 + 0, 13 + 0, 13 + 0, 9 + 0, 1 + 0, | |
648 5 + 0, 6 + 0, 14 + 0, 14 + 0, 13 + 0, 5 + 0, | |
649 6 + 0, 2 + 0, 10 + 0, 10 + 0, 14 + 0, 6 + 0, | |
650 2 + 0, 3 + 0, 11 + 0, 11 + 0, 10 + 0, 2 + 0, | |
651 3 + 0, 7 + 0, 15 + 0, 15 + 0, 11 + 0, 3 + 0, | |
652 7 + 0, 4 + 0, 12 + 0, 12 + 0, 15 + 0, 7 + 0, | |
653 4 + 0, 0 + 0, 8 + 0, 8 + 0, 12 + 0, 4 + 0, | |
654 | |
655 // Draw the stroke, from outer edge to inner edge, shift is 8. | |
656 0 + 8, 1 + 8, 9 + 8, 9 + 8, 8 + 8, 0 + 8, | |
657 1 + 8, 5 + 8, 9 + 8, | |
658 5 + 8, 6 + 8, 10 + 8, 10 + 8, 9 + 8, 5 + 8, | |
659 6 + 8, 2 + 8, 10 + 8, | |
660 2 + 8, 3 + 8, 11 + 8, 11 + 8, 10 + 8, 2 + 8, | |
661 3 + 8, 7 + 8, 11 + 8, | |
662 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8, | |
663 4 + 8, 0 + 8, 8 + 8, | |
664 | |
665 // Draw the inner AA, from inner edge to inner AA line, shift is
16. | |
666 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16, | |
667 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16, | |
668 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16, | |
669 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16, | |
670 }; | |
671 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gBevelIndices) == kBevelIndexCnt); | |
672 | |
673 GR_DEFINE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); | |
674 return resourceProvider->refOrCreateInstancedIndexBuffer(gBevelIndic
es, | |
675 kBevelIndexCnt, kNumBevelRectsInIndexBuffer, kBevelVertexCnt, | |
676 gBevelIndexBufferKey); | |
677 } | |
678 } | |
679 | |
680 GrColor color() const { return fBatch.fColor; } | 698 GrColor color() const { return fBatch.fColor; } |
681 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 699 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
682 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } | 700 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } |
683 bool colorIgnored() const { return fBatch.fColorIgnored; } | 701 bool colorIgnored() const { return fBatch.fColorIgnored; } |
684 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | 702 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } |
685 bool miterStroke() const { return fBatch.fMiterStroke; } | 703 bool miterStroke() const { return fBatch.fMiterStroke; } |
686 | 704 |
687 bool onCombineIfPossible(GrBatch* t) override { | 705 bool onCombineIfPossible(GrBatch* t) override { |
688 AAStrokeRectBatch* that = t->cast<AAStrokeRectBatch>(); | 706 AAStrokeRectBatch* that = t->cast<AAStrokeRectBatch>(); |
689 | 707 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 SkMatrix fViewMatrix; | 848 SkMatrix fViewMatrix; |
831 GrColor fColor; | 849 GrColor fColor; |
832 bool fUsesLocalCoords; | 850 bool fUsesLocalCoords; |
833 bool fColorIgnored; | 851 bool fColorIgnored; |
834 bool fCoverageIgnored; | 852 bool fCoverageIgnored; |
835 bool fMiterStroke; | 853 bool fMiterStroke; |
836 bool fCanTweakAlphaForCoverage; | 854 bool fCanTweakAlphaForCoverage; |
837 }; | 855 }; |
838 | 856 |
839 BatchTracker fBatch; | 857 BatchTracker fBatch; |
| 858 const GrIndexBuffer* fIndexBuffer; |
840 SkSTArray<1, Geometry, true> fGeoData; | 859 SkSTArray<1, Geometry, true> fGeoData; |
841 }; | 860 }; |
842 | 861 |
843 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, | 862 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, |
844 GrPipelineBuilder* pipelineBuilder, | 863 GrPipelineBuilder* pipelineBuilder, |
845 GrColor color, | 864 GrColor color, |
846 const SkMatrix& viewMatrix, | 865 const SkMatrix& viewMatrix, |
847 const SkRect& devOutside, | 866 const SkRect& devOutside, |
848 const SkRect& devOutsideAssist, | 867 const SkRect& devOutsideAssist, |
849 const SkRect& devInside, | 868 const SkRect& devInside, |
850 bool miterStroke) { | 869 bool miterStroke) { |
| 870 GrIndexBuffer* indexBuffer = setup_aa_stroke_rect_indexbuffer(&fAAMiterStrok
eRectIndexBuffer, |
| 871 &fAABevelStrok
eRectIndexBuffer, |
| 872 fGpu, |
| 873 miterStroke); |
| 874 if (!indexBuffer) { |
| 875 SkDebugf("Failed to create index buffer!\n"); |
| 876 return; |
| 877 } |
| 878 |
851 AAStrokeRectBatch::Geometry geometry; | 879 AAStrokeRectBatch::Geometry geometry; |
852 geometry.fColor = color; | 880 geometry.fColor = color; |
853 geometry.fDevOutside = devOutside; | 881 geometry.fDevOutside = devOutside; |
854 geometry.fDevOutsideAssist = devOutsideAssist; | 882 geometry.fDevOutsideAssist = devOutsideAssist; |
855 geometry.fDevInside = devInside; | 883 geometry.fDevInside = devInside; |
856 geometry.fMiterStroke = miterStroke; | 884 geometry.fMiterStroke = miterStroke; |
857 | 885 |
858 SkAutoTUnref<GrBatch> batch(AAStrokeRectBatch::Create(geometry, viewMatrix))
; | 886 SkAutoTUnref<GrBatch> batch(AAStrokeRectBatch::Create(geometry, viewMatrix,
indexBuffer)); |
859 target->drawBatch(pipelineBuilder, batch); | 887 target->drawBatch(pipelineBuilder, batch); |
860 } | 888 } |
861 | 889 |
862 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, | 890 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, |
863 GrPipelineBuilder* pipelineBuilder, | 891 GrPipelineBuilder* pipelineBuilder, |
864 GrColor color, | 892 GrColor color, |
865 const SkMatrix& viewMatrix, | 893 const SkMatrix& viewMatrix, |
866 const SkRect rects[2]) { | 894 const SkRect rects[2]) { |
867 SkASSERT(viewMatrix.rectStaysRect()); | 895 SkASSERT(viewMatrix.rectStaysRect()); |
868 SkASSERT(!rects[1].isEmpty()); | 896 SkASSERT(!rects[1].isEmpty()); |
(...skipping 15 matching lines...) Expand all Loading... |
884 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 912 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
885 | 913 |
886 #ifdef GR_TEST_UTILS | 914 #ifdef GR_TEST_UTILS |
887 | 915 |
888 BATCH_TEST_DEFINE(AAFillRectBatch) { | 916 BATCH_TEST_DEFINE(AAFillRectBatch) { |
889 AAFillRectBatch::Geometry geo; | 917 AAFillRectBatch::Geometry geo; |
890 geo.fColor = GrRandomColor(random); | 918 geo.fColor = GrRandomColor(random); |
891 geo.fViewMatrix = GrTest::TestMatrix(random); | 919 geo.fViewMatrix = GrTest::TestMatrix(random); |
892 geo.fRect = GrTest::TestRect(random); | 920 geo.fRect = GrTest::TestRect(random); |
893 geo.fDevRect = GrTest::TestRect(random); | 921 geo.fDevRect = GrTest::TestRect(random); |
894 return AAFillRectBatch::Create(geo); | 922 |
| 923 static GrIndexBuffer* aaFillRectIndexBuffer = NULL; |
| 924 if (!aaFillRectIndexBuffer) { |
| 925 aaFillRectIndexBuffer = |
| 926 context->getGpu()->createInstancedIndexBuffer(gFillAARectIdx, |
| 927 kIndicesPerAAFillR
ect, |
| 928 kNumAAFillRectsInI
ndexBuffer, |
| 929 kVertsPerAAFillRec
t); |
| 930 } |
| 931 |
| 932 return AAFillRectBatch::Create(geo, aaFillRectIndexBuffer); |
895 } | 933 } |
896 | 934 |
897 BATCH_TEST_DEFINE(AAStrokeRectBatch) { | 935 BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
| 936 static GrIndexBuffer* aaMiterStrokeRectIndexBuffer = NULL; |
| 937 static GrIndexBuffer* aaBevelStrokeRectIndexBuffer = NULL; |
| 938 |
898 bool miterStroke = random->nextBool(); | 939 bool miterStroke = random->nextBool(); |
899 | 940 |
| 941 GrIndexBuffer* indexBuffer = setup_aa_stroke_rect_indexbuffer(&aaMiterStroke
RectIndexBuffer, |
| 942 &aaBevelStroke
RectIndexBuffer, |
| 943 context->getGp
u(), |
| 944 miterStroke); |
| 945 |
900 // Create mock stroke rect | 946 // Create mock stroke rect |
901 SkRect outside = GrTest::TestRect(random); | 947 SkRect outside = GrTest::TestRect(random); |
902 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); | 948 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); |
903 SkScalar strokeWidth = minDim * 0.1f; | 949 SkScalar strokeWidth = minDim * 0.1f; |
904 SkRect outsideAssist = outside; | 950 SkRect outsideAssist = outside; |
905 outsideAssist.outset(strokeWidth, strokeWidth); | 951 outsideAssist.outset(strokeWidth, strokeWidth); |
906 SkRect inside = outside; | 952 SkRect inside = outside; |
907 inside.inset(strokeWidth, strokeWidth); | 953 inside.inset(strokeWidth, strokeWidth); |
908 | 954 |
909 AAStrokeRectBatch::Geometry geo; | 955 AAStrokeRectBatch::Geometry geo; |
910 geo.fColor = GrRandomColor(random); | 956 geo.fColor = GrRandomColor(random); |
911 geo.fDevOutside = outside; | 957 geo.fDevOutside = outside; |
912 geo.fDevOutsideAssist = outsideAssist; | 958 geo.fDevOutsideAssist = outsideAssist; |
913 geo.fDevInside = inside; | 959 geo.fDevInside = inside; |
914 geo.fMiterStroke = miterStroke; | 960 geo.fMiterStroke = miterStroke; |
915 | 961 |
916 return AAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random)); | 962 return AAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random), indexBuffe
r); |
917 } | 963 } |
918 | 964 |
919 #endif | 965 #endif |
OLD | NEW |