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( | |
49 const SkMatrix& viewMatrix, | |
50 const GrXPOverridesForBatch& overrides, | |
51 GrDefaultGeoProcFactory::LocalCoords::Typ
e localCoordsType) { | |
52 using namespace GrDefaultGeoProcFactory; | |
53 | |
54 Color color(Color::kAttribute_Type); | |
55 Coverage::Type coverageType; | |
56 // TODO remove coverage if coverage is ignored | |
57 /*if (coverageIgnored) { | |
58 coverageType = Coverage::kNone_Type; | |
59 } else*/ if (overrides.canTweakAlphaForCoverage()) { | |
60 coverageType = Coverage::kSolid_Type; | |
61 } else { | |
62 coverageType = Coverage::kAttribute_Type; | |
63 } | |
64 Coverage coverage(coverageType); | |
65 | |
66 // We assume the caller has inverted the viewmatrix | |
67 if (LocalCoords::kHasExplicit_Type == localCoordsType) { | |
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 } | |
76 | |
77 static void generate_aa_fill_rect_geometry(intptr_t verts, | 48 static void generate_aa_fill_rect_geometry(intptr_t verts, |
78 size_t vertexStride, | 49 size_t vertexStride, |
79 GrColor color, | 50 GrColor color, |
80 const SkMatrix& viewMatrix, | 51 const SkMatrix& viewMatrix, |
81 const SkRect& rect, | 52 const SkRect& rect, |
82 const SkRect& devRect, | 53 const SkRect& devRect, |
83 const GrXPOverridesForBatch& override
s, | 54 const GrXPOverridesForBatch& override
s, |
84 const SkMatrix* localMatrix) { | 55 const SkMatrix* localMatrix) { |
85 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 56 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
86 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); | 57 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1]; | 101 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1]; |
131 // TR | 102 // TR |
132 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = | 103 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = |
133 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1
]; | 104 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1
]; |
134 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; | 105 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; |
135 } | 106 } |
136 | 107 |
137 if (localMatrix) { | 108 if (localMatrix) { |
138 SkMatrix invViewMatrix; | 109 SkMatrix invViewMatrix; |
139 if (!viewMatrix.invert(&invViewMatrix)) { | 110 if (!viewMatrix.invert(&invViewMatrix)) { |
140 SkASSERT(false); | 111 SkDebugf("View matrix is non-invertible, local coords will be wrong.
"); |
141 invViewMatrix = SkMatrix::I(); | 112 invViewMatrix = SkMatrix::I(); |
142 } | 113 } |
143 SkMatrix localCoordMatrix; | 114 SkMatrix localCoordMatrix; |
144 localCoordMatrix.setConcat(*localMatrix, invViewMatrix); | 115 localCoordMatrix.setConcat(*localMatrix, invViewMatrix); |
145 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) +
sizeof(GrColor)); | 116 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) +
sizeof(GrColor)); |
146 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); | 117 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); |
147 } | 118 } |
148 | 119 |
149 bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage(); | 120 bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage(); |
150 | 121 |
(...skipping 28 matching lines...) Expand all Loading... |
179 for (int i = 0; i < 4; ++i) { | 150 for (int i = 0; i < 4; ++i) { |
180 if (tweakAlphaForCoverage) { | 151 if (tweakAlphaForCoverage) { |
181 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 152 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
182 } else { | 153 } else { |
183 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 154 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
184 *reinterpret_cast<float*>(verts + i * vertexStride + | 155 *reinterpret_cast<float*>(verts + i * vertexStride + |
185 coverageOffset) = innerCoverage; | 156 coverageOffset) = innerCoverage; |
186 } | 157 } |
187 } | 158 } |
188 } | 159 } |
189 | 160 class AAFillRectBatch : public GrVertexBatch { |
190 class AAFillRectNoLocalMatrixBatch : public GrVertexBatch { | |
191 public: | 161 public: |
192 DEFINE_BATCH_CLASS_ID | 162 DEFINE_BATCH_CLASS_ID |
193 AAFillRectNoLocalMatrixBatch(GrColor color, | 163 |
194 const SkMatrix& viewMatrix, | 164 AAFillRectBatch(GrColor color, |
195 const SkRect& rect, | 165 const SkMatrix& viewMatrix, |
196 const SkRect& devRect) : INHERITED(ClassID()) { | 166 const SkRect& rect, |
197 fRects.emplace_back(RectInfo{color, viewMatrix, rect, devRect}); | 167 const SkRect& devRect, |
| 168 const SkMatrix* localMatrix) : INHERITED(ClassID()) { |
| 169 if (localMatrix) { |
| 170 void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo)); |
| 171 new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect,
*localMatrix); |
| 172 } else { |
| 173 void* mem = fRectData.push_back_n(sizeof(RectInfo)); |
| 174 new (mem) RectInfo(color, viewMatrix, rect, devRect); |
| 175 } |
198 fBounds = devRect; | 176 fBounds = devRect; |
| 177 fRectCnt = 1; |
199 } | 178 } |
200 | 179 |
201 const char* name() const override { return "AAFillRectBatchNoLocalMatrix"; } | 180 const char* name() const override { return "AAFillRectBatch"; } |
202 | 181 |
203 SkString dumpInfo() const override { | 182 SkString dumpInfo() const override { |
204 SkString str; | 183 SkString str; |
205 str.appendf("# batched: %d\n", fRects.count()); | 184 str.appendf("# batched: %d\n", fRectCnt); |
206 for (int i = 0; i < fRects.count(); ++i) { | 185 const RectInfo* info = this->first(); |
207 const RectInfo& info = fRects[i]; | 186 for (int i = 0; i < fRectCnt; ++i) { |
| 187 const SkRect& rect = info->rect(); |
208 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | 188 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", |
209 i, info.fColor, | 189 i, info->color(), rect.fLeft, rect.fTop, rect.fRight, re
ct.fBottom); |
210 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | 190 info = this->next(info); |
211 } | 191 } |
212 str.append(INHERITED::dumpInfo()); | 192 str.append(INHERITED::dumpInfo()); |
213 return str; | 193 return str; |
214 } | 194 } |
215 | 195 |
216 void computePipelineOptimizations(GrInitInvariantOutput* color, | 196 void computePipelineOptimizations(GrInitInvariantOutput* color, |
217 GrInitInvariantOutput* coverage, | 197 GrInitInvariantOutput* coverage, |
218 GrBatchToXPOverrides* overrides) const ove
rride { | 198 GrBatchToXPOverrides* overrides) const ove
rride { |
219 // When this is called on a batch, there is only one rect | 199 // When this is called on a batch, there is only one rect |
220 color->setKnownFourComponents(fRects[0].fColor); | 200 color->setKnownFourComponents(this->first()->color()); |
221 coverage->setUnknownSingleComponent(); | 201 coverage->setUnknownSingleComponent(); |
222 } | 202 } |
223 | 203 |
224 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 204 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
225 overrides.getOverrideColorIfSet(&fRects[0].fColor); | 205 GrColor color; |
| 206 if (overrides.getOverrideColorIfSet(&color)) { |
| 207 this->first()->setColor(color); |
| 208 } |
226 fOverrides = overrides; | 209 fOverrides = overrides; |
227 } | 210 } |
228 | 211 |
229 private: | 212 private: |
230 AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} | 213 void onPrepareDraws(Target* target) const override { |
| 214 bool needLocalCoords = fOverrides.readsLocalCoords(); |
| 215 using namespace GrDefaultGeoProcFactory; |
231 | 216 |
232 void onPrepareDraws(Target* target) const override { | 217 Color color(Color::kAttribute_Type); |
233 sk_sp<GrGeometryProcessor> gp = | 218 Coverage::Type coverageType; |
234 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, | 219 if (fOverrides.canTweakAlphaForCoverage()) { |
235 GrDefaultGeoProcFactory::LocalCoords::kUsePo
sition_Type); | 220 coverageType = Coverage::kSolid_Type; |
| 221 } else { |
| 222 coverageType = Coverage::kAttribute_Type; |
| 223 } |
| 224 Coverage coverage(coverageType); |
| 225 LocalCoords lc = needLocalCoords ? LocalCoords::kHasExplicit_Type |
| 226 : LocalCoords::kUnused_Type; |
| 227 sk_sp<GrGeometryProcessor> gp = GrDefaultGeoProcFactory::Make(color, cov
erage, lc, |
| 228 SkMatrix::
I()); |
236 if (!gp) { | 229 if (!gp) { |
237 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 230 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
238 return; | 231 return; |
239 } | 232 } |
240 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? | |
241 gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Po
sitionColorAttr) : | |
242 gp->getVertexStride() == | |
243 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAt
tr)); | |
244 | 233 |
245 size_t vertexStride = gp->getVertexStride(); | 234 size_t vertexStride = gp->getVertexStride(); |
246 | 235 |
247 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); | 236 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); |
248 InstancedHelper helper; | 237 InstancedHelper helper; |
249 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | 238 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
250 indexBuffer, kVertsPerAAFillRect, | 239 indexBuffer, kVertsPerAAFillRect, |
251 kIndicesPerAAFillRect, fRects.count()); | 240 kIndicesPerAAFillRect, fRectCnt); |
252 if (!vertices || !indexBuffer) { | 241 if (!vertices || !indexBuffer) { |
253 SkDebugf("Could not allocate vertices\n"); | 242 SkDebugf("Could not allocate vertices\n"); |
254 return; | 243 return; |
255 } | 244 } |
256 | 245 |
257 for (int i = 0; i < fRects.count(); i++) { | 246 const RectInfo* info = this->first(); |
| 247 const SkMatrix* localMatrix = nullptr; |
| 248 for (int i = 0; i < fRectCnt; i++) { |
258 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | 249 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
259 i * kVertsPerAAFillRect * vertexStride; | 250 i * kVertsPerAAFillRect * vertexStride; |
260 generate_aa_fill_rect_geometry(verts, vertexStride, | 251 if (needLocalCoords) { |
261 fRects[i].fColor, fRects[i].fViewMatr
ix, | 252 if (info->hasLocalMatrix()) { |
262 fRects[i].fRect, fRects[i].fDevRect,
fOverrides, | 253 localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(i
nfo)->localMatrix(); |
263 nullptr); | 254 } else { |
| 255 localMatrix = &SkMatrix::I(); |
| 256 } |
| 257 } |
| 258 generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), |
| 259 info->viewMatrix(), info->rect(), |
| 260 info->devRect(), fOverrides, localMat
rix); |
| 261 info = this->next(info); |
264 } | 262 } |
265 helper.recordDraw(target, gp.get()); | 263 helper.recordDraw(target, gp.get()); |
266 } | 264 } |
267 | 265 |
268 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 266 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
269 AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatc
h>(); | 267 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); |
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 { | |
308 public: | |
309 DEFINE_BATCH_CLASS_ID | |
310 | |
311 AAFillRectLocalMatrixBatch(GrColor color, | |
312 const SkMatrix& viewMatrix, | |
313 const SkMatrix& localMatrix, | |
314 const SkRect& rect, | |
315 const SkRect& devRect) : INHERITED(ClassID()) { | |
316 fRects.emplace_back(RectInfo{color, viewMatrix, localMatrix, rect, devRe
ct}); | |
317 fBounds = devRect; | |
318 } | |
319 | |
320 const char* name() const override { return "AAFillRectBatchLocalMatrix"; } | |
321 | |
322 SkString dumpInfo() const override { | |
323 SkString str; | |
324 str.appendf("# batched: %d\n", fRects.count()); | |
325 for (int i = 0; i < fRects.count(); ++i) { | |
326 const RectInfo& info = fRects[i]; | |
327 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | |
328 i, info.fColor, | |
329 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | |
330 } | |
331 str.append(INHERITED::dumpInfo()); | |
332 return str; | |
333 } | |
334 | |
335 void computePipelineOptimizations(GrInitInvariantOutput* color, | |
336 GrInitInvariantOutput* coverage, | |
337 GrBatchToXPOverrides* overrides) const ove
rride { | |
338 // When this is called on a batch, there is only one rect | |
339 color->setKnownFourComponents(fRects[0].fColor); | |
340 coverage->setUnknownSingleComponent(); | |
341 } | |
342 | |
343 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | |
344 overrides.getOverrideColorIfSet(&fRects[0].fColor); | |
345 fOverrides = overrides; | |
346 } | |
347 | |
348 private: | |
349 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} | |
350 | |
351 void onPrepareDraws(Target* target) const override { | |
352 sk_sp<GrGeometryProcessor> gp = | |
353 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, | |
354 GrDefaultGeoProcFactory::LocalCoords::kHasEx
plicit_Type); | |
355 if (!gp) { | |
356 SkDebugf("Couldn't create GrGeometryProcessor\n"); | |
357 return; | |
358 } | |
359 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? | |
360 gp->getVertexStride() == | |
361 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : | |
362 gp->getVertexStride() == | |
363 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage
)); | |
364 | |
365 size_t vertexStride = gp->getVertexStride(); | |
366 | |
367 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); | |
368 InstancedHelper helper; | |
369 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | |
370 indexBuffer, kVertsPerAAFillRect, | |
371 kIndicesPerAAFillRect, fRects.count()); | |
372 if (!vertices || !indexBuffer) { | |
373 SkDebugf("Could not allocate vertices\n"); | |
374 return; | |
375 } | |
376 | |
377 for (int i = 0; i < fRects.count(); i++) { | |
378 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | |
379 i * kVertsPerAAFillRect * vertexStride; | |
380 generate_aa_fill_rect_geometry(verts, vertexStride, fRects[i].fColor
, | |
381 fRects[i].fViewMatrix, fRects[i].fRec
t, | |
382 fRects[i].fDevRect, fOverrides, | |
383 &fRects[i].fLocalMatrix); | |
384 } | |
385 helper.recordDraw(target, gp.get()); | |
386 } | |
387 | |
388 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | |
389 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>()
; | |
390 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 268 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
391 that->bounds(), caps)) { | 269 that->bounds(), caps)) { |
392 return false; | 270 return false; |
393 } | 271 } |
394 | 272 |
395 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | 273 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
396 // not tweaking | 274 // not tweaking |
397 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | 275 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
398 fOverrides = that->fOverrides; | 276 fOverrides = that->fOverrides; |
399 } | 277 } |
400 | 278 |
401 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | 279 fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin()); |
| 280 fRectCnt += that->fRectCnt; |
402 this->joinBounds(that->bounds()); | 281 this->joinBounds(that->bounds()); |
403 return true; | 282 return true; |
404 } | 283 } |
405 | 284 |
406 struct RectInfo { | 285 struct RectInfo { |
| 286 public: |
| 287 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
| 288 const SkRect& devRect) |
| 289 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {} |
| 290 bool hasLocalMatrix() const { return HasLocalMatrix::kYes == fHasLocalMa
trix; } |
| 291 GrColor color() const { return fColor; } |
| 292 const SkMatrix& viewMatrix() const { return fViewMatrix; } |
| 293 const SkRect& rect() const { return fRect; } |
| 294 const SkRect& devRect() const { return fDevRect; } |
| 295 |
| 296 void setColor(GrColor color) { fColor = color; } |
| 297 protected: |
| 298 enum class HasLocalMatrix : uint32_t { kNo, kYes }; |
| 299 |
| 300 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
| 301 const SkRect& devRect, HasLocalMatrix hasLM) |
| 302 : fHasLocalMatrix(hasLM) |
| 303 , fColor(color) |
| 304 , fViewMatrix(viewMatrix) |
| 305 , fRect(rect) |
| 306 , fDevRect(devRect) {} |
| 307 |
| 308 HasLocalMatrix fHasLocalMatrix; |
407 GrColor fColor; | 309 GrColor fColor; |
408 SkMatrix fViewMatrix; | 310 SkMatrix fViewMatrix; |
409 SkMatrix fLocalMatrix; | |
410 SkRect fRect; | 311 SkRect fRect; |
411 SkRect fDevRect; | 312 SkRect fDevRect; |
412 }; | 313 }; |
413 | 314 |
| 315 struct RectWithLocalMatrixInfo : public RectInfo { |
| 316 public: |
| 317 RectWithLocalMatrixInfo(GrColor color, const SkMatrix& viewMatrix, const
SkRect& rect, |
| 318 const SkRect& devRect, const SkMatrix& localMatr
ix) |
| 319 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes) |
| 320 , fLocalMatrix(localMatrix) {} |
| 321 const SkMatrix& localMatrix() const { return fLocalMatrix; } |
| 322 private: |
| 323 SkMatrix fLocalMatrix; |
| 324 }; |
| 325 |
| 326 RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); } |
| 327 const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRe
ctData.begin()); } |
| 328 const RectInfo* next(const RectInfo* prev) const { |
| 329 intptr_t next = reinterpret_cast<intptr_t>(prev) + |
| 330 (prev->hasLocalMatrix() ? sizeof(RectWithLocalMatrixInfo) |
| 331 : sizeof(RectInfo)); |
| 332 return reinterpret_cast<const RectInfo*>(next); |
| 333 } |
| 334 |
414 GrXPOverridesForBatch fOverrides; | 335 GrXPOverridesForBatch fOverrides; |
415 SkSTArray<1, RectInfo, true> fRects; | 336 SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData; |
| 337 int fRectCnt; |
416 | 338 |
417 typedef GrVertexBatch INHERITED; | 339 typedef GrVertexBatch INHERITED; |
418 }; | 340 }; |
419 | 341 |
420 namespace GrAAFillRectBatch { | 342 namespace GrAAFillRectBatch { |
421 | 343 |
422 GrDrawBatch* Create(GrColor color, | 344 GrDrawBatch* Create(GrColor color, |
423 const SkMatrix& viewMatrix, | 345 const SkMatrix& viewMatrix, |
424 const SkRect& rect, | 346 const SkRect& rect, |
425 const SkRect& devRect) { | 347 const SkRect& devRect) { |
426 return new AAFillRectNoLocalMatrixBatch(color, viewMatrix, rect, devRect); | 348 return new AAFillRectBatch(color, viewMatrix, rect, devRect, nullptr); |
427 } | 349 } |
428 | 350 |
429 GrDrawBatch* Create(GrColor color, | 351 GrDrawBatch* Create(GrColor color, |
430 const SkMatrix& viewMatrix, | 352 const SkMatrix& viewMatrix, |
431 const SkMatrix& localMatrix, | 353 const SkMatrix& localMatrix, |
432 const SkRect& rect, | 354 const SkRect& rect, |
433 const SkRect& devRect) { | 355 const SkRect& devRect) { |
434 return new AAFillRectLocalMatrixBatch(color, viewMatrix, localMatrix, rect,
devRect); | 356 return new AAFillRectBatch(color, viewMatrix, rect, devRect, &localMatrix); |
435 } | 357 } |
436 | 358 |
437 GrDrawBatch* Create(GrColor color, | 359 GrDrawBatch* Create(GrColor color, |
438 const SkMatrix& viewMatrix, | 360 const SkMatrix& viewMatrix, |
439 const SkMatrix& localMatrix, | 361 const SkMatrix& localMatrix, |
440 const SkRect& rect) { | 362 const SkRect& rect) { |
441 SkRect devRect; | 363 SkRect devRect; |
442 viewMatrix.mapRect(&devRect, rect); | 364 viewMatrix.mapRect(&devRect, rect); |
443 return Create(color, viewMatrix, localMatrix, rect, devRect); | 365 return Create(color, viewMatrix, localMatrix, rect, devRect); |
444 } | 366 } |
(...skipping 30 matching lines...) Expand all Loading... |
475 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { | 397 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { |
476 GrColor color = GrRandomColor(random); | 398 GrColor color = GrRandomColor(random); |
477 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 399 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
478 SkMatrix localMatrix = GrTest::TestMatrix(random); | 400 SkMatrix localMatrix = GrTest::TestMatrix(random); |
479 SkRect rect = GrTest::TestRect(random); | 401 SkRect rect = GrTest::TestRect(random); |
480 SkRect devRect = GrTest::TestRect(random); | 402 SkRect devRect = GrTest::TestRect(random); |
481 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); | 403 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); |
482 } | 404 } |
483 | 405 |
484 #endif | 406 #endif |
OLD | NEW |