| 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 25 matching lines...) Expand all Loading... |
| 36 coverageType = Coverage::kSolid_Type; | 36 coverageType = Coverage::kSolid_Type; |
| 37 } else { | 37 } else { |
| 38 coverageType = Coverage::kAttribute_Type; | 38 coverageType = Coverage::kAttribute_Type; |
| 39 } | 39 } |
| 40 Coverage coverage(coverageType); | 40 Coverage coverage(coverageType); |
| 41 LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type : | 41 LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type : |
| 42 LocalCoords::kUnused_Type); | 42 LocalCoords::kUnused_Type); |
| 43 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix); | 43 return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix); |
| 44 } | 44 } |
| 45 | 45 |
| 46 void GrAAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { | 46 class AAStrokeRectBatch : public GrVertexBatch { |
| 47 public: |
| 48 DEFINE_BATCH_CLASS_ID |
| 49 |
| 50 // TODO support AA rotated stroke rects by copying around view matrices |
| 51 struct Geometry { |
| 52 SkRect fDevOutside; |
| 53 SkRect fDevOutsideAssist; |
| 54 SkRect fDevInside; |
| 55 GrColor fColor; |
| 56 bool fMiterStroke; |
| 57 }; |
| 58 |
| 59 static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const
SkRect& devOutside, |
| 60 const SkRect& devOutsideAssist, const SkRect& dev
Inside, |
| 61 bool miterStroke) { |
| 62 return new AAStrokeRectBatch(color, viewMatrix, devOutside, devOutsideAs
sist, devInside, |
| 63 miterStroke); |
| 64 } |
| 65 |
| 66 const char* name() const override { return "AAStrokeRect"; } |
| 67 |
| 68 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 69 // When this is called on a batch, there is only one geometry bundle |
| 70 out->setKnownFourComponents(fGeoData[0].fColor); |
| 71 } |
| 72 |
| 73 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
| 74 out->setUnknownSingleComponent(); |
| 75 } |
| 76 |
| 77 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 78 |
| 79 private: |
| 80 void onPrepareDraws(Target*) override; |
| 81 void initBatchTracker(const GrPipelineOptimizations&) override; |
| 82 |
| 83 AAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& d
evOutside, |
| 84 const SkRect& devOutsideAssist, const SkRect& devInside, b
ool miterStroke) |
| 85 : INHERITED(ClassID()) { |
| 86 fBatch.fViewMatrix = viewMatrix; |
| 87 Geometry& geometry = fGeoData.push_back(); |
| 88 geometry.fColor = color; |
| 89 geometry.fDevOutside = devOutside; |
| 90 geometry.fDevOutsideAssist = devOutsideAssist; |
| 91 geometry.fDevInside = devInside; |
| 92 geometry.fMiterStroke = miterStroke; |
| 93 |
| 94 // If we have miterstroke then we inset devOutside and outset devOutside
Assist, so we need |
| 95 // the join for proper bounds |
| 96 fBounds = geometry.fDevOutside; |
| 97 fBounds.join(geometry.fDevOutsideAssist); |
| 98 } |
| 99 |
| 100 |
| 101 static const int kMiterIndexCnt = 3 * 24; |
| 102 static const int kMiterVertexCnt = 16; |
| 103 static const int kNumMiterRectsInIndexBuffer = 256; |
| 104 |
| 105 static const int kBevelIndexCnt = 48 + 36 + 24; |
| 106 static const int kBevelVertexCnt = 24; |
| 107 static const int kNumBevelRectsInIndexBuffer = 256; |
| 108 |
| 109 static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvi
der, |
| 110 bool miterStroke); |
| 111 |
| 112 GrColor color() const { return fBatch.fColor; } |
| 113 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| 114 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } |
| 115 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; } |
| 119 |
| 120 bool onCombineIfPossible(GrBatch* t, const GrCaps&) override; |
| 121 |
| 122 void generateAAStrokeRectGeometry(void* vertices, |
| 123 size_t offset, |
| 124 size_t vertexStride, |
| 125 int outerVertexNum, |
| 126 int innerVertexNum, |
| 127 GrColor color, |
| 128 const SkRect& devOutside, |
| 129 const SkRect& devOutsideAssist, |
| 130 const SkRect& devInside, |
| 131 bool miterStroke, |
| 132 bool tweakAlphaForCoverage) const; |
| 133 |
| 134 struct BatchTracker { |
| 135 SkMatrix fViewMatrix; |
| 136 GrColor fColor; |
| 137 bool fUsesLocalCoords; |
| 138 bool fColorIgnored; |
| 139 bool fCoverageIgnored; |
| 140 bool fMiterStroke; |
| 141 bool fCanTweakAlphaForCoverage; |
| 142 }; |
| 143 |
| 144 BatchTracker fBatch; |
| 145 SkSTArray<1, Geometry, true> fGeoData; |
| 146 |
| 147 typedef GrVertexBatch INHERITED; |
| 148 }; |
| 149 |
| 150 void AAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { |
| 47 // Handle any color overrides | 151 // Handle any color overrides |
| 48 if (!opt.readsColor()) { | 152 if (!opt.readsColor()) { |
| 49 fGeoData[0].fColor = GrColor_ILLEGAL; | 153 fGeoData[0].fColor = GrColor_ILLEGAL; |
| 50 } | 154 } |
| 51 opt.getOverrideColorIfSet(&fGeoData[0].fColor); | 155 opt.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 52 | 156 |
| 53 // setup batch properties | 157 // setup batch properties |
| 54 fBatch.fColorIgnored = !opt.readsColor(); | 158 fBatch.fColorIgnored = !opt.readsColor(); |
| 55 fBatch.fColor = fGeoData[0].fColor; | 159 fBatch.fColor = fGeoData[0].fColor; |
| 56 fBatch.fUsesLocalCoords = opt.readsLocalCoords(); | 160 fBatch.fUsesLocalCoords = opt.readsLocalCoords(); |
| 57 fBatch.fCoverageIgnored = !opt.readsCoverage(); | 161 fBatch.fCoverageIgnored = !opt.readsCoverage(); |
| 58 fBatch.fMiterStroke = fGeoData[0].fMiterStroke; | 162 fBatch.fMiterStroke = fGeoData[0].fMiterStroke; |
| 59 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); | 163 fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); |
| 60 } | 164 } |
| 61 | 165 |
| 62 void GrAAStrokeRectBatch::onPrepareDraws(Target* target) { | 166 void AAStrokeRectBatch::onPrepareDraws(Target* target) { |
| 63 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); | 167 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); |
| 64 | 168 |
| 65 SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlp
haForCoverage, | 169 SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlp
haForCoverage, |
| 66 this->viewM
atrix(), | 170 this->viewM
atrix(), |
| 67 this->usesL
ocalCoords(), | 171 this->usesL
ocalCoords(), |
| 68 this->cover
ageIgnored())); | 172 this->cover
ageIgnored())); |
| 69 if (!gp) { | 173 if (!gp) { |
| 70 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 174 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 71 return; | 175 return; |
| 72 } | 176 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 args.fColor, | 209 args.fColor, |
| 106 args.fDevOutside, | 210 args.fDevOutside, |
| 107 args.fDevOutsideAssist, | 211 args.fDevOutsideAssist, |
| 108 args.fDevInside, | 212 args.fDevInside, |
| 109 args.fMiterStroke, | 213 args.fMiterStroke, |
| 110 canTweakAlphaForCoverage); | 214 canTweakAlphaForCoverage); |
| 111 } | 215 } |
| 112 helper.recordDraw(target); | 216 helper.recordDraw(target); |
| 113 } | 217 } |
| 114 | 218 |
| 115 const GrIndexBuffer* GrAAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* res
ourceProvider, | 219 const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resou
rceProvider, |
| 116 bool miterStroke) { | 220 bool miterStroke) { |
| 117 | 221 |
| 118 if (miterStroke) { | 222 if (miterStroke) { |
| 119 static const uint16_t gMiterIndices[] = { | 223 static const uint16_t gMiterIndices[] = { |
| 120 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, | 224 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, |
| 121 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, | 225 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, |
| 122 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, | 226 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, |
| 123 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, | 227 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, |
| 124 | 228 |
| 125 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, | 229 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, |
| 126 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, | 230 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 }; | 300 }; |
| 197 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gBevelIndices) == kBevelIndexCnt); | 301 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gBevelIndices) == kBevelIndexCnt); |
| 198 | 302 |
| 199 GR_DEFINE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); | 303 GR_DEFINE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); |
| 200 return resourceProvider->findOrCreateInstancedIndexBuffer(gBevelIndices, | 304 return resourceProvider->findOrCreateInstancedIndexBuffer(gBevelIndices, |
| 201 kBevelIndexCnt, kNumBevelRectsInIndexBuffer, kBevelVertexCnt, | 305 kBevelIndexCnt, kNumBevelRectsInIndexBuffer, kBevelVertexCnt, |
| 202 gBevelIndexBufferKey); | 306 gBevelIndexBufferKey); |
| 203 } | 307 } |
| 204 } | 308 } |
| 205 | 309 |
| 206 bool GrAAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { | 310 bool AAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { |
| 207 GrAAStrokeRectBatch* that = t->cast<GrAAStrokeRectBatch>(); | 311 AAStrokeRectBatch* that = t->cast<AAStrokeRectBatch>(); |
| 208 | 312 |
| 209 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeli
ne(), | 313 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeli
ne(), |
| 210 that->bounds(), caps)) { | 314 that->bounds(), caps)) { |
| 211 return false; | 315 return false; |
| 212 } | 316 } |
| 213 | 317 |
| 214 // TODO batch across miterstroke changes | 318 // TODO batch across miterstroke changes |
| 215 if (this->miterStroke() != that->miterStroke()) { | 319 if (this->miterStroke() != that->miterStroke()) { |
| 216 return false; | 320 return false; |
| 217 } | 321 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 230 } | 334 } |
| 231 | 335 |
| 232 if (this->color() != that->color()) { | 336 if (this->color() != that->color()) { |
| 233 fBatch.fColor = GrColor_ILLEGAL; | 337 fBatch.fColor = GrColor_ILLEGAL; |
| 234 } | 338 } |
| 235 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); | 339 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); |
| 236 this->joinBounds(that->bounds()); | 340 this->joinBounds(that->bounds()); |
| 237 return true; | 341 return true; |
| 238 } | 342 } |
| 239 | 343 |
| 240 void GrAAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, | 344 void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
| 241 size_t offset, | 345 size_t offset, |
| 242 size_t vertexStride, | 346 size_t vertexStride, |
| 243 int outerVertexNum, | 347 int outerVertexNum, |
| 244 int innerVertexNum, | 348 int innerVertexNum, |
| 245 GrColor color, | 349 GrColor color, |
| 246 const SkRect& devOutside, | 350 const SkRect& devOutside, |
| 247 const SkRect& devOutsideA
ssist, | 351 const SkRect& devOutsideAss
ist, |
| 248 const SkRect& devInside, | 352 const SkRect& devInside, |
| 249 bool miterStroke, | 353 bool miterStroke, |
| 250 bool tweakAlphaForCoverag
e) const { | 354 bool tweakAlphaForCoverage)
const { |
| 251 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; | 355 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; |
| 252 | 356 |
| 253 // We create vertices for four nested rectangles. There are two ramps from 0
to full | 357 // We create vertices for four nested rectangles. There are two ramps from 0
to full |
| 254 // coverage, one on the exterior of the stroke and the other on the interior
. | 358 // coverage, one on the exterior of the stroke and the other on the interior
. |
| 255 // The following pointers refer to the four rects, from outermost to innermo
st. | 359 // The following pointers refer to the four rects, from outermost to innermo
st. |
| 256 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 360 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
| 257 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * verte
xStride); | 361 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * verte
xStride); |
| 258 SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * v
ertexStride); | 362 SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * v
ertexStride); |
| 259 SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + | 363 SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + |
| 260 (2 * outerVertexNum + innerVer
texNum) * | 364 (2 * outerVertexNum + innerVer
texNum) * |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 for (int i = 0; i < innerVertexNum; ++i) { | 447 for (int i = 0; i < innerVertexNum; ++i) { |
| 344 if (tweakAlphaForCoverage) { | 448 if (tweakAlphaForCoverage) { |
| 345 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; | 449 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; |
| 346 } else { | 450 } else { |
| 347 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 451 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 348 *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColo
r)) = 0; | 452 *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColo
r)) = 0; |
| 349 } | 453 } |
| 350 } | 454 } |
| 351 } | 455 } |
| 352 | 456 |
| 457 namespace GrAAStrokeRectBatch { |
| 458 |
| 459 GrDrawBatch* Create(GrColor color, |
| 460 const SkMatrix& viewMatrix, |
| 461 const SkRect& devOutside, |
| 462 const SkRect& devOutsideAssist, |
| 463 const SkRect& devInside, |
| 464 bool miterStroke) { |
| 465 return AAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAs
sist, devInside, |
| 466 miterStroke); |
| 467 } |
| 468 |
| 469 }; |
| 470 |
| 353 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 471 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 354 | 472 |
| 355 #ifdef GR_TEST_UTILS | 473 #ifdef GR_TEST_UTILS |
| 356 | 474 |
| 357 #include "GrBatchTest.h" | 475 #include "GrBatchTest.h" |
| 358 | 476 |
| 359 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { | 477 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
| 360 bool miterStroke = random->nextBool(); | 478 bool miterStroke = random->nextBool(); |
| 361 | 479 |
| 362 // Create mock stroke rect | 480 // Create mock stroke rect |
| 363 SkRect outside = GrTest::TestRect(random); | 481 SkRect outside = GrTest::TestRect(random); |
| 364 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); | 482 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); |
| 365 SkScalar strokeWidth = minDim * 0.1f; | 483 SkScalar strokeWidth = minDim * 0.1f; |
| 366 SkRect outsideAssist = outside; | 484 SkRect outsideAssist = outside; |
| 367 outsideAssist.outset(strokeWidth, strokeWidth); | 485 outsideAssist.outset(strokeWidth, strokeWidth); |
| 368 SkRect inside = outside; | 486 SkRect inside = outside; |
| 369 inside.inset(strokeWidth, strokeWidth); | 487 inside.inset(strokeWidth, strokeWidth); |
| 370 | 488 |
| 371 GrAAStrokeRectBatch::Geometry geo; | 489 GrColor color = GrRandomColor(random); |
| 372 geo.fColor = GrRandomColor(random); | |
| 373 geo.fDevOutside = outside; | |
| 374 geo.fDevOutsideAssist = outsideAssist; | |
| 375 geo.fDevInside = inside; | |
| 376 geo.fMiterStroke = miterStroke; | |
| 377 | 490 |
| 378 return GrAAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random)); | 491 return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outsid
e, outsideAssist, |
| 492 inside, miterStroke); |
| 379 } | 493 } |
| 380 | 494 |
| 381 #endif | 495 #endif |
| OLD | NEW |