| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrAAStrokeRectBatch.h" | 8 #include "GrAAStrokeRectBatch.h" |
| 9 | 9 |
| 10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 class AAStrokeRectBatch : public GrVertexBatch { | 46 class AAStrokeRectBatch : public GrVertexBatch { |
| 47 public: | 47 public: |
| 48 DEFINE_BATCH_CLASS_ID | 48 DEFINE_BATCH_CLASS_ID |
| 49 | 49 |
| 50 // TODO support AA rotated stroke rects by copying around view matrices | 50 // TODO support AA rotated stroke rects by copying around view matrices |
| 51 struct Geometry { | 51 struct Geometry { |
| 52 SkRect fDevOutside; | 52 SkRect fDevOutside; |
| 53 SkRect fDevOutsideAssist; | 53 SkRect fDevOutsideAssist; |
| 54 SkRect fDevInside; | 54 SkRect fDevInside; |
| 55 GrColor fColor; | 55 GrColor fColor; |
| 56 bool fMiterStroke; | |
| 57 }; | 56 }; |
| 58 | 57 |
| 59 static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const
SkRect& devOutside, | 58 static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStrok
e) { |
| 60 const SkRect& devOutsideAssist, const SkRect& dev
Inside, | 59 return new AAStrokeRectBatch(viewMatrix, miterStroke); |
| 61 bool miterStroke) { | |
| 62 return new AAStrokeRectBatch(color, viewMatrix, devOutside, devOutsideAs
sist, devInside, | |
| 63 miterStroke); | |
| 64 } | 60 } |
| 65 | 61 |
| 66 const char* name() const override { return "AAStrokeRect"; } | 62 const char* name() const override { return "AAStrokeRect"; } |
| 67 | 63 |
| 68 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 64 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 69 // When this is called on a batch, there is only one geometry bundle | 65 // When this is called on a batch, there is only one geometry bundle |
| 70 out->setKnownFourComponents(fGeoData[0].fColor); | 66 out->setKnownFourComponents(fGeoData[0].fColor); |
| 71 } | 67 } |
| 72 | 68 |
| 73 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 69 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
| 74 out->setUnknownSingleComponent(); | 70 out->setUnknownSingleComponent(); |
| 75 } | 71 } |
| 76 | 72 |
| 77 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 73 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 78 | 74 |
| 79 private: | 75 bool canAppend(const SkMatrix& viewMatrix, bool miterStroke) { |
| 80 void onPrepareDraws(Target*) override; | 76 return fViewMatrix.cheapEqualTo(viewMatrix) && fMiterStroke == miterStro
ke; |
| 81 void initBatchTracker(const GrPipelineOptimizations&) override; | 77 } |
| 82 | 78 |
| 83 AAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& d
evOutside, | 79 void append(GrColor color, const SkRect& devOutside, const SkRect& devOutsid
eAssist, |
| 84 const SkRect& devOutsideAssist, const SkRect& devInside, b
ool miterStroke) | 80 const SkRect& devInside) { |
| 85 : INHERITED(ClassID()) { | |
| 86 fBatch.fViewMatrix = viewMatrix; | |
| 87 Geometry& geometry = fGeoData.push_back(); | 81 Geometry& geometry = fGeoData.push_back(); |
| 88 geometry.fColor = color; | 82 geometry.fColor = color; |
| 89 geometry.fDevOutside = devOutside; | 83 geometry.fDevOutside = devOutside; |
| 90 geometry.fDevOutsideAssist = devOutsideAssist; | 84 geometry.fDevOutsideAssist = devOutsideAssist; |
| 91 geometry.fDevInside = devInside; | 85 geometry.fDevInside = devInside; |
| 92 geometry.fMiterStroke = miterStroke; | 86 } |
| 93 | 87 |
| 88 void appendAndUpdateBounds(GrColor color, const SkRect& devOutside, |
| 89 const SkRect& devOutsideAssist, const SkRect& dev
Inside) { |
| 90 this->append(color, devOutside, devOutsideAssist, devInside); |
| 91 |
| 92 SkRect bounds; |
| 93 this->updateBounds(&bounds, fGeoData.back()); |
| 94 this->joinBounds(bounds); |
| 95 } |
| 96 |
| 97 void init() { this->updateBounds(&fBounds, fGeoData[0]); } |
| 98 |
| 99 private: |
| 100 void updateBounds(SkRect* bounds, const Geometry& geo) { |
| 94 // If we have miterstroke then we inset devOutside and outset devOutside
Assist, so we need | 101 // If we have miterstroke then we inset devOutside and outset devOutside
Assist, so we need |
| 95 // the join for proper bounds | 102 // the join for proper bounds |
| 96 fBounds = geometry.fDevOutside; | 103 *bounds = geo.fDevOutside; |
| 97 fBounds.join(geometry.fDevOutsideAssist); | 104 bounds->join(geo.fDevOutsideAssist); |
| 98 } | 105 } |
| 99 | 106 |
| 107 void onPrepareDraws(Target*) override; |
| 108 void initBatchTracker(const GrPipelineOptimizations&) override; |
| 109 |
| 110 AAStrokeRectBatch(const SkMatrix& viewMatrix,bool miterStroke) |
| 111 : INHERITED(ClassID()) { |
| 112 fViewMatrix = viewMatrix; |
| 113 fMiterStroke = miterStroke; |
| 114 } |
| 100 | 115 |
| 101 static const int kMiterIndexCnt = 3 * 24; | 116 static const int kMiterIndexCnt = 3 * 24; |
| 102 static const int kMiterVertexCnt = 16; | 117 static const int kMiterVertexCnt = 16; |
| 103 static const int kNumMiterRectsInIndexBuffer = 256; | 118 static const int kNumMiterRectsInIndexBuffer = 256; |
| 104 | 119 |
| 105 static const int kBevelIndexCnt = 48 + 36 + 24; | 120 static const int kBevelIndexCnt = 48 + 36 + 24; |
| 106 static const int kBevelVertexCnt = 24; | 121 static const int kBevelVertexCnt = 24; |
| 107 static const int kNumBevelRectsInIndexBuffer = 256; | 122 static const int kNumBevelRectsInIndexBuffer = 256; |
| 108 | 123 |
| 109 static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvi
der, | 124 static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvi
der, |
| 110 bool miterStroke); | 125 bool miterStroke); |
| 111 | 126 |
| 112 GrColor color() const { return fBatch.fColor; } | 127 GrColor color() const { return fBatch.fColor; } |
| 113 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 128 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| 114 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } | 129 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } |
| 115 bool colorIgnored() const { return fBatch.fColorIgnored; } | 130 bool colorIgnored() const { return fBatch.fColorIgnored; } |
| 116 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | |
| 117 bool miterStroke() const { return fBatch.fMiterStroke; } | |
| 118 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } | 131 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } |
| 132 const Geometry& geometry() const { return fGeoData[0]; } |
| 133 const SkMatrix& viewMatrix() const { return fViewMatrix; } |
| 134 bool miterStroke() const { return fMiterStroke; } |
| 119 | 135 |
| 120 bool onCombineIfPossible(GrBatch* t, const GrCaps&) override; | 136 bool onCombineIfPossible(GrBatch* t, const GrCaps&) override; |
| 121 | 137 |
| 122 void generateAAStrokeRectGeometry(void* vertices, | 138 void generateAAStrokeRectGeometry(void* vertices, |
| 123 size_t offset, | 139 size_t offset, |
| 124 size_t vertexStride, | 140 size_t vertexStride, |
| 125 int outerVertexNum, | 141 int outerVertexNum, |
| 126 int innerVertexNum, | 142 int innerVertexNum, |
| 127 GrColor color, | 143 GrColor color, |
| 128 const SkRect& devOutside, | 144 const SkRect& devOutside, |
| 129 const SkRect& devOutsideAssist, | 145 const SkRect& devOutsideAssist, |
| 130 const SkRect& devInside, | 146 const SkRect& devInside, |
| 131 bool miterStroke, | 147 bool miterStroke, |
| 132 bool tweakAlphaForCoverage) const; | 148 bool tweakAlphaForCoverage) const; |
| 133 | 149 |
| 134 struct BatchTracker { | 150 struct BatchTracker { |
| 135 SkMatrix fViewMatrix; | |
| 136 GrColor fColor; | 151 GrColor fColor; |
| 137 bool fUsesLocalCoords; | 152 bool fUsesLocalCoords; |
| 138 bool fColorIgnored; | 153 bool fColorIgnored; |
| 139 bool fCoverageIgnored; | 154 bool fCoverageIgnored; |
| 140 bool fMiterStroke; | |
| 141 bool fCanTweakAlphaForCoverage; | 155 bool fCanTweakAlphaForCoverage; |
| 142 }; | 156 }; |
| 143 | 157 |
| 144 BatchTracker fBatch; | 158 BatchTracker fBatch; |
| 145 SkSTArray<1, Geometry, true> fGeoData; | 159 SkSTArray<1, Geometry, true> fGeoData; |
| 160 SkMatrix fViewMatrix; |
| 161 bool fMiterStroke; |
| 146 | 162 |
| 147 typedef GrVertexBatch INHERITED; | 163 typedef GrVertexBatch INHERITED; |
| 148 }; | 164 }; |
| 149 | 165 |
| 150 void AAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { | 166 void AAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { |
| 151 // Handle any color overrides | 167 // Handle any color overrides |
| 152 if (!opt.readsColor()) { | 168 if (!opt.readsColor()) { |
| 153 fGeoData[0].fColor = GrColor_ILLEGAL; | 169 fGeoData[0].fColor = GrColor_ILLEGAL; |
| 154 } | 170 } |
| 155 opt.getOverrideColorIfSet(&fGeoData[0].fColor); | 171 opt.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 156 | 172 |
| 157 // setup batch properties | 173 // setup batch properties |
| 158 fBatch.fColorIgnored = !opt.readsColor(); | 174 fBatch.fColorIgnored = !opt.readsColor(); |
| 159 fBatch.fColor = fGeoData[0].fColor; | 175 fBatch.fColor = fGeoData[0].fColor; |
| 160 fBatch.fUsesLocalCoords = opt.readsLocalCoords(); | 176 fBatch.fUsesLocalCoords = opt.readsLocalCoords(); |
| 161 fBatch.fCoverageIgnored = !opt.readsCoverage(); | 177 fBatch.fCoverageIgnored = !opt.readsCoverage(); |
| 162 fBatch.fMiterStroke = fGeoData[0].fMiterStroke; | |
| 163 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); | 178 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); |
| 164 } | 179 } |
| 165 | 180 |
| 166 void AAStrokeRectBatch::onPrepareDraws(Target* target) { | 181 void AAStrokeRectBatch::onPrepareDraws(Target* target) { |
| 167 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); | 182 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); |
| 168 | 183 |
| 169 SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlp
haForCoverage, | 184 SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlp
haForCoverage, |
| 170 this->viewM
atrix(), | 185 this->viewM
atrix(), |
| 171 this->usesL
ocalCoords(), | 186 this->usesL
ocalCoords(), |
| 172 this->cover
ageIgnored())); | 187 this->cover
ageIgnored())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 203 const Geometry& args = fGeoData[i]; | 218 const Geometry& args = fGeoData[i]; |
| 204 this->generateAAStrokeRectGeometry(vertices, | 219 this->generateAAStrokeRectGeometry(vertices, |
| 205 i * verticesPerInstance * vertexStrid
e, | 220 i * verticesPerInstance * vertexStrid
e, |
| 206 vertexStride, | 221 vertexStride, |
| 207 outerVertexNum, | 222 outerVertexNum, |
| 208 innerVertexNum, | 223 innerVertexNum, |
| 209 args.fColor, | 224 args.fColor, |
| 210 args.fDevOutside, | 225 args.fDevOutside, |
| 211 args.fDevOutsideAssist, | 226 args.fDevOutsideAssist, |
| 212 args.fDevInside, | 227 args.fDevInside, |
| 213 args.fMiterStroke, | 228 fMiterStroke, |
| 214 canTweakAlphaForCoverage); | 229 canTweakAlphaForCoverage); |
| 215 } | 230 } |
| 216 helper.recordDraw(target); | 231 helper.recordDraw(target); |
| 217 } | 232 } |
| 218 | 233 |
| 219 const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resou
rceProvider, | 234 const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resou
rceProvider, |
| 220 bool miterStroke) { | 235 bool miterStroke) { |
| 221 | 236 |
| 222 if (miterStroke) { | 237 if (miterStroke) { |
| 223 static const uint16_t gMiterIndices[] = { | 238 static const uint16_t gMiterIndices[] = { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 } | 470 } |
| 456 | 471 |
| 457 namespace GrAAStrokeRectBatch { | 472 namespace GrAAStrokeRectBatch { |
| 458 | 473 |
| 459 GrDrawBatch* Create(GrColor color, | 474 GrDrawBatch* Create(GrColor color, |
| 460 const SkMatrix& viewMatrix, | 475 const SkMatrix& viewMatrix, |
| 461 const SkRect& devOutside, | 476 const SkRect& devOutside, |
| 462 const SkRect& devOutsideAssist, | 477 const SkRect& devOutsideAssist, |
| 463 const SkRect& devInside, | 478 const SkRect& devInside, |
| 464 bool miterStroke) { | 479 bool miterStroke) { |
| 465 return AAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAs
sist, devInside, | 480 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, miterStroke
); |
| 466 miterStroke); | 481 batch->append(color, devOutside, devOutsideAssist, devInside); |
| 482 batch->init(); |
| 483 return batch; |
| 484 } |
| 485 |
| 486 bool Append(GrBatch* origBatch, |
| 487 GrColor color, |
| 488 const SkMatrix& viewMatrix, |
| 489 const SkRect& devOutside, |
| 490 const SkRect& devOutsideAssist, |
| 491 const SkRect& devInside, |
| 492 bool miterStroke) { |
| 493 AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); |
| 494 |
| 495 // we can't batch across vm changes |
| 496 if (!batch->canAppend(viewMatrix, miterStroke)) { |
| 497 return false; |
| 498 } |
| 499 |
| 500 batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside)
; |
| 501 return true; |
| 467 } | 502 } |
| 468 | 503 |
| 469 }; | 504 }; |
| 470 | 505 |
| 471 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 506 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 472 | 507 |
| 473 #ifdef GR_TEST_UTILS | 508 #ifdef GR_TEST_UTILS |
| 474 | 509 |
| 475 #include "GrBatchTest.h" | 510 #include "GrBatchTest.h" |
| 476 | 511 |
| 477 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { | 512 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
| 478 bool miterStroke = random->nextBool(); | 513 bool miterStroke = random->nextBool(); |
| 479 | 514 |
| 480 // Create mock stroke rect | 515 // Create mock stroke rect |
| 481 SkRect outside = GrTest::TestRect(random); | 516 SkRect outside = GrTest::TestRect(random); |
| 482 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); | 517 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); |
| 483 SkScalar strokeWidth = minDim * 0.1f; | 518 SkScalar strokeWidth = minDim * 0.1f; |
| 484 SkRect outsideAssist = outside; | 519 SkRect outsideAssist = outside; |
| 485 outsideAssist.outset(strokeWidth, strokeWidth); | 520 outsideAssist.outset(strokeWidth, strokeWidth); |
| 486 SkRect inside = outside; | 521 SkRect inside = outside; |
| 487 inside.inset(strokeWidth, strokeWidth); | 522 inside.inset(strokeWidth, strokeWidth); |
| 488 | 523 |
| 489 GrColor color = GrRandomColor(random); | 524 GrColor color = GrRandomColor(random); |
| 490 | 525 |
| 491 return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outsid
e, outsideAssist, | 526 return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outsid
e, outsideAssist, |
| 492 inside, miterStroke); | 527 inside, miterStroke); |
| 493 } | 528 } |
| 494 | 529 |
| 495 #endif | 530 #endif |
| OLD | NEW |