Index: src/gpu/batches/GrAAFillRectBatch.cpp |
diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp |
index 94cef02a1a7f7156102ca8a029db2e10513dbaf0..b2a3de9ee8da06b84d43c6e2c830d73dc63130ff 100644 |
--- a/src/gpu/batches/GrAAFillRectBatch.cpp |
+++ b/src/gpu/batches/GrAAFillRectBatch.cpp |
@@ -7,14 +7,15 @@ |
#include "GrAAFillRectBatch.h" |
+#include "GrBatchFlushState.h" |
#include "GrColor.h" |
#include "GrDefaultGeoProcFactory.h" |
#include "GrResourceKey.h" |
#include "GrResourceProvider.h" |
-#include "GrTInstanceBatch.h" |
#include "GrTypes.h" |
#include "SkMatrix.h" |
#include "SkRect.h" |
+#include "GrVertexBatch.h" |
GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); |
@@ -186,9 +187,58 @@ static void generate_aa_fill_rect_geometry(intptr_t verts, |
} |
} |
-// Common functions |
-class AAFillRectBatchBase { |
+class AAFillRectNoLocalMatrixBatch : public GrVertexBatch { |
public: |
+ DEFINE_BATCH_CLASS_ID |
+ |
+ struct Geometry { |
+ SkMatrix fViewMatrix; |
+ SkRect fRect; |
+ SkRect fDevRect; |
+ GrColor fColor; |
+ }; |
+ |
+ static AAFillRectNoLocalMatrixBatch* Create() { return new AAFillRectNoLocalMatrixBatch; } |
+ |
robertphillips
2016/06/30 19:22:16
rm Name too ?
|
+ const char* name() const override { return Name(); } |
+ |
+ SkString dumpInfo() const override { |
+ SkString str; |
+ str.appendf("# batched: %d\n", fGeoData.count()); |
+ for (int i = 0; i < fGeoData.count(); ++i) { |
+ str.append(DumpInfo(fGeoData[i], i)); |
+ } |
+ str.append(INHERITED::dumpInfo()); |
+ return str; |
+ } |
+ |
+ void computePipelineOptimizations(GrInitInvariantOutput* color, |
+ GrInitInvariantOutput* coverage, |
+ GrBatchToXPOverrides* overrides) const override { |
+ // When this is called on a batch, there is only one geometry bundle |
+ color->setKnownFourComponents(fGeoData[0].fColor); |
robertphillips
2016/06/30 19:22:16
rm InitInvariantOutput ?
|
+ InitInvariantOutputCoverage(coverage); |
+ } |
+ |
+ void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
+ overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
+ fOverrides = overrides; |
+ } |
+ |
+ SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
+ |
+ // After seeding, the client should call init() so the Batch can initialize itself |
+ void init() { |
+ const Geometry& geo = fGeoData[0]; |
robertphillips
2016/06/30 19:22:16
fold this in ?
|
+ SetBounds(geo, &fBounds); |
+ } |
+ |
+ void updateBoundsAfterAppend() { |
+ const Geometry& geo = fGeoData.back(); |
robertphillips
2016/06/30 19:22:16
this too ?
|
+ UpdateBoundsAfterAppend(geo, &fBounds); |
+ } |
+ |
+private: |
static const int kVertsPerInstance = kVertsPerAAFillRect; |
static const int kIndicesPerInstance = kIndicesPerAAFillRect; |
@@ -200,25 +250,13 @@ public: |
return get_index_buffer(rp); |
} |
- template <class Geometry> |
static void SetBounds(const Geometry& geo, SkRect* outBounds) { |
*outBounds = geo.fDevRect; |
} |
- template <class Geometry> |
static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds) { |
outBounds->join(geo.fDevRect); |
} |
-}; |
- |
-class AAFillRectBatchNoLocalMatrixImp : public AAFillRectBatchBase { |
-public: |
- struct Geometry { |
- SkMatrix fViewMatrix; |
- SkRect fRect; |
- SkRect fDevRect; |
- GrColor fColor; |
- }; |
static const char* Name() { return "AAFillRectBatchNoLocalMatrix"; } |
@@ -240,7 +278,7 @@ public: |
} |
static sk_sp<GrGeometryProcessor> MakeGP(const Geometry& geo, |
- const GrXPOverridesForBatch& overrides) { |
+ const GrXPOverridesForBatch& overrides) { |
sk_sp<GrGeometryProcessor> gp = |
create_fill_rect_gp(geo.fViewMatrix, overrides, |
GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type); |
@@ -258,10 +296,71 @@ public: |
geo.fColor, geo.fViewMatrix, geo.fRect, geo.fDevRect, |
overrides, nullptr); |
} |
+ |
+ AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} |
+ |
+ void onPrepareDraws(Target* target) const override { |
+ sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); |
+ if (!gp) { |
+ SkDebugf("Couldn't create GrGeometryProcessor\n"); |
+ return; |
+ } |
+ |
+ size_t vertexStride = gp->getVertexStride(); |
+ int instanceCount = fGeoData.count(); |
+ |
+ SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resourceProvider())); |
+ InstancedHelper helper; |
+ void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, |
+ indexBuffer, kVertsPerInstance, |
+ kIndicesPerInstance, instanceCount); |
+ if (!vertices || !indexBuffer) { |
+ SkDebugf("Could not allocate vertices\n"); |
+ return; |
+ } |
+ |
+ for (int i = 0; i < instanceCount; i++) { |
+ intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
+ i * kVertsPerInstance * vertexStride; |
robertphillips
2016/06/30 19:22:16
rm Tesselate ?
|
+ Tesselate(verts, vertexStride, fGeoData[i], fOverrides); |
+ } |
+ helper.recordDraw(target, gp.get()); |
+ } |
+ |
+ const Geometry& seedGeometry() const { return fGeoData[0]; } |
+ |
+ bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
+ AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatch>(); |
+ if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), |
+ that->bounds(), caps)) { |
+ return false; |
+ } |
+ |
+ if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides)) { |
+ return false; |
+ } |
+ |
+ // In the event of two batches, one who can tweak, one who cannot, we just fall back to |
+ // not tweaking |
+ if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) { |
+ fOverrides = that->fOverrides; |
+ } |
+ |
+ fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); |
+ this->joinBounds(that->bounds()); |
+ return true; |
+ } |
+ |
+ GrXPOverridesForBatch fOverrides; |
+ SkSTArray<1, Geometry, true> fGeoData; |
+ |
+ typedef GrVertexBatch INHERITED; |
}; |
-class AAFillRectBatchLocalMatrixImp : public AAFillRectBatchBase { |
+class AAFillRectLocalMatrixBatch : public GrVertexBatch { |
public: |
+ DEFINE_BATCH_CLASS_ID |
+ |
struct Geometry { |
SkMatrix fViewMatrix; |
SkMatrix fLocalMatrix; |
@@ -270,6 +369,66 @@ public: |
GrColor fColor; |
}; |
+ static AAFillRectLocalMatrixBatch* Create() { return new AAFillRectLocalMatrixBatch; } |
+ |
robertphillips
2016/06/30 19:22:16
same here
|
+ const char* name() const override { return Name(); } |
+ |
+ SkString dumpInfo() const override { |
+ SkString str; |
+ str.appendf("# batched: %d\n", fGeoData.count()); |
+ for (int i = 0; i < fGeoData.count(); ++i) { |
+ str.append(DumpInfo(fGeoData[i], i)); |
+ } |
+ str.append(INHERITED::dumpInfo()); |
+ return str; |
+ } |
+ |
+ void computePipelineOptimizations(GrInitInvariantOutput* color, |
+ GrInitInvariantOutput* coverage, |
+ GrBatchToXPOverrides* overrides) const override { |
+ // When this is called on a batch, there is only one geometry bundle |
+ color->setKnownFourComponents(fGeoData[0].fColor); |
robertphillips
2016/06/30 19:22:16
rm InitInvariantOutput ?
|
+ InitInvariantOutputCoverage(coverage); |
+ } |
+ |
+ void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
+ overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
+ fOverrides = overrides; |
+ } |
+ |
+ SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
+ |
+ // After seeding, the client should call init() so the Batch can initialize itself |
+ void init() { |
+ const Geometry& geo = fGeoData[0]; |
+ SetBounds(geo, &fBounds); |
+ } |
+ |
+ void updateBoundsAfterAppend() { |
+ const Geometry& geo = fGeoData.back(); |
+ UpdateBoundsAfterAppend(geo, &fBounds); |
+ } |
+ |
+private: |
+ static const int kVertsPerInstance = kVertsPerAAFillRect; |
+ static const int kIndicesPerInstance = kIndicesPerAAFillRect; |
+ |
+ static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { |
+ out->setUnknownSingleComponent(); |
+ } |
+ |
+ static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { |
+ return get_index_buffer(rp); |
+ } |
+ |
+ static void SetBounds(const Geometry& geo, SkRect* outBounds) { |
+ *outBounds = geo.fDevRect; |
+ } |
+ |
+ static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds) { |
+ outBounds->join(geo.fDevRect); |
+ } |
+ |
static const char* Name() { return "AAFillRectBatchLocalMatrix"; } |
static SkString DumpInfo(const Geometry& geo, int index) { |
@@ -306,25 +465,81 @@ public: |
geo.fColor, geo.fViewMatrix, geo.fRect, geo.fDevRect, |
overrides, &geo.fLocalMatrix); |
} |
-}; |
-typedef GrTInstanceBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalMatrix; |
-typedef GrTInstanceBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatrix; |
+ AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} |
+ |
+ void onPrepareDraws(Target* target) const override { |
+ sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); |
+ if (!gp) { |
+ SkDebugf("Couldn't create GrGeometryProcessor\n"); |
+ return; |
+ } |
+ |
+ size_t vertexStride = gp->getVertexStride(); |
+ int instanceCount = fGeoData.count(); |
+ |
+ SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resourceProvider())); |
+ InstancedHelper helper; |
+ void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, |
+ indexBuffer, kVertsPerInstance, |
+ kIndicesPerInstance, instanceCount); |
+ if (!vertices || !indexBuffer) { |
+ SkDebugf("Could not allocate vertices\n"); |
+ return; |
+ } |
+ |
+ for (int i = 0; i < instanceCount; i++) { |
+ intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
+ i * kVertsPerInstance * vertexStride; |
robertphillips
2016/06/30 19:22:16
rm Tesselate here too ?
|
+ Tesselate(verts, vertexStride, fGeoData[i], fOverrides); |
+ } |
+ helper.recordDraw(target, gp.get()); |
+ } |
+ |
+ const Geometry& seedGeometry() const { return fGeoData[0]; } |
+ |
+ bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
+ AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>(); |
+ if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), |
+ that->bounds(), caps)) { |
+ return false; |
+ } |
+ |
+ if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides)) { |
+ return false; |
+ } |
+ |
+ // In the event of two batches, one who can tweak, one who cannot, we just fall back to |
+ // not tweaking |
+ if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) { |
+ fOverrides = that->fOverrides; |
+ } |
+ |
+ fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); |
+ this->joinBounds(that->bounds()); |
+ return true; |
+ } |
+ |
+ GrXPOverridesForBatch fOverrides; |
+ SkSTArray<1, Geometry, true> fGeoData; |
+ |
+ typedef GrVertexBatch INHERITED; |
+}; |
-inline static void append_to_batch(AAFillRectBatchNoLocalMatrix* batch, GrColor color, |
+inline static void append_to_batch(AAFillRectNoLocalMatrixBatch* batch, GrColor color, |
const SkMatrix& viewMatrix, const SkRect& rect, |
const SkRect& devRect) { |
- AAFillRectBatchNoLocalMatrix::Geometry& geo = batch->geoData()->push_back(); |
+ AAFillRectNoLocalMatrixBatch::Geometry& geo = batch->geoData()->push_back(); |
geo.fColor = color; |
geo.fViewMatrix = viewMatrix; |
geo.fRect = rect; |
geo.fDevRect = devRect; |
} |
-inline static void append_to_batch(AAFillRectBatchLocalMatrix* batch, GrColor color, |
+inline static void append_to_batch(AAFillRectLocalMatrixBatch* batch, GrColor color, |
const SkMatrix& viewMatrix, const SkMatrix& localMatrix, |
const SkRect& rect, const SkRect& devRect) { |
- AAFillRectBatchLocalMatrix::Geometry& geo = batch->geoData()->push_back(); |
+ AAFillRectLocalMatrixBatch::Geometry& geo = batch->geoData()->push_back(); |
geo.fColor = color; |
geo.fViewMatrix = viewMatrix; |
geo.fLocalMatrix = localMatrix; |
@@ -338,7 +553,7 @@ GrDrawBatch* Create(GrColor color, |
const SkMatrix& viewMatrix, |
const SkRect& rect, |
const SkRect& devRect) { |
- AAFillRectBatchNoLocalMatrix* batch = AAFillRectBatchNoLocalMatrix::Create(); |
+ AAFillRectNoLocalMatrixBatch* batch = AAFillRectNoLocalMatrixBatch::Create(); |
append_to_batch(batch, color, viewMatrix, rect, devRect); |
batch->init(); |
return batch; |
@@ -349,7 +564,7 @@ GrDrawBatch* Create(GrColor color, |
const SkMatrix& localMatrix, |
const SkRect& rect, |
const SkRect& devRect) { |
- AAFillRectBatchLocalMatrix* batch = AAFillRectBatchLocalMatrix::Create(); |
+ AAFillRectLocalMatrixBatch* batch = AAFillRectLocalMatrixBatch::Create(); |
append_to_batch(batch, color, viewMatrix, localMatrix, rect, devRect); |
batch->init(); |
return batch; |
@@ -382,7 +597,7 @@ void Append(GrBatch* origBatch, |
const SkMatrix& viewMatrix, |
const SkRect& rect, |
const SkRect& devRect) { |
- AAFillRectBatchNoLocalMatrix* batch = origBatch->cast<AAFillRectBatchNoLocalMatrix>(); |
+ AAFillRectNoLocalMatrixBatch* batch = origBatch->cast<AAFillRectNoLocalMatrixBatch>(); |
append_to_batch(batch, color, viewMatrix, rect, devRect); |
batch->updateBoundsAfterAppend(); |
} |
@@ -393,7 +608,7 @@ void Append(GrBatch* origBatch, |
const SkMatrix& localMatrix, |
const SkRect& rect, |
const SkRect& devRect) { |
- AAFillRectBatchLocalMatrix* batch = origBatch->cast<AAFillRectBatchLocalMatrix>(); |
+ AAFillRectLocalMatrixBatch* batch = origBatch->cast<AAFillRectLocalMatrixBatch>(); |
append_to_batch(batch, color, viewMatrix, localMatrix, rect, devRect); |
batch->updateBoundsAfterAppend(); |
} |