Chromium Code Reviews| 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 "GrBWFillRectBatch.h" | 8 #include "GrBWFillRectBatch.h" |
| 9 | 9 |
| 10 #include "GrBatchTarget.h" | 10 #include "GrBatchTarget.h" |
| 11 #include "GrColor.h" | 11 #include "GrColor.h" |
| 12 #include "GrDefaultGeoProcFactory.h" | 12 #include "GrDefaultGeoProcFactory.h" |
| 13 #include "GrPrimitiveProcessor.h" | 13 #include "GrPrimitiveProcessor.h" |
| 14 #include "GrVertexBatch.h" | 14 #include "GrVertexBatch.h" |
| 15 | 15 |
| 16 class GrBatchTarget; | 16 class GrBatchTarget; |
| 17 class SkMatrix; | 17 class SkMatrix; |
| 18 struct SkRect; | 18 struct SkRect; |
| 19 | 19 |
| 20 /* | |
| 21 * BWFillRectBatch is templated to optionally allow the insertion of an addition al | |
| 22 * attribute for explicit local coordinates and also to handle an optional local Matrix | |
| 23 * To use this template, an implementation must define the following static func tions: | |
| 24 * A Geometry struct | |
| 25 * | |
| 26 * bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatrix& theirs, | |
| 27 * bool usesLocalCoords) | |
| 28 * | |
| 29 * GrDefaultGeoProcFactory::LocalCoords::Type LocalCoordsType() | |
| 30 * | |
| 31 * bool StrideCheck(size_t vertexStride, bool canTweakAlphaForCoverage, | |
| 32 * bool usesLocalCoords) | |
| 33 * | |
| 34 * void FillInAttributes(intptr_t startVertex, size_t vertexStride, | |
| 35 * SkPoint* fan0Position, const Geometry&) | |
| 36 * | |
| 37 * const GrGeometryProcessor* CreateGP(const Geometry& geo, | |
| 38 * const GrDefaultGeoProcFactory::Color& color, | |
| 39 * const GrDefaultGeoProcFactory::Covera ge& coverage) | |
| 40 */ | |
| 41 template <typename Base> | |
|
bsalomon
2015/08/14 14:37:48
I don't Base is a good a name for the template par
| |
| 20 class BWFillRectBatch : public GrVertexBatch { | 42 class BWFillRectBatch : public GrVertexBatch { |
| 21 public: | 43 public: |
| 22 struct Geometry { | 44 typedef typename Base::Geometry Geometry; |
| 23 SkMatrix fViewMatrix; | |
| 24 SkRect fRect; | |
| 25 SkRect fLocalRect; | |
| 26 SkMatrix fLocalMatrix; | |
| 27 GrColor fColor; | |
| 28 bool fHasLocalRect; | |
| 29 bool fHasLocalMatrix; | |
| 30 }; | |
| 31 | 45 |
| 32 static GrDrawBatch* Create(const Geometry& geometry) { | 46 static BWFillRectBatch* Create() { |
| 33 return SkNEW_ARGS(BWFillRectBatch, (geometry)); | 47 return SkNEW(BWFillRectBatch); |
| 34 } | 48 } |
| 35 | 49 |
| 36 const char* name() const override { return "RectBatch"; } | 50 const char* name() const override { return "RectBatch"; } |
| 37 | 51 |
| 38 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 52 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 39 // When this is called on a batch, there is only one geometry bundle | 53 // When this is called on a batch, there is only one geometry bundle |
| 40 out->setKnownFourComponents(fGeoData[0].fColor); | 54 out->setKnownFourComponents(fGeoData[0].fColor); |
| 41 } | 55 } |
| 42 | 56 |
| 43 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 57 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
| 44 out->setKnownSingleComponent(0xff); | 58 out->setKnownSingleComponent(0xff); |
| 45 } | 59 } |
| 46 | 60 |
| 47 void initBatchTracker(const GrPipelineOptimizations& init) override { | 61 void initBatchTracker(const GrPipelineOptimizations& init) override { |
| 48 // Handle any color overrides | 62 // Handle any color overrides |
| 49 if (!init.readsColor()) { | 63 if (!init.readsColor()) { |
| 50 fGeoData[0].fColor = GrColor_ILLEGAL; | 64 fGeoData[0].fColor = GrColor_ILLEGAL; |
| 51 } | 65 } |
| 52 init.getOverrideColorIfSet(&fGeoData[0].fColor); | 66 init.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 53 | 67 |
| 54 // setup batch properties | 68 // setup batch properties |
| 55 fBatch.fColorIgnored = !init.readsColor(); | 69 fBatch.fColorIgnored = !init.readsColor(); |
| 56 fBatch.fColor = fGeoData[0].fColor; | 70 fBatch.fColor = fGeoData[0].fColor; |
| 57 fBatch.fUsesLocalCoords = init.readsLocalCoords(); | 71 fBatch.fUsesLocalCoords = init.readsLocalCoords(); |
| 58 fBatch.fCoverageIgnored = !init.readsCoverage(); | 72 fBatch.fCoverageIgnored = !init.readsCoverage(); |
| 59 } | 73 } |
| 60 | 74 |
| 61 void generateGeometry(GrBatchTarget* batchTarget) override { | 75 void generateGeometry(GrBatchTarget* batchTarget) override { |
| 62 SkAutoTUnref<const GrGeometryProcessor> gp(this->createRectGP()); | 76 SkAutoTUnref<const GrGeometryProcessor> gp(this->createGP(fGeoData[0])); |
| 63 if (!gp) { | 77 if (!gp) { |
| 64 SkDebugf("Could not create GrGeometryProcessor\n"); | 78 SkDebugf("Could not create GrGeometryProcessor\n"); |
| 65 return; | 79 return; |
| 66 } | 80 } |
| 67 | 81 |
| 68 batchTarget->initDraw(gp, this->pipeline()); | 82 batchTarget->initDraw(gp, this->pipeline()); |
| 69 | 83 |
| 70 int instanceCount = fGeoData.count(); | 84 int instanceCount = fGeoData.count(); |
| 71 size_t vertexStride = gp->getVertexStride(); | 85 size_t vertexStride = gp->getVertexStride(); |
| 72 SkASSERT(this->hasLocalRect() ? | 86 SkASSERT(Base::StrideCheck(vertexStride)); |
| 73 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo calCoordAttr) : | |
| 74 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt tr)); | |
| 75 QuadHelper helper; | 87 QuadHelper helper; |
| 76 void* vertices = helper.init(batchTarget, vertexStride, instanceCount); | 88 void* vertices = helper.init(batchTarget, vertexStride, instanceCount); |
| 77 | 89 |
| 78 if (!vertices) { | 90 if (!vertices) { |
| 79 return; | 91 return; |
| 80 } | 92 } |
| 81 | 93 |
| 82 for (int i = 0; i < instanceCount; i++) { | 94 for (int i = 0; i < instanceCount; i++) { |
| 83 const Geometry& geom = fGeoData[i]; | 95 const Geometry& geom = fGeoData[i]; |
| 84 | 96 |
| 85 intptr_t offset = reinterpret_cast<intptr_t>(vertices) + | 97 intptr_t offset = reinterpret_cast<intptr_t>(vertices) + |
| 86 kVerticesPerQuad * i * vertexStride; | 98 kVerticesPerQuad * i * vertexStride; |
| 87 SkPoint* positions = reinterpret_cast<SkPoint*>(offset); | 99 SkPoint* positions = reinterpret_cast<SkPoint*>(offset); |
| 88 | 100 |
| 89 positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop, | 101 positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop, |
| 90 geom.fRect.fRight, geom.fRect.fBottom, vertexS tride); | 102 geom.fRect.fRight, geom.fRect.fBottom, vertexS tride); |
|
robertphillips
2015/08/14 14:42:57
space before '(' ?
| |
| 103 // TODO we are mapping the rect twice(three times in the GrDrawConte xt::drawRect case) | |
| 91 geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerti cesPerQuad); | 104 geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerti cesPerQuad); |
| 92 | 105 |
| 93 // TODO we should only do this if local coords are being read | 106 Base::FillInAttributes(offset, vertexStride, geom); |
| 94 if (geom.fHasLocalRect) { | |
| 95 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor ); | |
| 96 SkPoint* coords = reinterpret_cast<SkPoint*>(offset + kLocalOffs et); | |
| 97 coords->setRectFan(geom.fLocalRect.fLeft, geom.fLocalRect.fTop, | |
| 98 geom.fLocalRect.fRight, geom.fLocalRect.fBott om, | |
| 99 vertexStride); | |
| 100 if (geom.fHasLocalMatrix) { | |
| 101 geom.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPerQuad); | |
| 102 } | |
| 103 } | |
| 104 | 107 |
| 105 static const int kColorOffset = sizeof(SkPoint); | 108 static const int kColorOffset = sizeof(SkPoint); |
| 106 GrColor* vertColor = reinterpret_cast<GrColor*>(offset + kColorOffse t); | 109 GrColor* vertColor = reinterpret_cast<GrColor*>(offset + kColorOffse t); |
| 107 for (int j = 0; j < 4; ++j) { | 110 for (int j = 0; j < 4; ++j) { |
| 108 *vertColor = geom.fColor; | 111 *vertColor = geom.fColor; |
| 109 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); | 112 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); |
| 110 } | 113 } |
| 111 } | 114 } |
| 112 | 115 |
| 113 helper.issueDraw(batchTarget); | 116 helper.issueDraw(batchTarget); |
| 114 } | 117 } |
| 115 | 118 |
| 116 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 119 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 117 | 120 |
| 121 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which | |
| 122 // is used to seed the batch with its initial geometry. After seeding, the client should call | |
| 123 // init() so the Batch can initialize itself | |
| 124 Geometry* geometry() { return &fGeoData[0]; } | |
| 125 void init() { | |
| 126 const Geometry& geo = fGeoData[0]; | |
| 127 geo.fViewMatrix.mapRect(&fBounds, geo.fRect); | |
| 128 } | |
| 129 | |
| 118 private: | 130 private: |
| 119 BWFillRectBatch(const Geometry& geometry) { | 131 BWFillRectBatch() { |
| 120 this->initClassID<BWFillRectBatch>(); | 132 this->initClassID<BWFillRectBatch<Base>>(); |
| 121 fGeoData.push_back(geometry); | 133 fGeoData.push_back(); |
| 122 | |
| 123 fBounds = geometry.fRect; | |
| 124 geometry.fViewMatrix.mapRect(&fBounds); | |
| 125 } | 134 } |
| 126 | 135 |
| 127 GrColor color() const { return fBatch.fColor; } | 136 GrColor color() const { return fBatch.fColor; } |
| 128 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 137 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| 129 bool colorIgnored() const { return fBatch.fColorIgnored; } | 138 bool colorIgnored() const { return fBatch.fColorIgnored; } |
| 130 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 139 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| 131 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; } | |
| 132 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; } | |
| 133 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; } | |
| 134 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } | 140 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } |
| 135 | 141 |
| 136 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 142 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 137 BWFillRectBatch* that = t->cast<BWFillRectBatch>(); | 143 BWFillRectBatch* that = t->cast<BWFillRectBatch>(); |
| 138 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), | 144 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), |
| 139 that->bounds(), caps)) { | 145 that->bounds(), caps)) { |
| 140 return false; | 146 return false; |
| 141 } | 147 } |
| 142 | 148 |
| 143 if (this->hasLocalRect() != that->hasLocalRect()) { | 149 if (!Base::CanCombineLocalCoords(this->viewMatrix(), that->viewMatrix(), |
| 150 this->usesLocalCoords())) { | |
| 144 return false; | 151 return false; |
| 145 } | 152 } |
| 146 | 153 |
| 147 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | |
| 148 if (!this->hasLocalRect() && this->usesLocalCoords()) { | |
| 149 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { | |
| 150 return false; | |
| 151 } | |
| 152 | |
| 153 if (this->hasLocalMatrix() != that->hasLocalMatrix()) { | |
| 154 return false; | |
| 155 } | |
| 156 | |
| 157 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that ->localMatrix())) { | |
| 158 return false; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 if (this->color() != that->color()) { | 154 if (this->color() != that->color()) { |
| 163 fBatch.fColor = GrColor_ILLEGAL; | 155 fBatch.fColor = GrColor_ILLEGAL; |
| 164 } | 156 } |
| 165 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; | 157 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; |
| 166 this->joinBounds(that->bounds()); | 158 this->joinBounds(that->bounds()); |
| 167 return true; | 159 return true; |
| 168 } | 160 } |
| 169 | 161 |
| 170 | 162 |
| 171 /** We always use per-vertex colors so that rects can be batched across colo r changes. Sometimes | 163 /** We always use per-vertex colors so that rects can be batched across colo r changes. Sometimes |
| 172 we have explicit local coords and sometimes not. We *could* always prov ide explicit local | 164 we have explicit local coords and sometimes not. We *could* always prov ide explicit local |
| 173 coords and just duplicate the positions when the caller hasn't provided a local coord rect, | 165 coords and just duplicate the positions when the caller hasn't provided a local coord rect, |
| 174 but we haven't seen a use case which frequently switches between local r ect and no local | 166 but we haven't seen a use case which frequently switches between local r ect and no local |
| 175 rect draws. | 167 rect draws. |
| 176 | 168 |
| 177 The color param is used to determine whether the opaque hint can be set on the draw state. | 169 The color param is used to determine whether the opaque hint can be set on the draw state. |
| 178 The caller must populate the vertex colors itself. | 170 The caller must populate the vertex colors itself. |
| 179 | 171 |
| 180 The vertex attrib order is always pos, color, [local coords]. | 172 The vertex attrib order is always pos, color, [local coords]. |
| 181 */ | 173 */ |
| 182 const GrGeometryProcessor* createRectGP() const { | 174 const GrGeometryProcessor* createGP(const Geometry& geo) const { |
| 183 using namespace GrDefaultGeoProcFactory; | 175 using namespace GrDefaultGeoProcFactory; |
| 184 Color color(Color::kAttribute_Type); | 176 Color color(Color::kAttribute_Type); |
| 185 Coverage coverage(this->coverageIgnored() ? Coverage::kNone_Type : Cover age::kSolid_Type); | 177 Coverage coverage(this->coverageIgnored() ? Coverage::kNone_Type : Cover age::kSolid_Type); |
| 186 | 178 |
| 187 // if we have a local rect, then we apply the localMatrix directly to th e localRect to | 179 return Base::CreateGP(geo, color, coverage); |
| 188 // generate vertex local coords | |
| 189 if (this->hasLocalRect()) { | |
| 190 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); | |
| 191 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I()); | |
| 192 } else { | |
| 193 LocalCoords localCoords(LocalCoords::kUsePosition_Type, | |
| 194 this->hasLocalMatrix() ? &this->localMatrix( ) : NULL); | |
| 195 return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage , localCoords, | |
| 196 this->viewMatri x()); | |
| 197 } | |
| 198 } | 180 } |
| 199 | 181 |
| 200 struct BatchTracker { | 182 struct BatchTracker { |
| 201 GrColor fColor; | 183 GrColor fColor; |
| 202 bool fUsesLocalCoords; | 184 bool fUsesLocalCoords; |
| 203 bool fColorIgnored; | 185 bool fColorIgnored; |
| 204 bool fCoverageIgnored; | 186 bool fCoverageIgnored; |
| 205 }; | 187 }; |
| 206 | 188 |
| 207 BatchTracker fBatch; | 189 BatchTracker fBatch; |
| 208 SkSTArray<1, Geometry, true> fGeoData; | 190 SkSTArray<1, Geometry, true> fGeoData; |
| 209 }; | 191 }; |
| 210 | 192 |
| 193 /* | |
| 194 * Right now we have 4 variants of BWFillRect. BWFillRect with no local matrix or local rect, | |
|
bsalomon
2015/08/14 14:37:48
Maybe write this as bullets? Kind of hard to follo
| |
| 195 * BWFillRect who has a uniform localMatrix, BWFillRect who has a localRect, and a BWFillRect who | |
| 196 * applies its localMatrix to its localRect | |
|
robertphillips
2015/08/14 14:42:57
// These classes are created by having two levels
| |
| 197 */ | |
| 198 template <class Base> | |
| 199 class GrBWFillRectBatchNoLocalRectImp : public Base { | |
| 200 public: | |
| 201 typedef typename Base::Geometry Geometry; | |
| 202 | |
| 203 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs, | |
| 204 bool usesLocalCoords) { | |
| 205 // We apply the viewmatrix to the rect points on the cpu. However, if t he pipeline uses | |
| 206 // local coords then we won't be able to batch. We could actually uploa d the viewmatrix | |
| 207 // using vertex attributes in these cases, but haven't investigated that | |
| 208 return !usesLocalCoords || mine.cheapEqualTo(theirs); | |
| 209 } | |
| 210 | |
| 211 inline static bool StrideCheck(size_t vertexStride) { | |
| 212 return vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr ); | |
| 213 } | |
| 214 | |
| 215 inline static void FillInAttributes(intptr_t vertices, size_t vertexStride, | |
|
robertphillips
2015/08/14 14:42:57
We don't have to invoke "Base::OnFillInAttributes(
| |
| 216 const Geometry& args) {} | |
| 217 }; | |
| 218 | |
| 219 template <class Base> | |
| 220 class GrBWFillRectBatchLocalRectImp { | |
| 221 public: | |
| 222 typedef typename Base::Geometry Geometry; | |
| 223 | |
| 224 inline static bool CanCombineLocalCoords(const SkMatrix& mine, const SkMatri x& theirs, | |
| 225 bool usesLocalCoords) { | |
|
robertphillips
2015/08/14 14:42:57
// We can always combine b.c. ...
?
| |
| 226 return true; | |
| 227 } | |
| 228 | |
| 229 inline static const GrGeometryProcessor* CreateGP( | |
| 230 const Geometry& geo, | |
| 231 const GrDefaultGeoProcFactory::C olor& color, | |
| 232 const GrDefaultGeoProcFactory::C overage& coverage) { | |
| 233 using namespace GrDefaultGeoProcFactory; | |
| 234 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); | |
| 235 return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkM atrix::I()); | |
| 236 } | |
| 237 | |
| 238 inline static bool StrideCheck(size_t vertexStride) { | |
| 239 return vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLoca lCoordAttr); | |
| 240 } | |
| 241 | |
| 242 inline static void FillInAttributes(intptr_t vertices, size_t vertexStride, | |
| 243 const Geometry& args) { | |
| 244 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); | |
| 245 SkPoint* coords = reinterpret_cast<SkPoint*>(vertices + kLocalOffset); | |
| 246 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop, | |
| 247 args.fLocalRect.fRight, args.fLocalRect.fBottom, | |
| 248 vertexStride); | |
| 249 Base::OnFillInAttributes(coords, vertexStride, args); | |
| 250 } | |
| 251 }; | |
| 252 | |
| 253 class BWFillRectBatchSimpleImp { | |
| 254 public: | |
| 255 struct Geometry { | |
| 256 SkMatrix fViewMatrix; | |
| 257 SkRect fRect; | |
| 258 GrColor fColor; | |
| 259 }; | |
| 260 | |
| 261 inline static const GrGeometryProcessor* CreateGP( | |
| 262 const Geometry& geo, | |
| 263 const GrDefaultGeoProcFactory::C olor& color, | |
| 264 const GrDefaultGeoProcFactory::C overage& coverage) { | |
| 265 using namespace GrDefaultGeoProcFactory; | |
| 266 LocalCoords localCoords(LocalCoords::kUsePosition_Type); | |
| 267 return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage, lo calCoords, | |
| 268 geo.fViewMatrix); | |
| 269 } | |
| 270 }; | |
| 271 | |
| 272 class BWFillRectBatchLocalMatrixImp { | |
| 273 public: | |
| 274 struct Geometry { | |
| 275 SkMatrix fViewMatrix; | |
| 276 SkMatrix fLocalMatrix; | |
| 277 SkRect fRect; | |
| 278 GrColor fColor; | |
| 279 }; | |
| 280 | |
| 281 inline static const GrGeometryProcessor* CreateGP( | |
| 282 const Geometry& geo, | |
| 283 const GrDefaultGeoProcFactory::C olor& color, | |
| 284 const GrDefaultGeoProcFactory::C overage& coverage) { | |
| 285 using namespace GrDefaultGeoProcFactory; | |
| 286 LocalCoords localCoords(LocalCoords::kUsePosition_Type, &geo.fLocalMatri x); | |
| 287 return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage, lo calCoords, | |
| 288 geo.fViewMatrix); | |
| 289 } | |
| 290 }; | |
| 291 | |
| 292 class BWFillRectBatchLocalRectImp { | |
| 293 public: | |
| 294 struct Geometry { | |
| 295 SkMatrix fViewMatrix; | |
| 296 SkRect fRect; | |
| 297 SkRect fLocalRect; | |
| 298 GrColor fColor; | |
| 299 }; | |
| 300 inline static void OnFillInAttributes(SkPoint* coords, size_t vertexStride, | |
|
robertphillips
2015/08/14 14:42:57
call base class ?
| |
| 301 const Geometry& args) {} | |
| 302 }; | |
| 303 | |
| 304 class BWFillRectBatchLocalMatrixLocalRectImp { | |
| 305 public: | |
| 306 struct Geometry { | |
| 307 SkMatrix fViewMatrix; | |
| 308 SkMatrix fLocalMatrix; | |
| 309 SkRect fRect; | |
| 310 SkRect fLocalRect; | |
| 311 GrColor fColor; | |
| 312 }; | |
| 313 inline static void OnFillInAttributes(SkPoint* coords, size_t vertexStride, | |
| 314 const Geometry& args) { | |
| 315 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPer Quad); | |
| 316 } | |
| 317 static const int kVerticesPerQuad = 4; | |
| 318 }; | |
| 319 | |
| 320 | |
| 321 typedef BWFillRectBatch<GrBWFillRectBatchNoLocalRectImp<BWFillRectBatchSimpleImp >> BWFillRectBatchSimple; | |
| 322 typedef BWFillRectBatch<GrBWFillRectBatchNoLocalRectImp<BWFillRectBatchLocalMatr ixImp>> BWFillRectBatchLocalMatrix; | |
| 323 typedef BWFillRectBatch<GrBWFillRectBatchLocalRectImp<BWFillRectBatchLocalRectIm p>> BWFillRectBatchLocalRect; | |
| 324 typedef BWFillRectBatch<GrBWFillRectBatchLocalRectImp<BWFillRectBatchLocalMatrix LocalRectImp>> BWFillRectBatchLocalMatrixLocalRect; | |
| 325 | |
| 211 namespace GrBWFillRectBatch { | 326 namespace GrBWFillRectBatch { |
| 212 GrDrawBatch* Create(GrColor color, | 327 GrDrawBatch* Create(GrColor color, |
| 213 const SkMatrix& viewMatrix, | 328 const SkMatrix& viewMatrix, |
| 214 const SkRect& rect, | 329 const SkRect& rect, |
| 215 const SkRect* localRect, | 330 const SkRect* localRect, |
| 216 const SkMatrix* localMatrix) { | 331 const SkMatrix* localMatrix) { |
| 217 BWFillRectBatch::Geometry geometry; | 332 // TODO bubble these up as separate calls |
| 218 geometry.fColor = color; | 333 if (localRect && localMatrix) { |
| 219 geometry.fViewMatrix = viewMatrix; | 334 BWFillRectBatchLocalMatrixLocalRect* batch = BWFillRectBatchLocalMatrixL ocalRect::Create(); |
| 220 geometry.fRect = rect; | 335 BWFillRectBatchLocalMatrixLocalRect::Geometry& geo = *batch->geometry(); |
| 221 | 336 geo.fColor = color; |
| 222 if (localRect) { | 337 geo.fViewMatrix = viewMatrix; |
| 223 geometry.fHasLocalRect = true; | 338 geo.fLocalMatrix = *localMatrix; |
| 224 geometry.fLocalRect = *localRect; | 339 geo.fRect = rect; |
| 340 geo.fLocalRect = *localRect; | |
| 341 batch->init(); | |
| 342 return batch; | |
| 343 } else if (localRect) { | |
| 344 BWFillRectBatchLocalRect* batch = BWFillRectBatchLocalRect::Create(); | |
| 345 BWFillRectBatchLocalRect::Geometry& geo = *batch->geometry(); | |
| 346 geo.fColor = color; | |
| 347 geo.fViewMatrix = viewMatrix; | |
| 348 geo.fRect = rect; | |
| 349 geo.fLocalRect = *localRect; | |
| 350 batch->init(); | |
| 351 return batch; | |
| 352 } else if (localMatrix) { | |
| 353 BWFillRectBatchLocalMatrix* batch = BWFillRectBatchLocalMatrix::Create() ; | |
| 354 BWFillRectBatchLocalMatrix::Geometry& geo = *batch->geometry(); | |
| 355 geo.fColor = color; | |
| 356 geo.fViewMatrix = viewMatrix; | |
| 357 geo.fLocalMatrix = *localMatrix; | |
| 358 geo.fRect = rect; | |
| 359 batch->init(); | |
| 360 return batch; | |
| 225 } else { | 361 } else { |
| 226 geometry.fHasLocalRect = false; | 362 BWFillRectBatchSimple* batch = BWFillRectBatchSimple::Create(); |
| 363 BWFillRectBatchSimple::Geometry& geo = *batch->geometry(); | |
| 364 geo.fColor = color; | |
| 365 geo.fViewMatrix = viewMatrix; | |
| 366 geo.fRect = rect; | |
| 367 batch->init(); | |
| 368 return batch; | |
| 227 } | 369 } |
| 228 | |
| 229 if (localMatrix) { | |
| 230 geometry.fHasLocalMatrix = true; | |
| 231 geometry.fLocalMatrix = *localMatrix; | |
| 232 } else { | |
| 233 geometry.fHasLocalMatrix = false; | |
| 234 } | |
| 235 | |
| 236 return BWFillRectBatch::Create(geometry); | |
| 237 } | 370 } |
| 238 }; | 371 }; |
| 239 | 372 |
| 240 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 373 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 241 | 374 |
| 242 #ifdef GR_TEST_UTILS | 375 #ifdef GR_TEST_UTILS |
| 243 | 376 |
| 244 #include "GrBatchTest.h" | 377 #include "GrBatchTest.h" |
| 245 | 378 |
| 246 DRAW_BATCH_TEST_DEFINE(RectBatch) { | 379 DRAW_BATCH_TEST_DEFINE(RectBatch) { |
| 247 BWFillRectBatch::Geometry geometry; | 380 GrColor color = GrRandomColor(random); |
| 248 geometry.fColor = GrRandomColor(random); | 381 SkRect rect = GrTest::TestRect(random); |
| 382 SkRect localRect = GrTest::TestRect(random); | |
| 383 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | |
| 384 SkMatrix localMatrix = GrTest::TestMatrix(random); | |
| 249 | 385 |
| 250 geometry.fRect = GrTest::TestRect(random); | 386 bool hasLocalRect = random->nextBool(); |
| 251 geometry.fHasLocalRect = random->nextBool(); | 387 bool hasLocalMatrix = random->nextBool(); |
| 252 | 388 return GrBWFillRectBatch::Create(color, viewMatrix, rect, hasLocalRect ? &lo calRect : nullptr, |
| 253 if (geometry.fHasLocalRect) { | 389 hasLocalMatrix ? &localMatrix : nullptr); |
| 254 geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); | |
| 255 geometry.fLocalRect = GrTest::TestRect(random); | |
| 256 } else { | |
| 257 geometry.fViewMatrix = GrTest::TestMatrix(random); | |
| 258 } | |
| 259 | |
| 260 geometry.fHasLocalMatrix = random->nextBool(); | |
| 261 if (geometry.fHasLocalMatrix) { | |
| 262 geometry.fLocalMatrix = GrTest::TestMatrix(random); | |
| 263 } | |
| 264 | |
| 265 return BWFillRectBatch::Create(geometry); | |
| 266 } | 390 } |
| 267 | 391 |
| 268 #endif | 392 #endif |
| OLD | NEW |