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