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 "GrNonAAFillRectBatch.h" | 8 #include "GrNonAAFillRectBatch.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 } else if (hasExplicitLocalCoords) { | 48 } else if (hasExplicitLocalCoords) { |
49 LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix); | 49 LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix); |
50 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMat
rix::I()); | 50 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMat
rix::I()); |
51 } else { | 51 } else { |
52 LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix); | 52 LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix); |
53 return GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverage, loca
lCoords, | 53 return GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverage, loca
lCoords, |
54 viewMatrix); | 54 viewMatrix); |
55 } | 55 } |
56 } | 56 } |
57 | 57 |
58 static sk_sp<GrGeometryProcessor> make_gp(bool readsCoverage) { | |
59 using namespace GrDefaultGeoProcFactory; | |
60 Color color(Color::kAttribute_Type); | |
61 Coverage coverage(readsCoverage ? Coverage::kSolid_Type : Coverage::kNone_Ty
pe); | |
62 | |
63 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); | |
64 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix:
:I()); | |
65 } | |
66 | |
67 static void tesselate(intptr_t vertices, | 58 static void tesselate(intptr_t vertices, |
68 size_t vertexStride, | 59 size_t vertexStride, |
69 GrColor color, | 60 GrColor color, |
70 const SkMatrix* viewMatrix, | 61 const SkMatrix* viewMatrix, |
71 const SkRect& rect, | 62 const SkRect& rect, |
72 const GrQuad* localQuad) { | 63 const GrQuad* localQuad) { |
73 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices); | 64 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices); |
74 | 65 |
75 positions->setRectFan(rect.fLeft, rect.fTop, | 66 positions->setRectFan(rect.fLeft, rect.fTop, |
76 rect.fRight, rect.fBottom, vertexStride); | 67 rect.fRight, rect.fBottom, vertexStride); |
(...skipping 14 matching lines...) Expand all Loading... |
91 } | 82 } |
92 | 83 |
93 static const int kColorOffset = sizeof(SkPoint); | 84 static const int kColorOffset = sizeof(SkPoint); |
94 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset); | 85 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset); |
95 for (int j = 0; j < 4; ++j) { | 86 for (int j = 0; j < 4; ++j) { |
96 *vertColor = color; | 87 *vertColor = color; |
97 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); | 88 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); |
98 } | 89 } |
99 } | 90 } |
100 | 91 |
101 class NonAAFillRectBatch : public GrVertexBatch { | 92 // We handle perspective in the local matrix or viewmatrix with special batches |
| 93 class GrNonAAFillRectPerspectiveBatch : public GrVertexBatch { |
102 public: | 94 public: |
103 DEFINE_BATCH_CLASS_ID | 95 DEFINE_BATCH_CLASS_ID |
104 | 96 |
105 NonAAFillRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect&
rect, | 97 GrNonAAFillRectPerspectiveBatch(GrColor color, const SkMatrix& viewMatrix, c
onst SkRect& rect, |
106 const SkRect* localRect, const SkMatrix* localMatrix) | 98 const SkRect* localRect, const SkMatrix* loc
alMatrix) |
107 : INHERITED(ClassID()) { | |
108 SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || | |
109 !localMatrix->hasPerspective()
)); | |
110 RectInfo& info = fRects.push_back(); | |
111 info.fColor = color; | |
112 info.fViewMatrix = viewMatrix; | |
113 info.fRect = rect; | |
114 if (localRect && localMatrix) { | |
115 info.fLocalQuad.setFromMappedRect(*localRect, *localMatrix); | |
116 } else if (localRect) { | |
117 info.fLocalQuad.set(*localRect); | |
118 } else if (localMatrix) { | |
119 info.fLocalQuad.setFromMappedRect(rect, *localMatrix); | |
120 } else { | |
121 info.fLocalQuad.set(rect); | |
122 } | |
123 viewMatrix.mapRect(&fBounds, fRects[0].fRect); | |
124 } | |
125 | |
126 const char* name() const override { return "NonAAFillRectBatch"; } | |
127 | |
128 SkString dumpInfo() const override { | |
129 SkString str; | |
130 str.appendf("# batched: %d\n", fRects.count()); | |
131 for (int i = 0; i < fRects.count(); ++i) { | |
132 const RectInfo& info = fRects[i]; | |
133 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | |
134 i, info.fColor, | |
135 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | |
136 } | |
137 str.append(INHERITED::dumpInfo()); | |
138 return str; | |
139 } | |
140 | |
141 void computePipelineOptimizations(GrInitInvariantOutput* color, | |
142 GrInitInvariantOutput* coverage, | |
143 GrBatchToXPOverrides* overrides) const ove
rride { | |
144 // When this is called on a batch, there is only one geometry bundle | |
145 color->setKnownFourComponents(fRects[0].fColor); | |
146 coverage->setKnownSingleComponent(0xff); | |
147 } | |
148 | |
149 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | |
150 overrides.getOverrideColorIfSet(&fRects[0].fColor); | |
151 fOverrides = overrides; | |
152 } | |
153 | |
154 private: | |
155 NonAAFillRectBatch() : INHERITED(ClassID()) {} | |
156 | |
157 void onPrepareDraws(Target* target) const override { | |
158 sk_sp<GrGeometryProcessor> gp = make_gp(fOverrides.readsCoverage()); | |
159 if (!gp) { | |
160 SkDebugf("Couldn't create GrGeometryProcessor\n"); | |
161 return; | |
162 } | |
163 SkASSERT(gp->getVertexStride() == | |
164 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)); | |
165 | |
166 size_t vertexStride = gp->getVertexStride(); | |
167 int instanceCount = fRects.count(); | |
168 | |
169 SkAutoTUnref<const GrBuffer> indexBuffer(target->resourceProvider()->ref
QuadIndexBuffer()); | |
170 InstancedHelper helper; | |
171 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | |
172 indexBuffer, kVertsPerInstance, | |
173 kIndicesPerInstance, instanceCount); | |
174 if (!vertices || !indexBuffer) { | |
175 SkDebugf("Could not allocate vertices\n"); | |
176 return; | |
177 } | |
178 | |
179 for (int i = 0; i < instanceCount; i++) { | |
180 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | |
181 i * kVertsPerInstance * vertexStride; | |
182 tesselate(verts, vertexStride, fRects[i].fColor, &fRects[i].fViewMat
rix, | |
183 fRects[i].fRect, &fRects[i].fLocalQuad); | |
184 } | |
185 helper.recordDraw(target, gp.get()); | |
186 } | |
187 | |
188 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | |
189 NonAAFillRectBatch* that = t->cast<NonAAFillRectBatch>(); | |
190 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | |
191 that->bounds(), caps)) { | |
192 return false; | |
193 } | |
194 | |
195 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | |
196 // not tweaking | |
197 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | |
198 fOverrides = that->fOverrides; | |
199 } | |
200 | |
201 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | |
202 this->joinBounds(that->bounds()); | |
203 return true; | |
204 } | |
205 | |
206 struct RectInfo { | |
207 GrColor fColor; | |
208 SkMatrix fViewMatrix; | |
209 SkRect fRect; | |
210 GrQuad fLocalQuad; | |
211 }; | |
212 | |
213 GrXPOverridesForBatch fOverrides; | |
214 SkSTArray<1, RectInfo, true> fRects; | |
215 | |
216 typedef GrVertexBatch INHERITED; | |
217 }; | |
218 | |
219 // We handle perspective in the local matrix or viewmatrix with special batches | |
220 class NonAAFillRectPerspectiveBatch : public GrVertexBatch { | |
221 public: | |
222 DEFINE_BATCH_CLASS_ID | |
223 | |
224 NonAAFillRectPerspectiveBatch(GrColor color, const SkMatrix& viewMatrix, con
st SkRect& rect, | |
225 const SkRect* localRect, const SkMatrix* local
Matrix) | |
226 : INHERITED(ClassID()) | 99 : INHERITED(ClassID()) |
227 , fViewMatrix(viewMatrix) { | 100 , fViewMatrix(viewMatrix) { |
228 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && | 101 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && |
229 localMatrix->hasPerspective()))
; | 102 localMatrix->hasPerspective()))
; |
230 RectInfo& info = fRects.push_back(); | 103 RectInfo& info = fRects.push_back(); |
231 info.fColor = color; | 104 info.fColor = color; |
232 info.fRect = rect; | 105 info.fRect = rect; |
233 fHasLocalRect = SkToBool(localRect); | 106 fHasLocalRect = SkToBool(localRect); |
234 fHasLocalMatrix = SkToBool(localMatrix); | 107 fHasLocalMatrix = SkToBool(localMatrix); |
235 if (fHasLocalMatrix) { | 108 if (fHasLocalMatrix) { |
(...skipping 27 matching lines...) Expand all Loading... |
263 color->setKnownFourComponents(fRects[0].fColor); | 136 color->setKnownFourComponents(fRects[0].fColor); |
264 coverage->setKnownSingleComponent(0xff); | 137 coverage->setKnownSingleComponent(0xff); |
265 } | 138 } |
266 | 139 |
267 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 140 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
268 overrides.getOverrideColorIfSet(&fRects[0].fColor); | 141 overrides.getOverrideColorIfSet(&fRects[0].fColor); |
269 fOverrides = overrides; | 142 fOverrides = overrides; |
270 } | 143 } |
271 | 144 |
272 private: | 145 private: |
273 NonAAFillRectPerspectiveBatch() : INHERITED(ClassID()) {} | 146 GrNonAAFillRectPerspectiveBatch() : INHERITED(ClassID()) {} |
274 | 147 |
275 void onPrepareDraws(Target* target) const override { | 148 void onPrepareDraws(Target* target) const override { |
276 sk_sp<GrGeometryProcessor> gp = make_persp_gp(fViewMatrix, | 149 sk_sp<GrGeometryProcessor> gp = make_persp_gp(fViewMatrix, |
277 fOverrides.readsCoverage()
, | 150 fOverrides.readsCoverage()
, |
278 fHasLocalRect, | 151 fHasLocalRect, |
279 fHasLocalMatrix ? &fLocalM
atrix : nullptr); | 152 fHasLocalMatrix ? &fLocalM
atrix : nullptr); |
280 if (!gp) { | 153 if (!gp) { |
281 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 154 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
282 return; | 155 return; |
283 } | 156 } |
(...skipping 23 matching lines...) Expand all Loading... |
307 GrQuad quad(info.fLocalRect); | 180 GrQuad quad(info.fLocalRect); |
308 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
&quad); | 181 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
&quad); |
309 } else { | 182 } else { |
310 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
nullptr); | 183 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
nullptr); |
311 } | 184 } |
312 } | 185 } |
313 helper.recordDraw(target, gp.get()); | 186 helper.recordDraw(target, gp.get()); |
314 } | 187 } |
315 | 188 |
316 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 189 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
317 NonAAFillRectPerspectiveBatch* that = t->cast<NonAAFillRectPerspectiveBa
tch>(); | 190 GrNonAAFillRectPerspectiveBatch* that = t->cast<GrNonAAFillRectPerspecti
veBatch>(); |
318 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 191 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
319 that->bounds(), caps)) { | 192 that->bounds(), caps)) { |
320 return false; | 193 return false; |
321 } | 194 } |
322 | 195 |
323 // We could batch across perspective vm changes if we really wanted to | 196 // We could batch across perspective vm changes if we really wanted to |
324 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) { | 197 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) { |
325 return false; | 198 return false; |
326 } | 199 } |
327 if (fHasLocalRect != that->fHasLocalRect) { | 200 if (fHasLocalRect != that->fHasLocalRect) { |
(...skipping 25 matching lines...) Expand all Loading... |
353 bool fHasLocalMatrix; | 226 bool fHasLocalMatrix; |
354 bool fHasLocalRect; | 227 bool fHasLocalRect; |
355 SkMatrix fLocalMatrix; | 228 SkMatrix fLocalMatrix; |
356 SkMatrix fViewMatrix; | 229 SkMatrix fViewMatrix; |
357 | 230 |
358 typedef GrVertexBatch INHERITED; | 231 typedef GrVertexBatch INHERITED; |
359 }; | 232 }; |
360 | 233 |
361 namespace GrNonAAFillRectBatch { | 234 namespace GrNonAAFillRectBatch { |
362 | 235 |
363 GrDrawBatch* Create(GrColor color, | |
364 const SkMatrix& viewMatrix, | |
365 const SkRect& rect, | |
366 const SkRect* localRect, | |
367 const SkMatrix* localMatrix) { | |
368 return new NonAAFillRectBatch(color, viewMatrix, rect, localRect, localMatri
x); | |
369 } | |
370 | |
371 GrDrawBatch* CreateWithPerspective(GrColor color, | 236 GrDrawBatch* CreateWithPerspective(GrColor color, |
372 const SkMatrix& viewMatrix, | 237 const SkMatrix& viewMatrix, |
373 const SkRect& rect, | 238 const SkRect& rect, |
374 const SkRect* localRect, | 239 const SkRect* localRect, |
375 const SkMatrix* localMatrix) { | 240 const SkMatrix* localMatrix) { |
376 return new NonAAFillRectPerspectiveBatch(color, viewMatrix, rect, localRect,
localMatrix); | 241 return new GrNonAAFillRectPerspectiveBatch(color, viewMatrix, rect, localRec
t, localMatrix); |
377 } | 242 } |
378 | 243 |
379 }; | 244 }; |
380 | 245 |
381 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 246 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
382 | 247 |
383 #ifdef GR_TEST_UTILS | 248 #ifdef GR_TEST_UTILS |
384 | 249 |
385 #include "GrBatchTest.h" | 250 #include "GrBatchTest.h" |
386 | 251 |
387 DRAW_BATCH_TEST_DEFINE(RectBatch) { | 252 DRAW_BATCH_TEST_DEFINE(PerspRectBatch) { |
388 GrColor color = GrRandomColor(random); | 253 GrColor color = GrRandomColor(random); |
389 SkRect rect = GrTest::TestRect(random); | 254 SkRect rect = GrTest::TestRect(random); |
390 SkRect localRect = GrTest::TestRect(random); | 255 SkRect localRect = GrTest::TestRect(random); |
391 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 256 SkMatrix viewMatrix = GrTest::TestMatrix(random); |
392 SkMatrix localMatrix = GrTest::TestMatrix(random); | 257 bool hasLocalMatrix = random->nextBool(); |
| 258 SkMatrix localMatrix; |
| 259 if (!viewMatrix.hasPerspective()) { |
| 260 localMatrix = GrTest::TestMatrixPerspective(random); |
| 261 hasLocalMatrix = true; |
| 262 } |
393 | 263 |
394 bool hasLocalRect = random->nextBool(); | 264 bool hasLocalRect = random->nextBool(); |
395 bool hasLocalMatrix = random->nextBool(); | 265 return GrNonAAFillRectBatch::CreateWithPerspective(color, viewMatrix, rect, |
396 return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, | 266 hasLocalRect ? &localRect
: nullptr, |
397 hasLocalRect ? &localRect : nullptr, | 267 hasLocalMatrix ? &localMa
trix : nullptr); |
398 hasLocalMatrix ? &localMatrix : nullptr)
; | |
399 } | 268 } |
400 | 269 |
401 #endif | 270 #endif |
OLD | NEW |