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 "GrAAFillRectBatch.h" | 8 #include "GrAAFillRectBatch.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
11 #include "GrColor.h" | 11 #include "GrColor.h" |
12 #include "GrDefaultGeoProcFactory.h" | 12 #include "GrDefaultGeoProcFactory.h" |
13 #include "GrResourceKey.h" | 13 #include "GrResourceKey.h" |
14 #include "GrResourceProvider.h" | 14 #include "GrResourceProvider.h" |
15 #include "GrTypes.h" | 15 #include "GrTypes.h" |
| 16 #include "GrVertexBatch.h" |
16 #include "SkMatrix.h" | 17 #include "SkMatrix.h" |
17 #include "SkRect.h" | 18 #include "SkRect.h" |
18 #include "GrVertexBatch.h" | |
19 | 19 |
20 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); | 20 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); |
21 | 21 |
22 static void set_inset_fan(SkPoint* pts, size_t stride, | 22 static void set_inset_fan(SkPoint* pts, size_t stride, |
23 const SkRect& r, SkScalar dx, SkScalar dy) { | 23 const SkRect& r, SkScalar dx, SkScalar dy) { |
24 pts->setRectFan(r.fLeft + dx, r.fTop + dy, | 24 pts->setRectFan(r.fLeft + dx, r.fTop + dy, |
25 r.fRight - dx, r.fBottom - dy, stride); | 25 r.fRight - dx, r.fBottom - dy, stride); |
26 } | 26 } |
27 | 27 |
28 static const int kNumAAFillRectsInIndexBuffer = 256; | 28 static const int kNumAAFillRectsInIndexBuffer = 256; |
29 static const int kVertsPerAAFillRect = 8; | 29 static const int kVertsPerAAFillRect = 8; |
30 static const int kIndicesPerAAFillRect = 30; | 30 static const int kIndicesPerAAFillRect = 30; |
31 | 31 |
32 const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) { | 32 const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) { |
33 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); | 33 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); |
34 | 34 |
35 static const uint16_t gFillAARectIdx[] = { | 35 static const uint16_t gFillAARectIdx[] = { |
36 0, 1, 5, 5, 4, 0, | 36 0, 1, 5, 5, 4, 0, |
37 1, 2, 6, 6, 5, 1, | 37 1, 2, 6, 6, 5, 1, |
38 2, 3, 7, 7, 6, 2, | 38 2, 3, 7, 7, 6, 2, |
39 3, 0, 4, 4, 7, 3, | 39 3, 0, 4, 4, 7, 3, |
40 4, 5, 6, 6, 7, 4, | 40 4, 5, 6, 6, 7, 4, |
41 }; | 41 }; |
42 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect); | 42 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect); |
43 return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx, | 43 return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx, |
44 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect
, | 44 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect
, |
45 gAAFillRectIndexBufferKey); | 45 gAAFillRectIndexBufferKey); |
46 } | 46 } |
47 | 47 |
48 static sk_sp<GrGeometryProcessor> create_fill_rect_gp( | 48 static sk_sp<GrGeometryProcessor> create_fill_rect_gp(const GrXPOverridesForBatc
h& overrides, |
49 const SkMatrix& viewMatrix, | 49 bool hasLocalMatrix) { |
50 const GrXPOverridesForBatch& overrides, | |
51 GrDefaultGeoProcFactory::LocalCoords::Typ
e localCoordsType) { | |
52 using namespace GrDefaultGeoProcFactory; | 50 using namespace GrDefaultGeoProcFactory; |
53 | 51 |
54 Color color(Color::kAttribute_Type); | 52 Color color(Color::kAttribute_Type); |
55 Coverage::Type coverageType; | 53 Coverage::Type coverageType; |
56 // TODO remove coverage if coverage is ignored | 54 // TODO remove coverage if coverage is ignored |
57 /*if (coverageIgnored) { | 55 /*if (coverageIgnored) { |
58 coverageType = Coverage::kNone_Type; | 56 coverageType = Coverage::kNone_Type; |
59 } else*/ if (overrides.canTweakAlphaForCoverage()) { | 57 } else*/ if (overrides.canTweakAlphaForCoverage()) { |
60 coverageType = Coverage::kSolid_Type; | 58 coverageType = Coverage::kSolid_Type; |
61 } else { | 59 } else { |
62 coverageType = Coverage::kAttribute_Type; | 60 coverageType = Coverage::kAttribute_Type; |
63 } | 61 } |
64 Coverage coverage(coverageType); | 62 Coverage coverage(coverageType); |
65 | 63 |
| 64 LocalCoords lc = hasLocalMatrix ? LocalCoords::kHasExplicit_Type : LocalCoor
ds::kUsePosition_Type; |
66 // We assume the caller has inverted the viewmatrix | 65 // We assume the caller has inverted the viewmatrix |
67 if (LocalCoords::kHasExplicit_Type == localCoordsType) { | 66 return GrDefaultGeoProcFactory::Make(color, coverage, lc, SkMatrix::I()); |
68 LocalCoords localCoords(localCoordsType); | |
69 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMat
rix::I()); | |
70 } else { | |
71 LocalCoords localCoords(overrides.readsLocalCoords() ? localCoordsType : | |
72 LocalCoords::kUnu
sed_Type); | |
73 return MakeForDeviceSpace(color, coverage, localCoords, viewMatrix); | |
74 } | |
75 } | 67 } |
76 | 68 |
77 static void generate_aa_fill_rect_geometry(intptr_t verts, | 69 static void generate_aa_fill_rect_geometry(intptr_t verts, |
78 size_t vertexStride, | 70 size_t vertexStride, |
79 GrColor color, | 71 GrColor color, |
80 const SkMatrix& viewMatrix, | 72 const SkMatrix& viewMatrix, |
81 const SkRect& rect, | 73 const SkRect& rect, |
82 const SkRect& devRect, | 74 const SkRect& devRect, |
83 const GrXPOverridesForBatch& override
s, | 75 const GrXPOverridesForBatch& override
s, |
84 const SkMatrix* localMatrix) { | 76 const SkMatrix* localMatrix) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 for (int i = 0; i < 4; ++i) { | 171 for (int i = 0; i < 4; ++i) { |
180 if (tweakAlphaForCoverage) { | 172 if (tweakAlphaForCoverage) { |
181 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 173 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
182 } else { | 174 } else { |
183 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 175 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
184 *reinterpret_cast<float*>(verts + i * vertexStride + | 176 *reinterpret_cast<float*>(verts + i * vertexStride + |
185 coverageOffset) = innerCoverage; | 177 coverageOffset) = innerCoverage; |
186 } | 178 } |
187 } | 179 } |
188 } | 180 } |
189 | |
190 class AAFillRectNoLocalMatrixBatch : public GrVertexBatch { | |
191 public: | |
192 DEFINE_BATCH_CLASS_ID | |
193 AAFillRectNoLocalMatrixBatch(GrColor color, | |
194 const SkMatrix& viewMatrix, | |
195 const SkRect& rect, | |
196 const SkRect& devRect) : INHERITED(ClassID()) { | |
197 fRects.emplace_back(RectInfo{color, viewMatrix, rect, devRect}); | |
198 fBounds = devRect; | |
199 } | |
200 | |
201 const char* name() const override { return "AAFillRectBatchNoLocalMatrix"; } | |
202 | |
203 SkString dumpInfo() const override { | |
204 SkString str; | |
205 str.appendf("# batched: %d\n", fRects.count()); | |
206 for (int i = 0; i < fRects.count(); ++i) { | |
207 const RectInfo& info = fRects[i]; | |
208 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | |
209 i, info.fColor, | |
210 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | |
211 } | |
212 str.append(INHERITED::dumpInfo()); | |
213 return str; | |
214 } | |
215 | |
216 void computePipelineOptimizations(GrInitInvariantOutput* color, | |
217 GrInitInvariantOutput* coverage, | |
218 GrBatchToXPOverrides* overrides) const ove
rride { | |
219 // When this is called on a batch, there is only one rect | |
220 color->setKnownFourComponents(fRects[0].fColor); | |
221 coverage->setUnknownSingleComponent(); | |
222 } | |
223 | |
224 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | |
225 overrides.getOverrideColorIfSet(&fRects[0].fColor); | |
226 fOverrides = overrides; | |
227 } | |
228 | |
229 private: | |
230 AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} | |
231 | |
232 void onPrepareDraws(Target* target) const override { | |
233 sk_sp<GrGeometryProcessor> gp = | |
234 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, | |
235 GrDefaultGeoProcFactory::LocalCoords::kUsePo
sition_Type); | |
236 if (!gp) { | |
237 SkDebugf("Couldn't create GrGeometryProcessor\n"); | |
238 return; | |
239 } | |
240 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? | |
241 gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Po
sitionColorAttr) : | |
242 gp->getVertexStride() == | |
243 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAt
tr)); | |
244 | |
245 size_t vertexStride = gp->getVertexStride(); | |
246 | |
247 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); | |
248 InstancedHelper helper; | |
249 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | |
250 indexBuffer, kVertsPerAAFillRect, | |
251 kIndicesPerAAFillRect, fRects.count()); | |
252 if (!vertices || !indexBuffer) { | |
253 SkDebugf("Could not allocate vertices\n"); | |
254 return; | |
255 } | |
256 | |
257 for (int i = 0; i < fRects.count(); i++) { | |
258 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | |
259 i * kVertsPerAAFillRect * vertexStride; | |
260 generate_aa_fill_rect_geometry(verts, vertexStride, | |
261 fRects[i].fColor, fRects[i].fViewMatr
ix, | |
262 fRects[i].fRect, fRects[i].fDevRect,
fOverrides, | |
263 nullptr); | |
264 } | |
265 helper.recordDraw(target, gp.get()); | |
266 } | |
267 | |
268 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | |
269 AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatc
h>(); | |
270 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | |
271 that->bounds(), caps)) { | |
272 return false; | |
273 } | |
274 | |
275 // We apply the viewmatrix to the rect points on the cpu. However, if t
he pipeline uses | |
276 // local coords then we won't be able to batch. We could actually uploa
d the viewmatrix | |
277 // using vertex attributes in these cases, but haven't investigated that | |
278 if (fOverrides.readsLocalCoords() && | |
279 !fRects[0].fViewMatrix.cheapEqualTo(that->fRects[0].fViewMatrix)) { | |
280 return false; | |
281 } | |
282 | |
283 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | |
284 // not tweaking | |
285 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | |
286 fOverrides = that->fOverrides; | |
287 } | |
288 | |
289 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | |
290 this->joinBounds(that->bounds()); | |
291 return true; | |
292 } | |
293 | |
294 struct RectInfo { | |
295 GrColor fColor; | |
296 SkMatrix fViewMatrix; | |
297 SkRect fRect; | |
298 SkRect fDevRect; | |
299 }; | |
300 | |
301 GrXPOverridesForBatch fOverrides; | |
302 SkSTArray<1, RectInfo, true> fRects; | |
303 | |
304 typedef GrVertexBatch INHERITED; | |
305 }; | |
306 | |
307 class AAFillRectLocalMatrixBatch : public GrVertexBatch { | 181 class AAFillRectLocalMatrixBatch : public GrVertexBatch { |
308 public: | 182 public: |
309 DEFINE_BATCH_CLASS_ID | 183 DEFINE_BATCH_CLASS_ID |
310 | 184 |
311 AAFillRectLocalMatrixBatch(GrColor color, | 185 AAFillRectLocalMatrixBatch(GrColor color, |
312 const SkMatrix& viewMatrix, | 186 const SkMatrix& viewMatrix, |
313 const SkMatrix& localMatrix, | |
314 const SkRect& rect, | 187 const SkRect& rect, |
315 const SkRect& devRect) : INHERITED(ClassID()) { | 188 const SkRect& devRect, |
316 fRects.emplace_back(RectInfo{color, viewMatrix, localMatrix, rect, devRe
ct}); | 189 const SkMatrix* localMatrix) : INHERITED(ClassID(
)) { |
| 190 if (localMatrix) { |
| 191 void* mem = fRectData.append(sizeof(RectWithLocalMatrixInfo)); |
| 192 new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect,
*localMatrix); |
| 193 fUseLocalMatrix = true; |
| 194 } else { |
| 195 void* mem = fRectData.append(sizeof(RectInfo)); |
| 196 new (mem) RectInfo(color, viewMatrix, rect, devRect); |
| 197 fUseLocalMatrix = false; |
| 198 } |
317 fBounds = devRect; | 199 fBounds = devRect; |
| 200 fRectCnt = 1; |
318 } | 201 } |
319 | 202 |
320 const char* name() const override { return "AAFillRectBatchLocalMatrix"; } | 203 const char* name() const override { return "AAFillRectBatchLocalMatrix"; } |
321 | 204 |
322 SkString dumpInfo() const override { | 205 SkString dumpInfo() const override { |
323 SkString str; | 206 SkString str; |
324 str.appendf("# batched: %d\n", fRects.count()); | 207 str.appendf("# batched: %d\n", fRectCnt); |
325 for (int i = 0; i < fRects.count(); ++i) { | 208 const RectInfo* info = this->first(); |
326 const RectInfo& info = fRects[i]; | 209 for (int i = 0; i < fRectCnt; ++i) { |
| 210 const SkRect& rect = info->rect(); |
327 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | 211 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", |
328 i, info.fColor, | 212 i, info->color(), rect.fLeft, rect.fTop, rect.fRight, re
ct.fBottom); |
329 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | 213 info = this->next(info); |
330 } | 214 } |
331 str.append(INHERITED::dumpInfo()); | 215 str.append(INHERITED::dumpInfo()); |
332 return str; | 216 return str; |
333 } | 217 } |
334 | 218 |
335 void computePipelineOptimizations(GrInitInvariantOutput* color, | 219 void computePipelineOptimizations(GrInitInvariantOutput* color, |
336 GrInitInvariantOutput* coverage, | 220 GrInitInvariantOutput* coverage, |
337 GrBatchToXPOverrides* overrides) const ove
rride { | 221 GrBatchToXPOverrides* overrides) const ove
rride { |
338 // When this is called on a batch, there is only one rect | 222 // When this is called on a batch, there is only one rect |
339 color->setKnownFourComponents(fRects[0].fColor); | 223 color->setKnownFourComponents(this->first()->color()); |
340 coverage->setUnknownSingleComponent(); | 224 coverage->setUnknownSingleComponent(); |
341 } | 225 } |
342 | 226 |
343 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 227 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
344 overrides.getOverrideColorIfSet(&fRects[0].fColor); | 228 GrColor color; |
| 229 if (overrides.getOverrideColorIfSet(&color)) { |
| 230 this->first()->setColor(color); |
| 231 } |
345 fOverrides = overrides; | 232 fOverrides = overrides; |
| 233 if (!overrides.readsLocalCoords() && false) { |
| 234 fUseLocalMatrix = false; |
| 235 } |
346 } | 236 } |
347 | 237 |
348 private: | 238 private: |
349 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} | 239 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} |
350 | 240 |
351 void onPrepareDraws(Target* target) const override { | 241 void onPrepareDraws(Target* target) const override { |
352 sk_sp<GrGeometryProcessor> gp = | 242 sk_sp<GrGeometryProcessor> gp = create_fill_rect_gp(fOverrides, fUseLoca
lMatrix); |
353 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, | |
354 GrDefaultGeoProcFactory::LocalCoords::kHasEx
plicit_Type); | |
355 if (!gp) { | 243 if (!gp) { |
356 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 244 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
357 return; | 245 return; |
358 } | 246 } |
359 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? | 247 if (fOverrides.canTweakAlphaForCoverage()) { |
360 gp->getVertexStride() == | 248 if (fUseLocalMatrix) { |
361 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : | 249 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory
::PositionColorLocalCoordAttr)); |
362 gp->getVertexStride() == | 250 } else { |
363 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage
)); | 251 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory
::PositionColorAttr)); |
364 | 252 } |
| 253 } else { |
| 254 if (fUseLocalMatrix) { |
| 255 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory
::PositionColorLocalCoordCoverage)); |
| 256 } else { |
| 257 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory
::PositionColorCoverageAttr)); |
| 258 } |
| 259 } |
365 size_t vertexStride = gp->getVertexStride(); | 260 size_t vertexStride = gp->getVertexStride(); |
366 | 261 |
367 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); | 262 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); |
368 InstancedHelper helper; | 263 InstancedHelper helper; |
369 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | 264 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
370 indexBuffer, kVertsPerAAFillRect, | 265 indexBuffer, kVertsPerAAFillRect, |
371 kIndicesPerAAFillRect, fRects.count()); | 266 kIndicesPerAAFillRect, fRectCnt); |
372 if (!vertices || !indexBuffer) { | 267 if (!vertices || !indexBuffer) { |
373 SkDebugf("Could not allocate vertices\n"); | 268 SkDebugf("Could not allocate vertices\n"); |
374 return; | 269 return; |
375 } | 270 } |
376 | 271 |
377 for (int i = 0; i < fRects.count(); i++) { | 272 const RectInfo* info = this->first(); |
| 273 for (int i = 0; i < fRectCnt; i++) { |
378 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | 274 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
379 i * kVertsPerAAFillRect * vertexStride; | 275 i * kVertsPerAAFillRect * vertexStride; |
380 generate_aa_fill_rect_geometry(verts, vertexStride, fRects[i].fColor
, | 276 const SkMatrix* localMatrix = nullptr; |
381 fRects[i].fViewMatrix, fRects[i].fRec
t, | 277 if (fUseLocalMatrix) { |
382 fRects[i].fDevRect, fOverrides, | 278 if (HasLocalMatrix::kYes == info->hasLocalMatrix()) { |
383 &fRects[i].fLocalMatrix); | 279 localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(i
nfo)->localMatrix(); |
| 280 } else { |
| 281 localMatrix = &SkMatrix::I(); |
| 282 } |
| 283 } |
| 284 generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), |
| 285 info->viewMatrix(), info->rect(), |
| 286 info->devRect(), fOverrides, localMat
rix); |
| 287 info = this->next(info); |
384 } | 288 } |
385 helper.recordDraw(target, gp.get()); | 289 helper.recordDraw(target, gp.get()); |
386 } | 290 } |
387 | 291 |
388 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 292 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 293 return false; |
389 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>()
; | 294 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>()
; |
390 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 295 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
391 that->bounds(), caps)) { | 296 that->bounds(), caps)) { |
392 return false; | 297 return false; |
393 } | 298 } |
394 | 299 |
395 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | 300 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
396 // not tweaking | 301 // not tweaking |
397 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | 302 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
398 fOverrides = that->fOverrides; | 303 fOverrides = that->fOverrides; |
399 } | 304 } |
400 | 305 |
401 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | 306 fRectData.append(that->fRectData.count(), that->fRectData.begin()); |
| 307 fRectCnt += that->fRectCnt; |
402 this->joinBounds(that->bounds()); | 308 this->joinBounds(that->bounds()); |
| 309 fUseLocalMatrix = (fUseLocalMatrix || that->fUseLocalMatrix); |
403 return true; | 310 return true; |
404 } | 311 } |
405 | 312 |
| 313 enum class HasLocalMatrix : uint32_t { kNo, kYes }; |
| 314 |
406 struct RectInfo { | 315 struct RectInfo { |
| 316 public: |
| 317 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
| 318 const SkRect& devRect) |
| 319 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {} |
| 320 HasLocalMatrix hasLocalMatrix() const { return fHasLocalMatrix; } |
| 321 GrColor color() const { return fColor; } |
| 322 const SkMatrix& viewMatrix() const { return fViewMatrix; } |
| 323 const SkRect& rect() const { return fRect; } |
| 324 const SkRect& devRect() const { return fDevRect; } |
| 325 |
| 326 void setColor(GrColor color) { fColor = color; } |
| 327 protected: |
| 328 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
| 329 const SkRect& devRect, HasLocalMatrix hasLM) |
| 330 : fHasLocalMatrix(hasLM) |
| 331 , fColor(color) |
| 332 , fViewMatrix(viewMatrix) |
| 333 , fRect(rect) |
| 334 , fDevRect(devRect) {} |
| 335 |
| 336 HasLocalMatrix fHasLocalMatrix ; |
407 GrColor fColor; | 337 GrColor fColor; |
408 SkMatrix fViewMatrix; | 338 SkMatrix fViewMatrix; |
409 SkMatrix fLocalMatrix; | |
410 SkRect fRect; | 339 SkRect fRect; |
411 SkRect fDevRect; | 340 SkRect fDevRect; |
412 }; | 341 }; |
413 | 342 |
| 343 struct RectWithLocalMatrixInfo : public RectInfo { |
| 344 public: |
| 345 RectWithLocalMatrixInfo(GrColor color, const SkMatrix& viewMatrix, const
SkRect& rect, |
| 346 const SkRect& devRect, const SkMatrix& localMatri
x) |
| 347 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes) |
| 348 , fLocalMatrix(localMatrix) {} |
| 349 const SkMatrix& localMatrix() const { return fLocalMatrix; } |
| 350 private: |
| 351 SkMatrix fLocalMatrix; |
| 352 }; |
| 353 |
| 354 RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); } |
| 355 const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRe
ctData.begin()); } |
| 356 const RectInfo* next(const RectInfo* prev) const { |
| 357 intptr_t next = reinterpret_cast<intptr_t>(prev) + |
| 358 (HasLocalMatrix::kYes == prev->hasLocalMatrix() |
| 359 ? sizeof(RectWithLocalMatrixInfo) |
| 360 : sizeof(RectInfo)); |
| 361 return reinterpret_cast<const RectInfo*>(next); |
| 362 } |
| 363 |
414 GrXPOverridesForBatch fOverrides; | 364 GrXPOverridesForBatch fOverrides; |
415 SkSTArray<1, RectInfo, true> fRects; | 365 SkTDArray<uint8_t> fRectData; |
| 366 int fRectCnt; |
| 367 bool fUseLocalMatrix; |
416 | 368 |
417 typedef GrVertexBatch INHERITED; | 369 typedef GrVertexBatch INHERITED; |
418 }; | 370 }; |
419 | 371 |
420 namespace GrAAFillRectBatch { | 372 namespace GrAAFillRectBatch { |
421 | 373 |
422 GrDrawBatch* Create(GrColor color, | 374 GrDrawBatch* Create(GrColor color, |
423 const SkMatrix& viewMatrix, | 375 const SkMatrix& viewMatrix, |
424 const SkRect& rect, | 376 const SkRect& rect, |
425 const SkRect& devRect) { | 377 const SkRect& devRect) { |
426 return new AAFillRectNoLocalMatrixBatch(color, viewMatrix, rect, devRect); | 378 return new AAFillRectLocalMatrixBatch(color, viewMatrix, rect, devRect, null
ptr); |
427 } | 379 } |
428 | 380 |
429 GrDrawBatch* Create(GrColor color, | 381 GrDrawBatch* Create(GrColor color, |
430 const SkMatrix& viewMatrix, | 382 const SkMatrix& viewMatrix, |
431 const SkMatrix& localMatrix, | 383 const SkMatrix& localMatrix, |
432 const SkRect& rect, | 384 const SkRect& rect, |
433 const SkRect& devRect) { | 385 const SkRect& devRect) { |
434 return new AAFillRectLocalMatrixBatch(color, viewMatrix, localMatrix, rect,
devRect); | 386 return new AAFillRectLocalMatrixBatch(color, viewMatrix, rect, devRect, &loc
alMatrix); |
435 } | 387 } |
436 | 388 |
437 GrDrawBatch* Create(GrColor color, | 389 GrDrawBatch* Create(GrColor color, |
438 const SkMatrix& viewMatrix, | 390 const SkMatrix& viewMatrix, |
439 const SkMatrix& localMatrix, | 391 const SkMatrix& localMatrix, |
440 const SkRect& rect) { | 392 const SkRect& rect) { |
441 SkRect devRect; | 393 SkRect devRect; |
442 viewMatrix.mapRect(&devRect, rect); | 394 viewMatrix.mapRect(&devRect, rect); |
443 return Create(color, viewMatrix, localMatrix, rect, devRect); | 395 return Create(color, viewMatrix, localMatrix, rect, devRect); |
444 } | 396 } |
(...skipping 30 matching lines...) Expand all Loading... |
475 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { | 427 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { |
476 GrColor color = GrRandomColor(random); | 428 GrColor color = GrRandomColor(random); |
477 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 429 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
478 SkMatrix localMatrix = GrTest::TestMatrix(random); | 430 SkMatrix localMatrix = GrTest::TestMatrix(random); |
479 SkRect rect = GrTest::TestRect(random); | 431 SkRect rect = GrTest::TestRect(random); |
480 SkRect devRect = GrTest::TestRect(random); | 432 SkRect devRect = GrTest::TestRect(random); |
481 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); | 433 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); |
482 } | 434 } |
483 | 435 |
484 #endif | 436 #endif |
OLD | NEW |