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