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