| 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 "GrNonAAFillRectBatch.h" | 8 #include "GrNonAAFillRectBatch.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 "GrPrimitiveProcessor.h" | 13 #include "GrPrimitiveProcessor.h" |
| 14 #include "GrResourceProvider.h" | 14 #include "GrResourceProvider.h" |
| 15 #include "GrTInstanceBatch.h" | |
| 16 #include "GrQuad.h" | 15 #include "GrQuad.h" |
| 17 #include "GrVertexBatch.h" | 16 #include "GrVertexBatch.h" |
| 18 | 17 |
| 19 // Common functions | 18 static const int kVertsPerInstance = 4; |
| 20 class NonAAFillRectBatchBase { | 19 static const int kIndicesPerInstance = 6; |
| 21 public: | |
| 22 static const int kVertsPerInstance = 4; | |
| 23 static const int kIndicesPerInstance = 6; | |
| 24 | |
| 25 static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { | |
| 26 out->setKnownSingleComponent(0xff); | |
| 27 } | |
| 28 | |
| 29 static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { | |
| 30 return rp->refQuadIndexBuffer(); | |
| 31 } | |
| 32 | |
| 33 template <typename Geometry> | |
| 34 static void SetBounds(const Geometry& geo, SkRect* outBounds) { | |
| 35 geo.fViewMatrix.mapRect(outBounds, geo.fRect); | |
| 36 } | |
| 37 | |
| 38 template <typename Geometry> | |
| 39 static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds)
{ | |
| 40 SkRect bounds = geo.fRect; | |
| 41 geo.fViewMatrix.mapRect(&bounds); | |
| 42 outBounds->join(bounds); | |
| 43 } | |
| 44 }; | |
| 45 | 20 |
| 46 /** We always use per-vertex colors so that rects can be batched across color ch
anges. Sometimes | 21 /** We always use per-vertex colors so that rects can be batched across color ch
anges. Sometimes |
| 47 we have explicit local coords and sometimes not. We *could* always provide
explicit local | 22 we have explicit local coords and sometimes not. We *could* always provide
explicit local |
| 48 coords and just duplicate the positions when the caller hasn't provided a lo
cal coord rect, | 23 coords and just duplicate the positions when the caller hasn't provided a lo
cal coord rect, |
| 49 but we haven't seen a use case which frequently switches between local rect
and no local | 24 but we haven't seen a use case which frequently switches between local rect
and no local |
| 50 rect draws. | 25 rect draws. |
| 51 | 26 |
| 52 The vertex attrib order is always pos, color, [local coords]. | 27 The vertex attrib order is always pos, color, [local coords]. |
| 53 */ | 28 */ |
| 54 static sk_sp<GrGeometryProcessor> make_gp(const SkMatrix& viewMatrix, | 29 static sk_sp<GrGeometryProcessor> make_gp(const SkMatrix& viewMatrix, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 83 GrColor color, | 58 GrColor color, |
| 84 const SkMatrix& viewMatrix, | 59 const SkMatrix& viewMatrix, |
| 85 const SkRect& rect, | 60 const SkRect& rect, |
| 86 const GrQuad* localQuad) { | 61 const GrQuad* localQuad) { |
| 87 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices); | 62 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices); |
| 88 | 63 |
| 89 positions->setRectFan(rect.fLeft, rect.fTop, | 64 positions->setRectFan(rect.fLeft, rect.fTop, |
| 90 rect.fRight, rect.fBottom, vertexStride); | 65 rect.fRight, rect.fBottom, vertexStride); |
| 91 | 66 |
| 92 if (!viewMatrix.hasPerspective()) { | 67 if (!viewMatrix.hasPerspective()) { |
| 93 viewMatrix.mapPointsWithStride(positions, vertexStride, | 68 viewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerInstanc
e); |
| 94 NonAAFillRectBatchBase::kVertsPerInstance
); | |
| 95 } | 69 } |
| 96 | 70 |
| 97 // Setup local coords | 71 // Setup local coords |
| 98 // TODO we should only do this if local coords are being read | 72 // TODO we should only do this if local coords are being read |
| 99 if (localQuad) { | 73 if (localQuad) { |
| 100 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); | 74 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); |
| 101 for (int i = 0; i < NonAAFillRectBatchBase::kVertsPerInstance; i++) { | 75 for (int i = 0; i < kVertsPerInstance; i++) { |
| 102 SkPoint* coords = reinterpret_cast<SkPoint*>(vertices + kLocalOffset
+ | 76 SkPoint* coords = reinterpret_cast<SkPoint*>(vertices + kLocalOffset
+ |
| 103 i * vertexStride); | 77 i * vertexStride); |
| 104 *coords = localQuad->point(i); | 78 *coords = localQuad->point(i); |
| 105 } | 79 } |
| 106 } | 80 } |
| 107 | 81 |
| 108 static const int kColorOffset = sizeof(SkPoint); | 82 static const int kColorOffset = sizeof(SkPoint); |
| 109 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset); | 83 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset); |
| 110 for (int j = 0; j < 4; ++j) { | 84 for (int j = 0; j < 4; ++j) { |
| 111 *vertColor = color; | 85 *vertColor = color; |
| 112 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); | 86 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); |
| 113 } | 87 } |
| 114 } | 88 } |
| 115 | 89 |
| 116 class NonAAFillRectBatchImp : public NonAAFillRectBatchBase { | 90 class NonAAFillRectBatch : public GrVertexBatch { |
| 117 public: | 91 public: |
| 92 DEFINE_BATCH_CLASS_ID |
| 93 |
| 118 struct Geometry { | 94 struct Geometry { |
| 119 SkMatrix fViewMatrix; | 95 SkMatrix fViewMatrix; |
| 120 SkRect fRect; | 96 SkRect fRect; |
| 121 GrQuad fLocalQuad; | 97 GrQuad fLocalQuad; |
| 122 GrColor fColor; | 98 GrColor fColor; |
| 123 }; | 99 }; |
| 124 | 100 |
| 101 static NonAAFillRectBatch* Create() { return new NonAAFillRectBatch; } |
| 102 |
| 103 const char* name() const override { return Name(); } |
| 104 |
| 105 SkString dumpInfo() const override { |
| 106 SkString str; |
| 107 str.appendf("# batched: %d\n", fGeoData.count()); |
| 108 for (int i = 0; i < fGeoData.count(); ++i) { |
| 109 str.append(DumpInfo(fGeoData[i], i)); |
| 110 } |
| 111 str.append(INHERITED::dumpInfo()); |
| 112 return str; |
| 113 } |
| 114 |
| 115 void computePipelineOptimizations(GrInitInvariantOutput* color, |
| 116 GrInitInvariantOutput* coverage, |
| 117 GrBatchToXPOverrides* overrides) const ove
rride { |
| 118 // When this is called on a batch, there is only one geometry bundle |
| 119 color->setKnownFourComponents(fGeoData[0].fColor); |
| 120 InitInvariantOutputCoverage(coverage); |
| 121 } |
| 122 |
| 123 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| 124 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 125 fOverrides = overrides; |
| 126 } |
| 127 |
| 128 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 129 |
| 130 // After seeding, the client should call init() so the Batch can initialize
itself |
| 131 void init() { |
| 132 const Geometry& geo = fGeoData[0]; |
| 133 SetBounds(geo, &fBounds); |
| 134 } |
| 135 |
| 136 void updateBoundsAfterAppend() { |
| 137 const Geometry& geo = fGeoData.back(); |
| 138 UpdateBoundsAfterAppend(geo, &fBounds); |
| 139 } |
| 140 |
| 141 private: |
| 125 static const char* Name() { return "NonAAFillRectBatch"; } | 142 static const char* Name() { return "NonAAFillRectBatch"; } |
| 126 | 143 |
| 127 static SkString DumpInfo(const Geometry& geo, int index) { | 144 static SkString DumpInfo(const Geometry& geo, int index) { |
| 128 SkString str; | 145 SkString str; |
| 129 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f
]\n", | 146 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f
]\n", |
| 130 index, | 147 index, |
| 131 geo.fColor, | 148 geo.fColor, |
| 132 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect
.fBottom); | 149 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect
.fBottom); |
| 133 return str; | 150 return str; |
| 134 } | 151 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 145 | 162 |
| 146 SkASSERT(gp->getVertexStride() == | 163 SkASSERT(gp->getVertexStride() == |
| 147 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)); | 164 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)); |
| 148 return gp; | 165 return gp; |
| 149 } | 166 } |
| 150 | 167 |
| 151 static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry
& geo, | 168 static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry
& geo, |
| 152 const GrXPOverridesForBatch& overrides) { | 169 const GrXPOverridesForBatch& overrides) { |
| 153 tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect
, &geo.fLocalQuad); | 170 tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect
, &geo.fLocalQuad); |
| 154 } | 171 } |
| 172 |
| 173 static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { |
| 174 out->setKnownSingleComponent(0xff); |
| 175 } |
| 176 |
| 177 static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { |
| 178 return rp->refQuadIndexBuffer(); |
| 179 } |
| 180 |
| 181 static void SetBounds(const Geometry& geo, SkRect* outBounds) { |
| 182 geo.fViewMatrix.mapRect(outBounds, geo.fRect); |
| 183 } |
| 184 |
| 185 static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds)
{ |
| 186 SkRect bounds = geo.fRect; |
| 187 geo.fViewMatrix.mapRect(&bounds); |
| 188 outBounds->join(bounds); |
| 189 } |
| 190 |
| 191 NonAAFillRectBatch() : INHERITED(ClassID()) {} |
| 192 |
| 193 void onPrepareDraws(Target* target) const override { |
| 194 sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); |
| 195 if (!gp) { |
| 196 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 197 return; |
| 198 } |
| 199 |
| 200 size_t vertexStride = gp->getVertexStride(); |
| 201 int instanceCount = fGeoData.count(); |
| 202 |
| 203 SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resource
Provider())); |
| 204 InstancedHelper helper; |
| 205 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
| 206 indexBuffer, kVertsPerInstance, |
| 207 kIndicesPerInstance, instanceCount); |
| 208 if (!vertices || !indexBuffer) { |
| 209 SkDebugf("Could not allocate vertices\n"); |
| 210 return; |
| 211 } |
| 212 |
| 213 for (int i = 0; i < instanceCount; i++) { |
| 214 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
| 215 i * kVertsPerInstance * vertexStride; |
| 216 Tesselate(verts, vertexStride, fGeoData[i], fOverrides); |
| 217 } |
| 218 helper.recordDraw(target, gp.get()); |
| 219 } |
| 220 |
| 221 const Geometry& seedGeometry() const { return fGeoData[0]; } |
| 222 |
| 223 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 224 NonAAFillRectBatch* that = t->cast<NonAAFillRectBatch>(); |
| 225 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 226 that->bounds(), caps)) { |
| 227 return false; |
| 228 } |
| 229 |
| 230 if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides))
{ |
| 231 return false; |
| 232 } |
| 233 |
| 234 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 235 // not tweaking |
| 236 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
| 237 fOverrides = that->fOverrides; |
| 238 } |
| 239 |
| 240 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
| 241 this->joinBounds(that->bounds()); |
| 242 return true; |
| 243 } |
| 244 |
| 245 GrXPOverridesForBatch fOverrides; |
| 246 SkSTArray<1, Geometry, true> fGeoData; |
| 247 |
| 248 typedef GrVertexBatch INHERITED; |
| 155 }; | 249 }; |
| 156 | 250 |
| 157 // We handle perspective in the local matrix or viewmatrix with special batches | 251 // We handle perspective in the local matrix or viewmatrix with special batches |
| 158 class NonAAFillRectBatchPerspectiveImp : public NonAAFillRectBatchBase { | 252 class NonAAFillRectPerspectiveBatch : public GrVertexBatch { |
| 159 public: | 253 public: |
| 254 DEFINE_BATCH_CLASS_ID |
| 255 |
| 160 struct Geometry { | 256 struct Geometry { |
| 161 SkMatrix fViewMatrix; | 257 SkMatrix fViewMatrix; |
| 162 SkMatrix fLocalMatrix; | 258 SkMatrix fLocalMatrix; |
| 163 SkRect fRect; | 259 SkRect fRect; |
| 164 SkRect fLocalRect; | 260 SkRect fLocalRect; |
| 165 GrColor fColor; | 261 GrColor fColor; |
| 166 bool fHasLocalMatrix; | 262 bool fHasLocalMatrix; |
| 167 bool fHasLocalRect; | 263 bool fHasLocalRect; |
| 168 }; | 264 }; |
| 169 | 265 |
| 170 static const char* Name() { return "NonAAFillRectBatchPerspective"; } | 266 static NonAAFillRectPerspectiveBatch* Create() { return new NonAAFillRectPer
spectiveBatch; } |
| 267 |
| 268 const char* name() const override { return Name(); } |
| 269 |
| 270 SkString dumpInfo() const override { |
| 271 SkString str; |
| 272 str.appendf("# batched: %d\n", fGeoData.count()); |
| 273 for (int i = 0; i < fGeoData.count(); ++i) { |
| 274 str.append(DumpInfo(fGeoData[i], i)); |
| 275 } |
| 276 str.append(INHERITED::dumpInfo()); |
| 277 return str; |
| 278 } |
| 279 |
| 280 void computePipelineOptimizations(GrInitInvariantOutput* color, |
| 281 GrInitInvariantOutput* coverage, |
| 282 GrBatchToXPOverrides* overrides) const ove
rride { |
| 283 // When this is called on a batch, there is only one geometry bundle |
| 284 color->setKnownFourComponents(fGeoData[0].fColor); |
| 285 InitInvariantOutputCoverage(coverage); |
| 286 } |
| 287 |
| 288 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| 289 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 290 fOverrides = overrides; |
| 291 } |
| 292 |
| 293 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 294 |
| 295 // After seeding, the client should call init() so the Batch can initialize
itself |
| 296 void init() { |
| 297 const Geometry& geo = fGeoData[0]; |
| 298 SetBounds(geo, &fBounds); |
| 299 } |
| 300 |
| 301 void updateBoundsAfterAppend() { |
| 302 const Geometry& geo = fGeoData.back(); |
| 303 UpdateBoundsAfterAppend(geo, &fBounds); |
| 304 } |
| 305 |
| 306 private: |
| 307 static const char* Name() { return "NonAAFillRectPerspectiveBatch"; } |
| 171 | 308 |
| 172 static SkString DumpInfo(const Geometry& geo, int index) { | 309 static SkString DumpInfo(const Geometry& geo, int index) { |
| 173 SkString str; | 310 SkString str; |
| 174 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f
]\n", | 311 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f
]\n", |
| 175 index, | 312 index, |
| 176 geo.fColor, | 313 geo.fColor, |
| 177 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect
.fBottom); | 314 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect
.fBottom); |
| 178 return str; | 315 return str; |
| 179 } | 316 } |
| 180 | 317 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 201 | 338 |
| 202 static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry
& geo, | 339 static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry
& geo, |
| 203 const GrXPOverridesForBatch& overrides) { | 340 const GrXPOverridesForBatch& overrides) { |
| 204 if (geo.fHasLocalRect) { | 341 if (geo.fHasLocalRect) { |
| 205 GrQuad quad(geo.fLocalRect); | 342 GrQuad quad(geo.fLocalRect); |
| 206 tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.f
Rect, &quad); | 343 tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.f
Rect, &quad); |
| 207 } else { | 344 } else { |
| 208 tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.f
Rect, nullptr); | 345 tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.f
Rect, nullptr); |
| 209 } | 346 } |
| 210 } | 347 } |
| 348 |
| 349 static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { |
| 350 out->setKnownSingleComponent(0xff); |
| 351 } |
| 352 |
| 353 static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { |
| 354 return rp->refQuadIndexBuffer(); |
| 355 } |
| 356 |
| 357 static void SetBounds(const Geometry& geo, SkRect* outBounds) { |
| 358 geo.fViewMatrix.mapRect(outBounds, geo.fRect); |
| 359 } |
| 360 |
| 361 static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds)
{ |
| 362 SkRect bounds = geo.fRect; |
| 363 geo.fViewMatrix.mapRect(&bounds); |
| 364 outBounds->join(bounds); |
| 365 } |
| 366 |
| 367 NonAAFillRectPerspectiveBatch() : INHERITED(ClassID()) {} |
| 368 |
| 369 void onPrepareDraws(Target* target) const override { |
| 370 sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); |
| 371 if (!gp) { |
| 372 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 373 return; |
| 374 } |
| 375 |
| 376 size_t vertexStride = gp->getVertexStride(); |
| 377 int instanceCount = fGeoData.count(); |
| 378 |
| 379 SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resource
Provider())); |
| 380 InstancedHelper helper; |
| 381 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
| 382 indexBuffer, kVertsPerInstance, |
| 383 kIndicesPerInstance, instanceCount); |
| 384 if (!vertices || !indexBuffer) { |
| 385 SkDebugf("Could not allocate vertices\n"); |
| 386 return; |
| 387 } |
| 388 |
| 389 for (int i = 0; i < instanceCount; i++) { |
| 390 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
| 391 i * kVertsPerInstance * vertexStride; |
| 392 Tesselate(verts, vertexStride, fGeoData[i], fOverrides); |
| 393 } |
| 394 helper.recordDraw(target, gp.get()); |
| 395 } |
| 396 |
| 397 const Geometry& seedGeometry() const { return fGeoData[0]; } |
| 398 |
| 399 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 400 NonAAFillRectPerspectiveBatch* that = t->cast<NonAAFillRectPerspectiveBa
tch>(); |
| 401 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 402 that->bounds(), caps)) { |
| 403 return false; |
| 404 } |
| 405 |
| 406 if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides))
{ |
| 407 return false; |
| 408 } |
| 409 |
| 410 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 411 // not tweaking |
| 412 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
| 413 fOverrides = that->fOverrides; |
| 414 } |
| 415 |
| 416 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
| 417 this->joinBounds(that->bounds()); |
| 418 return true; |
| 419 } |
| 420 |
| 421 GrXPOverridesForBatch fOverrides; |
| 422 SkSTArray<1, Geometry, true> fGeoData; |
| 423 |
| 424 typedef GrVertexBatch INHERITED; |
| 211 }; | 425 }; |
| 212 | 426 |
| 213 typedef GrTInstanceBatch<NonAAFillRectBatchImp> NonAAFillRectBatchSimple; | 427 inline static void append_to_batch(NonAAFillRectBatch* batch, GrColor color, |
| 214 typedef GrTInstanceBatch<NonAAFillRectBatchPerspectiveImp> NonAAFillRectBatchPer
spective; | |
| 215 | |
| 216 inline static void append_to_batch(NonAAFillRectBatchSimple* batch, GrColor colo
r, | |
| 217 const SkMatrix& viewMatrix, const SkRect& rec
t, | 428 const SkMatrix& viewMatrix, const SkRect& rec
t, |
| 218 const SkRect* localRect, const SkMatrix* loca
lMatrix) { | 429 const SkRect* localRect, const SkMatrix* loca
lMatrix) { |
| 219 SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasP
erspective())); | 430 SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasP
erspective())); |
| 220 NonAAFillRectBatchSimple::Geometry& geo = batch->geoData()->push_back(); | 431 NonAAFillRectBatch::Geometry& geo = batch->geoData()->push_back(); |
| 221 | 432 |
| 222 geo.fColor = color; | 433 geo.fColor = color; |
| 223 geo.fViewMatrix = viewMatrix; | 434 geo.fViewMatrix = viewMatrix; |
| 224 geo.fRect = rect; | 435 geo.fRect = rect; |
| 225 | 436 |
| 226 if (localRect && localMatrix) { | 437 if (localRect && localMatrix) { |
| 227 geo.fLocalQuad.setFromMappedRect(*localRect, *localMatrix); | 438 geo.fLocalQuad.setFromMappedRect(*localRect, *localMatrix); |
| 228 } else if (localRect) { | 439 } else if (localRect) { |
| 229 geo.fLocalQuad.set(*localRect); | 440 geo.fLocalQuad.set(*localRect); |
| 230 } else if (localMatrix) { | 441 } else if (localMatrix) { |
| 231 geo.fLocalQuad.setFromMappedRect(rect, *localMatrix); | 442 geo.fLocalQuad.setFromMappedRect(rect, *localMatrix); |
| 232 } else { | 443 } else { |
| 233 geo.fLocalQuad.set(rect); | 444 geo.fLocalQuad.set(rect); |
| 234 } | 445 } |
| 235 } | 446 } |
| 236 | 447 |
| 237 inline static void append_to_batch(NonAAFillRectBatchPerspective* batch, GrColor
color, | 448 inline static void append_to_batch(NonAAFillRectPerspectiveBatch* batch, GrColor
color, |
| 238 const SkMatrix& viewMatrix, const SkRect& rec
t, | 449 const SkMatrix& viewMatrix, const SkRect& rec
t, |
| 239 const SkRect* localRect, const SkMatrix* loca
lMatrix) { | 450 const SkRect* localRect, const SkMatrix* loca
lMatrix) { |
| 240 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPers
pective())); | 451 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPers
pective())); |
| 241 NonAAFillRectBatchPerspective::Geometry& geo = batch->geoData()->push_back()
; | 452 NonAAFillRectPerspectiveBatch::Geometry& geo = batch->geoData()->push_back()
; |
| 242 | 453 |
| 243 geo.fColor = color; | 454 geo.fColor = color; |
| 244 geo.fViewMatrix = viewMatrix; | 455 geo.fViewMatrix = viewMatrix; |
| 245 geo.fRect = rect; | 456 geo.fRect = rect; |
| 246 geo.fHasLocalRect = SkToBool(localRect); | 457 geo.fHasLocalRect = SkToBool(localRect); |
| 247 geo.fHasLocalMatrix = SkToBool(localMatrix); | 458 geo.fHasLocalMatrix = SkToBool(localMatrix); |
| 248 if (localMatrix) { | 459 if (localMatrix) { |
| 249 geo.fLocalMatrix = *localMatrix; | 460 geo.fLocalMatrix = *localMatrix; |
| 250 } | 461 } |
| 251 if (localRect) { | 462 if (localRect) { |
| 252 geo.fLocalRect = *localRect; | 463 geo.fLocalRect = *localRect; |
| 253 } | 464 } |
| 254 | 465 |
| 255 } | 466 } |
| 256 | 467 |
| 257 namespace GrNonAAFillRectBatch { | 468 namespace GrNonAAFillRectBatch { |
| 258 | 469 |
| 259 GrDrawBatch* Create(GrColor color, | 470 GrDrawBatch* Create(GrColor color, |
| 260 const SkMatrix& viewMatrix, | 471 const SkMatrix& viewMatrix, |
| 261 const SkRect& rect, | 472 const SkRect& rect, |
| 262 const SkRect* localRect, | 473 const SkRect* localRect, |
| 263 const SkMatrix* localMatrix) { | 474 const SkMatrix* localMatrix) { |
| 264 NonAAFillRectBatchSimple* batch = NonAAFillRectBatchSimple::Create(); | 475 NonAAFillRectBatch* batch = NonAAFillRectBatch::Create(); |
| 265 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); | 476 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); |
| 266 batch->init(); | 477 batch->init(); |
| 267 return batch; | 478 return batch; |
| 268 } | 479 } |
| 269 | 480 |
| 270 GrDrawBatch* CreateWithPerspective(GrColor color, | 481 GrDrawBatch* CreateWithPerspective(GrColor color, |
| 271 const SkMatrix& viewMatrix, | 482 const SkMatrix& viewMatrix, |
| 272 const SkRect& rect, | 483 const SkRect& rect, |
| 273 const SkRect* localRect, | 484 const SkRect* localRect, |
| 274 const SkMatrix* localMatrix) { | 485 const SkMatrix* localMatrix) { |
| 275 NonAAFillRectBatchPerspective* batch = NonAAFillRectBatchPerspective::Create
(); | 486 NonAAFillRectPerspectiveBatch* batch = NonAAFillRectPerspectiveBatch::Create
(); |
| 276 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); | 487 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); |
| 277 batch->init(); | 488 batch->init(); |
| 278 return batch; | 489 return batch; |
| 279 } | 490 } |
| 280 | 491 |
| 281 bool Append(GrBatch* origBatch, | 492 bool Append(GrBatch* origBatch, |
| 282 GrColor color, | 493 GrColor color, |
| 283 const SkMatrix& viewMatrix, | 494 const SkMatrix& viewMatrix, |
| 284 const SkRect& rect, | 495 const SkRect& rect, |
| 285 const SkRect* localRect, | 496 const SkRect* localRect, |
| 286 const SkMatrix* localMatrix) { | 497 const SkMatrix* localMatrix) { |
| 287 bool usePerspective = viewMatrix.hasPerspective() || | 498 bool usePerspective = viewMatrix.hasPerspective() || |
| 288 (localMatrix && localMatrix->hasPerspective()); | 499 (localMatrix && localMatrix->hasPerspective()); |
| 289 | 500 |
| 290 if (usePerspective && origBatch->classID() != NonAAFillRectBatchPerspective:
:ClassID()) { | 501 if (usePerspective && origBatch->classID() != NonAAFillRectPerspectiveBatch:
:ClassID()) { |
| 291 return false; | 502 return false; |
| 292 } | 503 } |
| 293 | 504 |
| 294 if (!usePerspective) { | 505 if (!usePerspective) { |
| 295 NonAAFillRectBatchSimple* batch = origBatch->cast<NonAAFillRectBatchSimp
le>(); | 506 NonAAFillRectBatch* batch = origBatch->cast<NonAAFillRectBatch>(); |
| 296 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); | 507 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); |
| 297 batch->updateBoundsAfterAppend(); | 508 batch->updateBoundsAfterAppend(); |
| 298 } else { | 509 } else { |
| 299 NonAAFillRectBatchPerspective* batch = origBatch->cast<NonAAFillRectBatc
hPerspective>(); | 510 NonAAFillRectPerspectiveBatch* batch = origBatch->cast<NonAAFillRectPers
pectiveBatch>(); |
| 300 const NonAAFillRectBatchPerspective::Geometry& geo = batch->geoData()->b
ack(); | 511 const NonAAFillRectPerspectiveBatch::Geometry& geo = batch->geoData()->b
ack(); |
| 301 | 512 |
| 302 if (!geo.fViewMatrix.cheapEqualTo(viewMatrix) || | 513 if (!geo.fViewMatrix.cheapEqualTo(viewMatrix) || |
| 303 geo.fHasLocalRect != SkToBool(localRect) || | 514 geo.fHasLocalRect != SkToBool(localRect) || |
| 304 geo.fHasLocalMatrix != SkToBool(localMatrix) || | 515 geo.fHasLocalMatrix != SkToBool(localMatrix) || |
| 305 (geo.fHasLocalMatrix && !geo.fLocalMatrix.cheapEqualTo(*localMatrix)
)) { | 516 (geo.fHasLocalMatrix && !geo.fLocalMatrix.cheapEqualTo(*localMatrix)
)) { |
| 306 return false; | 517 return false; |
| 307 } | 518 } |
| 308 | 519 |
| 309 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); | 520 append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); |
| 310 batch->updateBoundsAfterAppend(); | 521 batch->updateBoundsAfterAppend(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 329 SkMatrix localMatrix = GrTest::TestMatrix(random); | 540 SkMatrix localMatrix = GrTest::TestMatrix(random); |
| 330 | 541 |
| 331 bool hasLocalRect = random->nextBool(); | 542 bool hasLocalRect = random->nextBool(); |
| 332 bool hasLocalMatrix = random->nextBool(); | 543 bool hasLocalMatrix = random->nextBool(); |
| 333 return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, | 544 return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, |
| 334 hasLocalRect ? &localRect : nullptr, | 545 hasLocalRect ? &localRect : nullptr, |
| 335 hasLocalMatrix ? &localMatrix : nullptr)
; | 546 hasLocalMatrix ? &localMatrix : nullptr)
; |
| 336 } | 547 } |
| 337 | 548 |
| 338 #endif | 549 #endif |
| OLD | NEW |