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 "GrRectBatch.h" | 8 #include "GrRectBatch.h" |
9 | 9 |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
11 #include "GrBatchTarget.h" | 11 #include "GrBatchTarget.h" |
12 #include "GrBatchTest.h" | 12 #include "GrBatchTest.h" |
13 #include "GrDefaultGeoProcFactory.h" | 13 #include "GrDefaultGeoProcFactory.h" |
14 #include "GrPrimitiveProcessor.h" | 14 #include "GrPrimitiveProcessor.h" |
15 | 15 |
16 /** We always use per-vertex colors so that rects can be batched across color ch
anges. Sometimes we | |
17 have explicit local coords and sometimes not. We *could* always provide expl
icit local coords | |
18 and just duplicate the positions when the caller hasn't provided a local coo
rd rect, but we | |
19 haven't seen a use case which frequently switches between local rect and no
local rect draws. | |
20 | |
21 The color param is used to determine whether the opaque hint can be set on t
he draw state. | |
22 The caller must populate the vertex colors itself. | |
23 | |
24 The vertex attrib order is always pos, color, [local coords]. | |
25 */ | |
26 static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords, | |
27 const SkMatrix* localMatrix, | |
28 bool coverageIgnored) { | |
29 typedef GrDefaultGeoProcFactory::Color Color; | |
30 typedef GrDefaultGeoProcFactory::Coverage Coverage; | |
31 typedef GrDefaultGeoProcFactory::LocalCoords LocalCoords; | |
32 Color color(Color::kAttribute_Type); | |
33 Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_
Type); | |
34 LocalCoords::Type localCoords; | |
35 if (hasExplicitLocalCoords) { | |
36 localCoords = LocalCoords::kHasExplicit_Type; | |
37 } else { | |
38 localCoords = LocalCoords::kUsePosition_Type; | |
39 } | |
40 | |
41 if (localMatrix) { | |
42 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkM
atrix::I(), | |
43 *localMatrix); | |
44 } else { | |
45 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords); | |
46 } | |
47 } | |
48 | |
49 class RectBatch : public GrBatch { | 16 class RectBatch : public GrBatch { |
50 public: | 17 public: |
51 struct Geometry { | 18 struct Geometry { |
52 SkMatrix fViewMatrix; | 19 SkMatrix fViewMatrix; |
53 SkRect fRect; | 20 SkRect fRect; |
54 SkRect fLocalRect; | 21 SkRect fLocalRect; |
55 SkMatrix fLocalMatrix; | 22 SkMatrix fLocalMatrix; |
56 GrColor fColor; | 23 GrColor fColor; |
57 bool fHasLocalRect; | 24 bool fHasLocalRect; |
58 bool fHasLocalMatrix; | 25 bool fHasLocalMatrix; |
(...skipping 22 matching lines...) Expand all Loading... |
81 init.getOverrideColorIfSet(&fGeoData[0].fColor); | 48 init.getOverrideColorIfSet(&fGeoData[0].fColor); |
82 | 49 |
83 // setup batch properties | 50 // setup batch properties |
84 fBatch.fColorIgnored = !init.readsColor(); | 51 fBatch.fColorIgnored = !init.readsColor(); |
85 fBatch.fColor = fGeoData[0].fColor; | 52 fBatch.fColor = fGeoData[0].fColor; |
86 fBatch.fUsesLocalCoords = init.readsLocalCoords(); | 53 fBatch.fUsesLocalCoords = init.readsLocalCoords(); |
87 fBatch.fCoverageIgnored = !init.readsCoverage(); | 54 fBatch.fCoverageIgnored = !init.readsCoverage(); |
88 } | 55 } |
89 | 56 |
90 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { | 57 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { |
91 // Go to device coords to allow batching across matrix changes | 58 SkAutoTUnref<const GrGeometryProcessor> gp(this->createRectGP()); |
92 SkMatrix invert = SkMatrix::I(); | 59 if (!gp) { |
93 | 60 SkDebugf("Could not create GrGeometryProcessor\n"); |
94 // if we have a local rect, then we apply the localMatrix directly to th
e localRect to | 61 return; |
95 // generate vertex local coords | |
96 bool hasExplicitLocalCoords = this->hasLocalRect(); | |
97 if (!hasExplicitLocalCoords) { | |
98 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&
invert)) { | |
99 SkDebugf("Could not invert\n"); | |
100 return; | |
101 } | |
102 | |
103 if (this->hasLocalMatrix()) { | |
104 invert.preConcat(this->localMatrix()); | |
105 } | |
106 } | 62 } |
107 | 63 |
108 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLoc
alCoords, | |
109 &invert, | |
110 this->coverage
Ignored())); | |
111 | |
112 batchTarget->initDraw(gp, pipeline); | 64 batchTarget->initDraw(gp, pipeline); |
113 | 65 |
114 int instanceCount = fGeoData.count(); | 66 int instanceCount = fGeoData.count(); |
115 size_t vertexStride = gp->getVertexStride(); | 67 size_t vertexStride = gp->getVertexStride(); |
116 SkASSERT(hasExplicitLocalCoords ? | 68 SkASSERT(this->hasLocalRect() ? |
117 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo
calCoordAttr) : | 69 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo
calCoordAttr) : |
118 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr)); | 70 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr)); |
119 QuadHelper helper; | 71 QuadHelper helper; |
120 void* vertices = helper.init(batchTarget, vertexStride, instanceCount); | 72 void* vertices = helper.init(batchTarget, vertexStride, instanceCount); |
121 | 73 |
122 if (!vertices) { | 74 if (!vertices) { |
123 return; | 75 return; |
124 } | 76 } |
125 | 77 |
126 for (int i = 0; i < instanceCount; i++) { | 78 for (int i = 0; i < instanceCount; i++) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 } | 156 } |
205 | 157 |
206 if (this->color() != that->color()) { | 158 if (this->color() != that->color()) { |
207 fBatch.fColor = GrColor_ILLEGAL; | 159 fBatch.fColor = GrColor_ILLEGAL; |
208 } | 160 } |
209 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 161 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
210 this->joinBounds(that->bounds()); | 162 this->joinBounds(that->bounds()); |
211 return true; | 163 return true; |
212 } | 164 } |
213 | 165 |
| 166 /** We always use per-vertex colors so that rects can be batched across colo
r changes. Sometimes |
| 167 we have explicit local coords and sometimes not. We *could* always prov
ide explicit local |
| 168 coords and just duplicate the positions when the caller hasn't provided
a local coord rect, |
| 169 but we haven't seen a use case which frequently switches between local r
ect and no local |
| 170 rect draws. |
| 171 |
| 172 The color param is used to determine whether the opaque hint can be set
on the draw state. |
| 173 The caller must populate the vertex colors itself. |
| 174 |
| 175 The vertex attrib order is always pos, color, [local coords]. |
| 176 */ |
| 177 const GrGeometryProcessor* createRectGP() { |
| 178 typedef GrDefaultGeoProcFactory::Color Color; |
| 179 typedef GrDefaultGeoProcFactory::Coverage Coverage; |
| 180 typedef GrDefaultGeoProcFactory::LocalCoords LocalCoords; |
| 181 Color color(Color::kAttribute_Type); |
| 182 Coverage coverage(this->coverageIgnored() ? Coverage::kNone_Type : Cover
age::kSolid_Type); |
| 183 |
| 184 // if we have a local rect, then we apply the localMatrix directly to th
e localRect to |
| 185 // generate vertex local coords |
| 186 if (this->hasLocalRect()) { |
| 187 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); |
| 188 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords)
; |
| 189 } else { |
| 190 LocalCoords localCoords(LocalCoords::kUsePosition_Type, |
| 191 this->hasLocalMatrix() ? &this->localMatrix(
) : NULL); |
| 192 return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage
, localCoords, |
| 193 this->viewMatri
x()); |
| 194 } |
| 195 } |
| 196 |
| 197 |
214 struct BatchTracker { | 198 struct BatchTracker { |
215 GrColor fColor; | 199 GrColor fColor; |
216 bool fUsesLocalCoords; | 200 bool fUsesLocalCoords; |
217 bool fColorIgnored; | 201 bool fColorIgnored; |
218 bool fCoverageIgnored; | 202 bool fCoverageIgnored; |
219 }; | 203 }; |
220 | 204 |
221 BatchTracker fBatch; | 205 BatchTracker fBatch; |
222 SkSTArray<1, Geometry, true> fGeoData; | 206 SkSTArray<1, Geometry, true> fGeoData; |
223 }; | 207 }; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 if (hasLocalMatrix) { | 261 if (hasLocalMatrix) { |
278 localMatrix = GrTest::TestMatrix(random); | 262 localMatrix = GrTest::TestMatrix(random); |
279 } | 263 } |
280 | 264 |
281 return GrRectBatch::Create(color, viewMatrix, rect, | 265 return GrRectBatch::Create(color, viewMatrix, rect, |
282 hasLocalRect ? &localRect : NULL, | 266 hasLocalRect ? &localRect : NULL, |
283 hasLocalMatrix ? &localMatrix : NULL); | 267 hasLocalMatrix ? &localMatrix : NULL); |
284 } | 268 } |
285 | 269 |
286 #endif | 270 #endif |
OLD | NEW |