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 | |
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 { | 160 class AAFillRectLocalMatrixBatch : public GrVertexBatch { |
308 public: | 161 public: |
309 DEFINE_BATCH_CLASS_ID | 162 DEFINE_BATCH_CLASS_ID |
310 | 163 |
311 AAFillRectLocalMatrixBatch(GrColor color, | 164 AAFillRectLocalMatrixBatch(GrColor color, |
312 const SkMatrix& viewMatrix, | 165 const SkMatrix& viewMatrix, |
313 const SkMatrix& localMatrix, | |
314 const SkRect& rect, | 166 const SkRect& rect, |
315 const SkRect& devRect) : INHERITED(ClassID()) { | 167 const SkRect& devRect, |
316 fRects.emplace_back(RectInfo{color, viewMatrix, localMatrix, rect, devRe ct}); | 168 const SkMatrix* localMatrix) : INHERITED(ClassID( )) { |
169 if (localMatrix) { | |
170 void* mem = fRectData.append(sizeof(RectWithLocalMatrixInfo)); | |
171 new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix); | |
172 } else { | |
173 void* mem = fRectData.append(sizeof(RectInfo)); | |
174 new (mem) RectInfo(color, viewMatrix, rect, devRect); | |
175 } | |
317 fBounds = devRect; | 176 fBounds = devRect; |
177 fRectCnt = 1; | |
318 } | 178 } |
319 | 179 |
320 const char* name() const override { return "AAFillRectBatchLocalMatrix"; } | 180 const char* name() const override { return "AAFillRectBatchLocalMatrix"; } |
321 | 181 |
322 SkString dumpInfo() const override { | 182 SkString dumpInfo() const override { |
323 SkString str; | 183 SkString str; |
324 str.appendf("# batched: %d\n", fRects.count()); | 184 str.appendf("# batched: %d\n", fRectCnt); |
325 for (int i = 0; i < fRects.count(); ++i) { | 185 const RectInfo* info = this->first(); |
326 const RectInfo& info = fRects[i]; | 186 for (int i = 0; i < fRectCnt; ++i) { |
187 const SkRect& rect = info->rect(); | |
327 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", |
328 i, info.fColor, | 189 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); | 190 info = this->next(info); |
330 } | 191 } |
331 str.append(INHERITED::dumpInfo()); | 192 str.append(INHERITED::dumpInfo()); |
332 return str; | 193 return str; |
333 } | 194 } |
334 | 195 |
335 void computePipelineOptimizations(GrInitInvariantOutput* color, | 196 void computePipelineOptimizations(GrInitInvariantOutput* color, |
336 GrInitInvariantOutput* coverage, | 197 GrInitInvariantOutput* coverage, |
337 GrBatchToXPOverrides* overrides) const ove rride { | 198 GrBatchToXPOverrides* overrides) const ove rride { |
338 // 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 |
339 color->setKnownFourComponents(fRects[0].fColor); | 200 color->setKnownFourComponents(this->first()->color()); |
340 coverage->setUnknownSingleComponent(); | 201 coverage->setUnknownSingleComponent(); |
341 } | 202 } |
342 | 203 |
343 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 204 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
344 overrides.getOverrideColorIfSet(&fRects[0].fColor); | 205 GrColor color; |
206 if (overrides.getOverrideColorIfSet(&color)) { | |
207 this->first()->setColor(color); | |
208 } | |
345 fOverrides = overrides; | 209 fOverrides = overrides; |
346 } | 210 } |
347 | 211 |
348 private: | 212 private: |
349 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} | 213 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} |
350 | 214 |
351 void onPrepareDraws(Target* target) const override { | 215 void onPrepareDraws(Target* target) const override { |
352 sk_sp<GrGeometryProcessor> gp = | 216 bool needLocalCoords = fOverrides.readsLocalCoords(); |
353 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, | 217 using namespace GrDefaultGeoProcFactory; |
354 GrDefaultGeoProcFactory::LocalCoords::kHasEx plicit_Type); | 218 |
219 Color color(Color::kAttribute_Type); | |
220 Coverage::Type coverageType; | |
221 if (fOverrides.canTweakAlphaForCoverage()) { | |
222 coverageType = Coverage::kSolid_Type; | |
223 } else { | |
224 coverageType = Coverage::kAttribute_Type; | |
225 } | |
226 Coverage coverage(coverageType); | |
227 LocalCoords lc = needLocalCoords ? LocalCoords::kHasExplicit_Type | |
228 : LocalCoords::kUnused_Type; | |
229 sk_sp<GrGeometryProcessor> gp = GrDefaultGeoProcFactory::Make(color, cov erage, lc, | |
230 SkMatrix:: I()); | |
355 if (!gp) { | 231 if (!gp) { |
356 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 232 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
357 return; | 233 return; |
358 } | 234 } |
359 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? | |
360 gp->getVertexStride() == | |
361 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : | |
362 gp->getVertexStride() == | |
363 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage )); | |
364 | 235 |
365 size_t vertexStride = gp->getVertexStride(); | 236 size_t vertexStride = gp->getVertexStride(); |
366 | 237 |
367 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour ceProvider())); | 238 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour ceProvider())); |
368 InstancedHelper helper; | 239 InstancedHelper helper; |
369 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS tride, | 240 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS tride, |
370 indexBuffer, kVertsPerAAFillRect, | 241 indexBuffer, kVertsPerAAFillRect, |
371 kIndicesPerAAFillRect, fRects.count()); | 242 kIndicesPerAAFillRect, fRectCnt); |
372 if (!vertices || !indexBuffer) { | 243 if (!vertices || !indexBuffer) { |
373 SkDebugf("Could not allocate vertices\n"); | 244 SkDebugf("Could not allocate vertices\n"); |
374 return; | 245 return; |
375 } | 246 } |
376 | 247 |
377 for (int i = 0; i < fRects.count(); i++) { | 248 const RectInfo* info = this->first(); |
249 const SkMatrix* localMatrix = nullptr; | |
250 for (int i = 0; i < fRectCnt; i++) { | |
378 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | 251 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
379 i * kVertsPerAAFillRect * vertexStride; | 252 i * kVertsPerAAFillRect * vertexStride; |
380 generate_aa_fill_rect_geometry(verts, vertexStride, fRects[i].fColor , | 253 if (needLocalCoords) { |
381 fRects[i].fViewMatrix, fRects[i].fRec t, | 254 if (HasLocalMatrix::kYes == info->hasLocalMatrix()) { |
382 fRects[i].fDevRect, fOverrides, | 255 localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(i nfo)->localMatrix(); |
383 &fRects[i].fLocalMatrix); | 256 } else { |
257 localMatrix = &SkMatrix::I(); | |
258 } | |
259 } | |
260 generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), | |
261 info->viewMatrix(), info->rect(), | |
262 info->devRect(), fOverrides, localMat rix); | |
263 info = this->next(info); | |
384 } | 264 } |
385 helper.recordDraw(target, gp.get()); | 265 helper.recordDraw(target, gp.get()); |
386 } | 266 } |
387 | 267 |
388 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 268 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
389 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>() ; | 269 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>() ; |
390 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), | 270 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), |
391 that->bounds(), caps)) { | 271 that->bounds(), caps)) { |
392 return false; | 272 return false; |
393 } | 273 } |
394 | 274 |
395 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to | 275 // In the event of two batches, one who can tweak, one who cannot, we ju st fall back to |
396 // not tweaking | 276 // not tweaking |
397 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA lphaForCoverage()) { | 277 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA lphaForCoverage()) { |
398 fOverrides = that->fOverrides; | 278 fOverrides = that->fOverrides; |
399 } | 279 } |
400 | 280 |
401 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | 281 fRectData.append(that->fRectData.count(), that->fRectData.begin()); |
282 fRectCnt += that->fRectCnt; | |
402 this->joinBounds(that->bounds()); | 283 this->joinBounds(that->bounds()); |
403 return true; | 284 return true; |
404 } | 285 } |
405 | 286 |
287 enum class HasLocalMatrix : uint32_t { kNo, kYes }; | |
288 | |
406 struct RectInfo { | 289 struct RectInfo { |
290 public: | |
291 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, | |
292 const SkRect& devRect) | |
293 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {} | |
robertphillips
2016/07/01 16:04:59
Can this just return bool and hide the 'HasLocalMa
bsalomon
2016/07/01 16:15:14
Done.
| |
294 HasLocalMatrix hasLocalMatrix() const { return fHasLocalMatrix; } | |
295 GrColor color() const { return fColor; } | |
296 const SkMatrix& viewMatrix() const { return fViewMatrix; } | |
297 const SkRect& rect() const { return fRect; } | |
298 const SkRect& devRect() const { return fDevRect; } | |
299 | |
300 void setColor(GrColor color) { fColor = color; } | |
301 protected: | |
302 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, | |
303 const SkRect& devRect, HasLocalMatrix hasLM) | |
304 : fHasLocalMatrix(hasLM) | |
305 , fColor(color) | |
306 , fViewMatrix(viewMatrix) | |
307 , fRect(rect) | |
308 , fDevRect(devRect) {} | |
309 | |
robertphillips
2016/07/01 16:04:59
rm ' ' ?
bsalomon
2016/07/01 16:15:14
Done.
| |
310 HasLocalMatrix fHasLocalMatrix ; | |
407 GrColor fColor; | 311 GrColor fColor; |
408 SkMatrix fViewMatrix; | 312 SkMatrix fViewMatrix; |
409 SkMatrix fLocalMatrix; | |
410 SkRect fRect; | 313 SkRect fRect; |
411 SkRect fDevRect; | 314 SkRect fDevRect; |
412 }; | 315 }; |
413 | 316 |
317 struct RectWithLocalMatrixInfo : public RectInfo { | |
318 public: | |
319 RectWithLocalMatrixInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, | |
robertphillips
2016/07/01 16:04:59
add a ' ' ?
bsalomon
2016/07/01 16:15:14
Done.
| |
320 const SkRect& devRect, const SkMatrix& localMatri x) | |
321 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes) | |
322 , fLocalMatrix(localMatrix) {} | |
323 const SkMatrix& localMatrix() const { return fLocalMatrix; } | |
324 private: | |
325 SkMatrix fLocalMatrix; | |
326 }; | |
327 | |
328 RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); } | |
329 const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRe ctData.begin()); } | |
330 const RectInfo* next(const RectInfo* prev) const { | |
331 intptr_t next = reinterpret_cast<intptr_t>(prev) + | |
332 (HasLocalMatrix::kYes == prev->hasLocalMatrix() | |
333 ? sizeof(RectWithLocalMatrixInfo) | |
334 : sizeof(RectInfo)); | |
335 return reinterpret_cast<const RectInfo*>(next); | |
336 } | |
337 | |
414 GrXPOverridesForBatch fOverrides; | 338 GrXPOverridesForBatch fOverrides; |
415 SkSTArray<1, RectInfo, true> fRects; | 339 SkTDArray<uint8_t> fRectData; |
340 int fRectCnt; | |
416 | 341 |
417 typedef GrVertexBatch INHERITED; | 342 typedef GrVertexBatch INHERITED; |
418 }; | 343 }; |
419 | 344 |
420 namespace GrAAFillRectBatch { | 345 namespace GrAAFillRectBatch { |
421 | 346 |
422 GrDrawBatch* Create(GrColor color, | 347 GrDrawBatch* Create(GrColor color, |
423 const SkMatrix& viewMatrix, | 348 const SkMatrix& viewMatrix, |
424 const SkRect& rect, | 349 const SkRect& rect, |
425 const SkRect& devRect) { | 350 const SkRect& devRect) { |
426 return new AAFillRectNoLocalMatrixBatch(color, viewMatrix, rect, devRect); | 351 return new AAFillRectLocalMatrixBatch(color, viewMatrix, rect, devRect, null ptr); |
427 } | 352 } |
428 | 353 |
429 GrDrawBatch* Create(GrColor color, | 354 GrDrawBatch* Create(GrColor color, |
430 const SkMatrix& viewMatrix, | 355 const SkMatrix& viewMatrix, |
431 const SkMatrix& localMatrix, | 356 const SkMatrix& localMatrix, |
432 const SkRect& rect, | 357 const SkRect& rect, |
433 const SkRect& devRect) { | 358 const SkRect& devRect) { |
434 return new AAFillRectLocalMatrixBatch(color, viewMatrix, localMatrix, rect, devRect); | 359 return new AAFillRectLocalMatrixBatch(color, viewMatrix, rect, devRect, &loc alMatrix); |
435 } | 360 } |
436 | 361 |
437 GrDrawBatch* Create(GrColor color, | 362 GrDrawBatch* Create(GrColor color, |
438 const SkMatrix& viewMatrix, | 363 const SkMatrix& viewMatrix, |
439 const SkMatrix& localMatrix, | 364 const SkMatrix& localMatrix, |
440 const SkRect& rect) { | 365 const SkRect& rect) { |
441 SkRect devRect; | 366 SkRect devRect; |
442 viewMatrix.mapRect(&devRect, rect); | 367 viewMatrix.mapRect(&devRect, rect); |
443 return Create(color, viewMatrix, localMatrix, rect, devRect); | 368 return Create(color, viewMatrix, localMatrix, rect, devRect); |
444 } | 369 } |
(...skipping 30 matching lines...) Expand all Loading... | |
475 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { | 400 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { |
476 GrColor color = GrRandomColor(random); | 401 GrColor color = GrRandomColor(random); |
477 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 402 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
478 SkMatrix localMatrix = GrTest::TestMatrix(random); | 403 SkMatrix localMatrix = GrTest::TestMatrix(random); |
479 SkRect rect = GrTest::TestRect(random); | 404 SkRect rect = GrTest::TestRect(random); |
480 SkRect devRect = GrTest::TestRect(random); | 405 SkRect devRect = GrTest::TestRect(random); |
481 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe ct); | 406 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe ct); |
482 } | 407 } |
483 | 408 |
484 #endif | 409 #endif |
OLD | NEW |