| 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" |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 193 |
| 194 struct Geometry { | 194 struct Geometry { |
| 195 SkMatrix fViewMatrix; | 195 SkMatrix fViewMatrix; |
| 196 SkRect fRect; | 196 SkRect fRect; |
| 197 SkRect fDevRect; | 197 SkRect fDevRect; |
| 198 GrColor fColor; | 198 GrColor fColor; |
| 199 }; | 199 }; |
| 200 | 200 |
| 201 static AAFillRectNoLocalMatrixBatch* Create() { return new AAFillRectNoLocal
MatrixBatch; } | 201 static AAFillRectNoLocalMatrixBatch* Create() { return new AAFillRectNoLocal
MatrixBatch; } |
| 202 | 202 |
| 203 const char* name() const override { return Name(); } | 203 const char* name() const override { return "AAFillRectBatchNoLocalMatrix"; } |
| 204 | 204 |
| 205 SkString dumpInfo() const override { | 205 SkString dumpInfo() const override { |
| 206 SkString str; | 206 SkString str; |
| 207 str.appendf("# batched: %d\n", fGeoData.count()); | 207 str.appendf("# batched: %d\n", fGeoData.count()); |
| 208 for (int i = 0; i < fGeoData.count(); ++i) { | 208 for (int i = 0; i < fGeoData.count(); ++i) { |
| 209 str.append(DumpInfo(fGeoData[i], i)); | 209 const Geometry& geo = fGeoData[i]; |
| 210 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", |
| 211 i, geo.fColor, |
| 212 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.f
Rect.fBottom); |
| 210 } | 213 } |
| 211 str.append(INHERITED::dumpInfo()); | 214 str.append(INHERITED::dumpInfo()); |
| 212 return str; | 215 return str; |
| 213 } | 216 } |
| 214 | 217 |
| 215 void computePipelineOptimizations(GrInitInvariantOutput* color, | 218 void computePipelineOptimizations(GrInitInvariantOutput* color, |
| 216 GrInitInvariantOutput* coverage, | 219 GrInitInvariantOutput* coverage, |
| 217 GrBatchToXPOverrides* overrides) const ove
rride { | 220 GrBatchToXPOverrides* overrides) const ove
rride { |
| 218 // When this is called on a batch, there is only one geometry bundle | 221 // When this is called on a batch, there is only one geometry bundle |
| 219 color->setKnownFourComponents(fGeoData[0].fColor); | 222 color->setKnownFourComponents(fGeoData[0].fColor); |
| 220 InitInvariantOutputCoverage(coverage); | 223 coverage->setUnknownSingleComponent(); |
| 221 } | 224 } |
| 222 | 225 |
| 223 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 226 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| 224 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); | 227 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 225 fOverrides = overrides; | 228 fOverrides = overrides; |
| 226 } | 229 } |
| 227 | 230 |
| 228 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 231 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 229 | 232 |
| 230 // After seeding, the client should call init() so the Batch can initialize
itself | 233 // After seeding, the client should call init() so the Batch can initialize
itself |
| 231 void init() { | 234 void init() { fBounds = fGeoData[0].fDevRect; } |
| 232 const Geometry& geo = fGeoData[0]; | |
| 233 SetBounds(geo, &fBounds); | |
| 234 } | |
| 235 | |
| 236 void updateBoundsAfterAppend() { | |
| 237 const Geometry& geo = fGeoData.back(); | |
| 238 UpdateBoundsAfterAppend(geo, &fBounds); | |
| 239 } | |
| 240 | 235 |
| 241 private: | 236 private: |
| 242 static const int kVertsPerInstance = kVertsPerAAFillRect; | |
| 243 static const int kIndicesPerInstance = kIndicesPerAAFillRect; | |
| 244 | |
| 245 static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { | |
| 246 out->setUnknownSingleComponent(); | |
| 247 } | |
| 248 | |
| 249 static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { | |
| 250 return get_index_buffer(rp); | |
| 251 } | |
| 252 | |
| 253 static void SetBounds(const Geometry& geo, SkRect* outBounds) { | |
| 254 *outBounds = geo.fDevRect; | |
| 255 } | |
| 256 | |
| 257 static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds)
{ | |
| 258 outBounds->join(geo.fDevRect); | |
| 259 } | |
| 260 | |
| 261 static const char* Name() { return "AAFillRectBatchNoLocalMatrix"; } | |
| 262 | |
| 263 static SkString DumpInfo(const Geometry& geo, int index) { | |
| 264 SkString str; | |
| 265 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f
]\n", | |
| 266 index, | |
| 267 geo.fColor, | |
| 268 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect
.fBottom); | |
| 269 return str; | |
| 270 } | |
| 271 | |
| 272 static bool CanCombine(const Geometry& mine, const Geometry& theirs, | |
| 273 const GrXPOverridesForBatch& overrides) { | |
| 274 // We apply the viewmatrix to the rect points on the cpu. However, if t
he pipeline uses | |
| 275 // local coords then we won't be able to batch. We could actually uploa
d the viewmatrix | |
| 276 // using vertex attributes in these cases, but haven't investigated that | |
| 277 return !overrides.readsLocalCoords() || mine.fViewMatrix.cheapEqualTo(th
eirs.fViewMatrix); | |
| 278 } | |
| 279 | |
| 280 static sk_sp<GrGeometryProcessor> MakeGP(const Geometry& geo, | |
| 281 const GrXPOverridesForBatch& overri
des) { | |
| 282 sk_sp<GrGeometryProcessor> gp = | |
| 283 create_fill_rect_gp(geo.fViewMatrix, overrides, | |
| 284 GrDefaultGeoProcFactory::LocalCoords::kUsePo
sition_Type); | |
| 285 | |
| 286 SkASSERT(overrides.canTweakAlphaForCoverage() ? | |
| 287 gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr) : | |
| 288 gp->getVertexStride() == | |
| 289 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAt
tr)); | |
| 290 return gp; | |
| 291 } | |
| 292 | |
| 293 static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry
& geo, | |
| 294 const GrXPOverridesForBatch& overrides) { | |
| 295 generate_aa_fill_rect_geometry(vertices, vertexStride, | |
| 296 geo.fColor, geo.fViewMatrix, geo.fRect, g
eo.fDevRect, | |
| 297 overrides, nullptr); | |
| 298 } | |
| 299 | |
| 300 AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} | 237 AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} |
| 301 | 238 |
| 302 void onPrepareDraws(Target* target) const override { | 239 void onPrepareDraws(Target* target) const override { |
| 303 sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); | 240 sk_sp<GrGeometryProcessor> gp = |
| 241 create_fill_rect_gp(fGeoData[0].fViewMatrix, fOverrides, |
| 242 GrDefaultGeoProcFactory::LocalCoords::kUsePo
sition_Type); |
| 304 if (!gp) { | 243 if (!gp) { |
| 305 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 244 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 306 return; | 245 return; |
| 307 } | 246 } |
| 247 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? |
| 248 gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Po
sitionColorAttr) : |
| 249 gp->getVertexStride() == |
| 250 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAt
tr)); |
| 308 | 251 |
| 309 size_t vertexStride = gp->getVertexStride(); | 252 size_t vertexStride = gp->getVertexStride(); |
| 310 int instanceCount = fGeoData.count(); | 253 int instanceCount = fGeoData.count(); |
| 311 | 254 |
| 312 SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resource
Provider())); | 255 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); |
| 313 InstancedHelper helper; | 256 InstancedHelper helper; |
| 314 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | 257 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
| 315 indexBuffer, kVertsPerInstance, | 258 indexBuffer, kVertsPerAAFillRect, |
| 316 kIndicesPerInstance, instanceCount); | 259 kIndicesPerAAFillRect, instanceCount); |
| 317 if (!vertices || !indexBuffer) { | 260 if (!vertices || !indexBuffer) { |
| 318 SkDebugf("Could not allocate vertices\n"); | 261 SkDebugf("Could not allocate vertices\n"); |
| 319 return; | 262 return; |
| 320 } | 263 } |
| 321 | 264 |
| 322 for (int i = 0; i < instanceCount; i++) { | 265 for (int i = 0; i < instanceCount; i++) { |
| 323 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | 266 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
| 324 i * kVertsPerInstance * vertexStride; | 267 i * kVertsPerAAFillRect * vertexStride; |
| 325 Tesselate(verts, vertexStride, fGeoData[i], fOverrides); | 268 generate_aa_fill_rect_geometry(verts, vertexStride, |
| 269 fGeoData[i].fColor, fGeoData[i].fView
Matrix, |
| 270 fGeoData[i].fRect, fGeoData[i].fDevRe
ct, fOverrides, |
| 271 nullptr); |
| 326 } | 272 } |
| 327 helper.recordDraw(target, gp.get()); | 273 helper.recordDraw(target, gp.get()); |
| 328 } | 274 } |
| 329 | 275 |
| 330 const Geometry& seedGeometry() const { return fGeoData[0]; } | |
| 331 | |
| 332 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 276 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 333 AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatc
h>(); | 277 AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatc
h>(); |
| 334 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 278 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 335 that->bounds(), caps)) { | 279 that->bounds(), caps)) { |
| 336 return false; | 280 return false; |
| 337 } | 281 } |
| 338 | 282 |
| 339 if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides))
{ | 283 // We apply the viewmatrix to the rect points on the cpu. However, if t
he pipeline uses |
| 284 // local coords then we won't be able to batch. We could actually uploa
d the viewmatrix |
| 285 // using vertex attributes in these cases, but haven't investigated that |
| 286 if (fOverrides.readsLocalCoords() && |
| 287 !fGeoData[0].fViewMatrix.cheapEqualTo(that->fGeoData[0].fViewMatrix)
) { |
| 340 return false; | 288 return false; |
| 341 } | 289 } |
| 342 | 290 |
| 343 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | 291 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 344 // not tweaking | 292 // not tweaking |
| 345 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | 293 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
| 346 fOverrides = that->fOverrides; | 294 fOverrides = that->fOverrides; |
| 347 } | 295 } |
| 348 | 296 |
| 349 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 297 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 364 struct Geometry { | 312 struct Geometry { |
| 365 SkMatrix fViewMatrix; | 313 SkMatrix fViewMatrix; |
| 366 SkMatrix fLocalMatrix; | 314 SkMatrix fLocalMatrix; |
| 367 SkRect fRect; | 315 SkRect fRect; |
| 368 SkRect fDevRect; | 316 SkRect fDevRect; |
| 369 GrColor fColor; | 317 GrColor fColor; |
| 370 }; | 318 }; |
| 371 | 319 |
| 372 static AAFillRectLocalMatrixBatch* Create() { return new AAFillRectLocalMatr
ixBatch; } | 320 static AAFillRectLocalMatrixBatch* Create() { return new AAFillRectLocalMatr
ixBatch; } |
| 373 | 321 |
| 374 const char* name() const override { return Name(); } | 322 const char* name() const override { return "AAFillRectBatchLocalMatrix"; } |
| 375 | 323 |
| 376 SkString dumpInfo() const override { | 324 SkString dumpInfo() const override { |
| 377 SkString str; | 325 SkString str; |
| 378 str.appendf("# batched: %d\n", fGeoData.count()); | 326 str.appendf("# batched: %d\n", fGeoData.count()); |
| 379 for (int i = 0; i < fGeoData.count(); ++i) { | 327 for (int i = 0; i < fGeoData.count(); ++i) { |
| 380 str.append(DumpInfo(fGeoData[i], i)); | 328 const Geometry& geo = fGeoData[i]; |
| 329 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", |
| 330 i, geo.fColor, |
| 331 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.f
Rect.fBottom); |
| 381 } | 332 } |
| 382 str.append(INHERITED::dumpInfo()); | 333 str.append(INHERITED::dumpInfo()); |
| 383 return str; | 334 return str; |
| 384 } | 335 } |
| 385 | 336 |
| 386 void computePipelineOptimizations(GrInitInvariantOutput* color, | 337 void computePipelineOptimizations(GrInitInvariantOutput* color, |
| 387 GrInitInvariantOutput* coverage, | 338 GrInitInvariantOutput* coverage, |
| 388 GrBatchToXPOverrides* overrides) const ove
rride { | 339 GrBatchToXPOverrides* overrides) const ove
rride { |
| 389 // When this is called on a batch, there is only one geometry bundle | 340 // When this is called on a batch, there is only one geometry bundle |
| 390 color->setKnownFourComponents(fGeoData[0].fColor); | 341 color->setKnownFourComponents(fGeoData[0].fColor); |
| 391 InitInvariantOutputCoverage(coverage); | 342 coverage->setUnknownSingleComponent(); |
| 392 } | 343 } |
| 393 | 344 |
| 394 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 345 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| 395 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); | 346 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 396 fOverrides = overrides; | 347 fOverrides = overrides; |
| 397 } | 348 } |
| 398 | 349 |
| 399 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 350 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 400 | 351 |
| 401 // After seeding, the client should call init() so the Batch can initialize
itself | 352 // After seeding, the client should call init() so the Batch can initialize
itself |
| 402 void init() { | 353 void init() { fBounds = fGeoData[0].fDevRect; } |
| 403 const Geometry& geo = fGeoData[0]; | |
| 404 SetBounds(geo, &fBounds); | |
| 405 } | |
| 406 | |
| 407 void updateBoundsAfterAppend() { | |
| 408 const Geometry& geo = fGeoData.back(); | |
| 409 UpdateBoundsAfterAppend(geo, &fBounds); | |
| 410 } | |
| 411 | 354 |
| 412 private: | 355 private: |
| 413 static const int kVertsPerInstance = kVertsPerAAFillRect; | |
| 414 static const int kIndicesPerInstance = kIndicesPerAAFillRect; | |
| 415 | |
| 416 static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { | |
| 417 out->setUnknownSingleComponent(); | |
| 418 } | |
| 419 | |
| 420 static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { | |
| 421 return get_index_buffer(rp); | |
| 422 } | |
| 423 | |
| 424 static void SetBounds(const Geometry& geo, SkRect* outBounds) { | |
| 425 *outBounds = geo.fDevRect; | |
| 426 } | |
| 427 | |
| 428 static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds)
{ | |
| 429 outBounds->join(geo.fDevRect); | |
| 430 } | |
| 431 | |
| 432 static const char* Name() { return "AAFillRectBatchLocalMatrix"; } | |
| 433 | |
| 434 static SkString DumpInfo(const Geometry& geo, int index) { | |
| 435 SkString str; | |
| 436 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f
]\n", | |
| 437 index, | |
| 438 geo.fColor, | |
| 439 geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect
.fBottom); | |
| 440 return str; | |
| 441 } | |
| 442 | |
| 443 static bool CanCombine(const Geometry& mine, const Geometry& theirs, | |
| 444 const GrXPOverridesForBatch& overrides) { | |
| 445 return true; | |
| 446 } | |
| 447 | |
| 448 static sk_sp<GrGeometryProcessor> MakeGP(const Geometry& geo, | |
| 449 const GrXPOverridesForBatch& over
rides) { | |
| 450 sk_sp<GrGeometryProcessor> gp = | |
| 451 create_fill_rect_gp(geo.fViewMatrix, overrides, | |
| 452 GrDefaultGeoProcFactory::LocalCoords::kHasEx
plicit_Type); | |
| 453 | |
| 454 SkASSERT(overrides.canTweakAlphaForCoverage() ? | |
| 455 gp->getVertexStride() == | |
| 456 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoord
Attr) : | |
| 457 gp->getVertexStride() == | |
| 458 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoord
Coverage)); | |
| 459 return gp; | |
| 460 } | |
| 461 | |
| 462 static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry
& geo, | |
| 463 const GrXPOverridesForBatch& overrides) { | |
| 464 generate_aa_fill_rect_geometry(vertices, vertexStride, | |
| 465 geo.fColor, geo.fViewMatrix, geo.fRect, g
eo.fDevRect, | |
| 466 overrides, &geo.fLocalMatrix); | |
| 467 } | |
| 468 | |
| 469 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} | 356 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} |
| 470 | 357 |
| 471 void onPrepareDraws(Target* target) const override { | 358 void onPrepareDraws(Target* target) const override { |
| 472 sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); | 359 sk_sp<GrGeometryProcessor> gp = |
| 360 create_fill_rect_gp(fGeoData[0].fViewMatrix, fOverrides, |
| 361 GrDefaultGeoProcFactory::LocalCoords::kHasEx
plicit_Type); |
| 473 if (!gp) { | 362 if (!gp) { |
| 474 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 363 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 475 return; | 364 return; |
| 476 } | 365 } |
| 366 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? |
| 367 gp->getVertexStride() == |
| 368 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : |
| 369 gp->getVertexStride() == |
| 370 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage
)); |
| 477 | 371 |
| 478 size_t vertexStride = gp->getVertexStride(); | 372 size_t vertexStride = gp->getVertexStride(); |
| 479 int instanceCount = fGeoData.count(); | 373 int instanceCount = fGeoData.count(); |
| 480 | 374 |
| 481 SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resource
Provider())); | 375 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); |
| 482 InstancedHelper helper; | 376 InstancedHelper helper; |
| 483 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | 377 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
| 484 indexBuffer, kVertsPerInstance, | 378 indexBuffer, kVertsPerAAFillRect, |
| 485 kIndicesPerInstance, instanceCount); | 379 kIndicesPerAAFillRect, instanceCount); |
| 486 if (!vertices || !indexBuffer) { | 380 if (!vertices || !indexBuffer) { |
| 487 SkDebugf("Could not allocate vertices\n"); | 381 SkDebugf("Could not allocate vertices\n"); |
| 488 return; | 382 return; |
| 489 } | 383 } |
| 490 | 384 |
| 491 for (int i = 0; i < instanceCount; i++) { | 385 for (int i = 0; i < instanceCount; i++) { |
| 492 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | 386 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
| 493 i * kVertsPerInstance * vertexStride; | 387 i * kVertsPerAAFillRect * vertexStride; |
| 494 Tesselate(verts, vertexStride, fGeoData[i], fOverrides); | 388 generate_aa_fill_rect_geometry(verts, vertexStride, fGeoData[i].fCol
or, |
| 389 fGeoData[i].fViewMatrix, fGeoData[i].
fRect, |
| 390 fGeoData[i].fDevRect, fOverrides, |
| 391 &fGeoData[i].fLocalMatrix); |
| 495 } | 392 } |
| 496 helper.recordDraw(target, gp.get()); | 393 helper.recordDraw(target, gp.get()); |
| 497 } | 394 } |
| 498 | 395 |
| 499 const Geometry& seedGeometry() const { return fGeoData[0]; } | |
| 500 | |
| 501 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 396 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 502 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>()
; | 397 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>()
; |
| 503 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 398 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 504 that->bounds(), caps)) { | 399 that->bounds(), caps)) { |
| 505 return false; | 400 return false; |
| 506 } | 401 } |
| 507 | 402 |
| 508 if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides))
{ | |
| 509 return false; | |
| 510 } | |
| 511 | |
| 512 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | 403 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 513 // not tweaking | 404 // not tweaking |
| 514 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | 405 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
| 515 fOverrides = that->fOverrides; | 406 fOverrides = that->fOverrides; |
| 516 } | 407 } |
| 517 | 408 |
| 518 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 409 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
| 519 this->joinBounds(that->bounds()); | 410 this->joinBounds(that->bounds()); |
| 520 return true; | 411 return true; |
| 521 } | 412 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { | 490 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { |
| 600 GrColor color = GrRandomColor(random); | 491 GrColor color = GrRandomColor(random); |
| 601 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 492 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
| 602 SkMatrix localMatrix = GrTest::TestMatrix(random); | 493 SkMatrix localMatrix = GrTest::TestMatrix(random); |
| 603 SkRect rect = GrTest::TestRect(random); | 494 SkRect rect = GrTest::TestRect(random); |
| 604 SkRect devRect = GrTest::TestRect(random); | 495 SkRect devRect = GrTest::TestRect(random); |
| 605 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); | 496 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); |
| 606 } | 497 } |
| 607 | 498 |
| 608 #endif | 499 #endif |
| OLD | NEW |