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 |