| 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 |