From 08d141534cb24a491edbf5db31cdc7b966ec8d72 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Thu, 30 Jun 2016 12:45:18 -0700 Subject: [PATCH] Remove GrTInstanceBatch BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2114663003 Review-Url: https://codereview.chromium.org/2114663003 --- gyp/gpu.gypi | 1 - src/gpu/batches/GrAAFillRectBatch.cpp | 271 ++++++++++++++++++++++++--- src/gpu/batches/GrNonAAFillRectBatch.cpp | 303 ++++++++++++++++++++++++++----- src/gpu/batches/GrTInstanceBatch.h | 151 --------------- 4 files changed, 500 insertions(+), 226 deletions(-) delete mode 100644 src/gpu/batches/GrTInstanceBatch.h diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index c9e206f..2660b2f 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -260,7 +260,6 @@ '<(skia_src_path)/gpu/batches/GrStencilPathBatch.h', '<(skia_src_path)/gpu/batches/GrTessellatingPathRenderer.cpp', '<(skia_src_path)/gpu/batches/GrTessellatingPathRenderer.h', - '<(skia_src_path)/gpu/batches/GrTInstanceBatch.h', '<(skia_src_path)/gpu/batches/GrVertexBatch.cpp', '<(skia_src_path)/gpu/batches/GrVertexBatch.h', diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp index 94cef02..b2a3de9 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; } + + 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); + 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; @@ -200,25 +250,13 @@ public: return get_index_buffer(rp); } - template static void SetBounds(const Geometry& geo, SkRect* outBounds) { *outBounds = geo.fDevRect; } - template 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 MakeGP(const Geometry& geo, - const GrXPOverridesForBatch& overrides) { + const GrXPOverridesForBatch& overrides) { sk_sp 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 gp(MakeGP(this->seedGeometry(), fOverrides)); + if (!gp) { + SkDebugf("Couldn't create GrGeometryProcessor\n"); + return; + } + + size_t vertexStride = gp->getVertexStride(); + int instanceCount = fGeoData.count(); + + SkAutoTUnref 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(vertices) + + i * kVertsPerInstance * vertexStride; + 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(); + 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; } + + 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); + 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 AAFillRectBatchNoLocalMatrix; -typedef GrTInstanceBatch AAFillRectBatchLocalMatrix; + AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} + + void onPrepareDraws(Target* target) const override { + sk_sp gp(MakeGP(this->seedGeometry(), fOverrides)); + if (!gp) { + SkDebugf("Couldn't create GrGeometryProcessor\n"); + return; + } + + size_t vertexStride = gp->getVertexStride(); + int instanceCount = fGeoData.count(); + + SkAutoTUnref 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(vertices) + + i * kVertsPerInstance * vertexStride; + 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(); + 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(); + AAFillRectNoLocalMatrixBatch* batch = origBatch->cast(); 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(); + AAFillRectLocalMatrixBatch* batch = origBatch->cast(); append_to_batch(batch, color, viewMatrix, localMatrix, rect, devRect); batch->updateBoundsAfterAppend(); } diff --git a/src/gpu/batches/GrNonAAFillRectBatch.cpp b/src/gpu/batches/GrNonAAFillRectBatch.cpp index 3b4c5da..186c935 100644 --- a/src/gpu/batches/GrNonAAFillRectBatch.cpp +++ b/src/gpu/batches/GrNonAAFillRectBatch.cpp @@ -12,36 +12,11 @@ #include "GrDefaultGeoProcFactory.h" #include "GrPrimitiveProcessor.h" #include "GrResourceProvider.h" -#include "GrTInstanceBatch.h" #include "GrQuad.h" #include "GrVertexBatch.h" -// Common functions -class NonAAFillRectBatchBase { -public: - static const int kVertsPerInstance = 4; - static const int kIndicesPerInstance = 6; - - static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { - out->setKnownSingleComponent(0xff); - } - - static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { - return rp->refQuadIndexBuffer(); - } - - template - static void SetBounds(const Geometry& geo, SkRect* outBounds) { - geo.fViewMatrix.mapRect(outBounds, geo.fRect); - } - - template - static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds) { - SkRect bounds = geo.fRect; - geo.fViewMatrix.mapRect(&bounds); - outBounds->join(bounds); - } -}; +static const int kVertsPerInstance = 4; +static const int kIndicesPerInstance = 6; /** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we have explicit local coords and sometimes not. We *could* always provide explicit local @@ -90,15 +65,14 @@ static void tesselate(intptr_t vertices, rect.fRight, rect.fBottom, vertexStride); if (!viewMatrix.hasPerspective()) { - viewMatrix.mapPointsWithStride(positions, vertexStride, - NonAAFillRectBatchBase::kVertsPerInstance); + viewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerInstance); } // Setup local coords // TODO we should only do this if local coords are being read if (localQuad) { static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); - for (int i = 0; i < NonAAFillRectBatchBase::kVertsPerInstance; i++) { + for (int i = 0; i < kVertsPerInstance; i++) { SkPoint* coords = reinterpret_cast(vertices + kLocalOffset + i * vertexStride); *coords = localQuad->point(i); @@ -113,8 +87,10 @@ static void tesselate(intptr_t vertices, } } -class NonAAFillRectBatchImp : public NonAAFillRectBatchBase { +class NonAAFillRectBatch : public GrVertexBatch { public: + DEFINE_BATCH_CLASS_ID + struct Geometry { SkMatrix fViewMatrix; SkRect fRect; @@ -122,6 +98,47 @@ public: GrColor fColor; }; + static NonAAFillRectBatch* Create() { return new NonAAFillRectBatch; } + + 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); + 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 char* Name() { return "NonAAFillRectBatch"; } static SkString DumpInfo(const Geometry& geo, int index) { @@ -152,11 +169,90 @@ public: const GrXPOverridesForBatch& overrides) { tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect, &geo.fLocalQuad); } + + static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { + out->setKnownSingleComponent(0xff); + } + + static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { + return rp->refQuadIndexBuffer(); + } + + static void SetBounds(const Geometry& geo, SkRect* outBounds) { + geo.fViewMatrix.mapRect(outBounds, geo.fRect); + } + + static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds) { + SkRect bounds = geo.fRect; + geo.fViewMatrix.mapRect(&bounds); + outBounds->join(bounds); + } + + NonAAFillRectBatch() : INHERITED(ClassID()) {} + + void onPrepareDraws(Target* target) const override { + sk_sp gp(MakeGP(this->seedGeometry(), fOverrides)); + if (!gp) { + SkDebugf("Couldn't create GrGeometryProcessor\n"); + return; + } + + size_t vertexStride = gp->getVertexStride(); + int instanceCount = fGeoData.count(); + + SkAutoTUnref 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(vertices) + + i * kVertsPerInstance * vertexStride; + 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 { + NonAAFillRectBatch* that = t->cast(); + 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; }; // We handle perspective in the local matrix or viewmatrix with special batches -class NonAAFillRectBatchPerspectiveImp : public NonAAFillRectBatchBase { +class NonAAFillRectPerspectiveBatch : public GrVertexBatch { public: + DEFINE_BATCH_CLASS_ID + struct Geometry { SkMatrix fViewMatrix; SkMatrix fLocalMatrix; @@ -167,7 +263,48 @@ public: bool fHasLocalRect; }; - static const char* Name() { return "NonAAFillRectBatchPerspective"; } + static NonAAFillRectPerspectiveBatch* Create() { return new NonAAFillRectPerspectiveBatch; } + + 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); + 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 char* Name() { return "NonAAFillRectPerspectiveBatch"; } static SkString DumpInfo(const Geometry& geo, int index) { SkString str; @@ -208,16 +345,90 @@ public: tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect, nullptr); } } -}; -typedef GrTInstanceBatch NonAAFillRectBatchSimple; -typedef GrTInstanceBatch NonAAFillRectBatchPerspective; + static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { + out->setKnownSingleComponent(0xff); + } + + static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { + return rp->refQuadIndexBuffer(); + } + + static void SetBounds(const Geometry& geo, SkRect* outBounds) { + geo.fViewMatrix.mapRect(outBounds, geo.fRect); + } + + static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds) { + SkRect bounds = geo.fRect; + geo.fViewMatrix.mapRect(&bounds); + outBounds->join(bounds); + } + + NonAAFillRectPerspectiveBatch() : INHERITED(ClassID()) {} + + void onPrepareDraws(Target* target) const override { + sk_sp gp(MakeGP(this->seedGeometry(), fOverrides)); + if (!gp) { + SkDebugf("Couldn't create GrGeometryProcessor\n"); + return; + } + + size_t vertexStride = gp->getVertexStride(); + int instanceCount = fGeoData.count(); + + SkAutoTUnref 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(vertices) + + i * kVertsPerInstance * vertexStride; + 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 { + NonAAFillRectPerspectiveBatch* that = t->cast(); + 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(NonAAFillRectBatchSimple* batch, GrColor color, +inline static void append_to_batch(NonAAFillRectBatch* batch, GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective())); - NonAAFillRectBatchSimple::Geometry& geo = batch->geoData()->push_back(); + NonAAFillRectBatch::Geometry& geo = batch->geoData()->push_back(); geo.fColor = color; geo.fViewMatrix = viewMatrix; @@ -234,11 +445,11 @@ inline static void append_to_batch(NonAAFillRectBatchSimple* batch, GrColor colo } } -inline static void append_to_batch(NonAAFillRectBatchPerspective* batch, GrColor color, +inline static void append_to_batch(NonAAFillRectPerspectiveBatch* batch, GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())); - NonAAFillRectBatchPerspective::Geometry& geo = batch->geoData()->push_back(); + NonAAFillRectPerspectiveBatch::Geometry& geo = batch->geoData()->push_back(); geo.fColor = color; geo.fViewMatrix = viewMatrix; @@ -261,7 +472,7 @@ GrDrawBatch* Create(GrColor color, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { - NonAAFillRectBatchSimple* batch = NonAAFillRectBatchSimple::Create(); + NonAAFillRectBatch* batch = NonAAFillRectBatch::Create(); append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); batch->init(); return batch; @@ -272,7 +483,7 @@ GrDrawBatch* CreateWithPerspective(GrColor color, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { - NonAAFillRectBatchPerspective* batch = NonAAFillRectBatchPerspective::Create(); + NonAAFillRectPerspectiveBatch* batch = NonAAFillRectPerspectiveBatch::Create(); append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); batch->init(); return batch; @@ -287,17 +498,17 @@ bool Append(GrBatch* origBatch, bool usePerspective = viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()); - if (usePerspective && origBatch->classID() != NonAAFillRectBatchPerspective::ClassID()) { + if (usePerspective && origBatch->classID() != NonAAFillRectPerspectiveBatch::ClassID()) { return false; } if (!usePerspective) { - NonAAFillRectBatchSimple* batch = origBatch->cast(); + NonAAFillRectBatch* batch = origBatch->cast(); append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); batch->updateBoundsAfterAppend(); } else { - NonAAFillRectBatchPerspective* batch = origBatch->cast(); - const NonAAFillRectBatchPerspective::Geometry& geo = batch->geoData()->back(); + NonAAFillRectPerspectiveBatch* batch = origBatch->cast(); + const NonAAFillRectPerspectiveBatch::Geometry& geo = batch->geoData()->back(); if (!geo.fViewMatrix.cheapEqualTo(viewMatrix) || geo.fHasLocalRect != SkToBool(localRect) || diff --git a/src/gpu/batches/GrTInstanceBatch.h b/src/gpu/batches/GrTInstanceBatch.h deleted file mode 100644 index e63f2e5..0000000 --- a/src/gpu/batches/GrTInstanceBatch.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrTInstanceBatch_DEFINED -#define GrTInstanceBatch_DEFINED - -#include "GrVertexBatch.h" - -#include "GrBatchFlushState.h" - -/** - * GrTInstanceBatch is an optional template to help with writing batches - * To use this template, The 'Impl' must define the following statics: - * A Geometry struct - * - * static const int kVertsPerInstance - * static const int kIndicesPerInstance - * - * const char* Name() - * - * void InvariantOutputCoverage(GrInitInvariantOutput* out) - * - * void SetBounds(const Geometry& seedGeometry, SkRect* outBounds) - * - * void UpdateBoundsAfterAppend(const Geometry& lastGeometry, SkRect* currentBounds) - * - * bool CanCombine(const Geometry& mine, const Geometry& theirs, - * const GrXPOverridesForBatch&) - * - * const GrGeometryProcessor* CreateGP(const Geometry& seedGeometry, - * const GrXPOverridesForBatch& overrides) - * - * const GrBuffer* GetIndexBuffer(GrResourceProvider*) - * - * Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo, - * const GrXPOverridesForBatch& overrides) - */ -template -class GrTInstanceBatch : public GrVertexBatch { -public: - DEFINE_BATCH_CLASS_ID - - typedef typename Impl::Geometry Geometry; - - static GrTInstanceBatch* Create() { return new GrTInstanceBatch; } - - const char* name() const override { return Impl::Name(); } - - SkString dumpInfo() const override { - SkString str; - str.appendf("# batched: %d\n", fGeoData.count()); - for (int i = 0; i < fGeoData.count(); ++i) { - str.append(Impl::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); - Impl::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]; - Impl::SetBounds(geo, &fBounds); - } - - void updateBoundsAfterAppend() { - const Geometry& geo = fGeoData.back(); - Impl::UpdateBoundsAfterAppend(geo, &fBounds); - } - -private: - GrTInstanceBatch() : INHERITED(ClassID()) {} - - void onPrepareDraws(Target* target) const override { - sk_sp gp(Impl::MakeGP(this->seedGeometry(), fOverrides)); - if (!gp) { - SkDebugf("Couldn't create GrGeometryProcessor\n"); - return; - } - - size_t vertexStride = gp->getVertexStride(); - int instanceCount = fGeoData.count(); - - SkAutoTUnref indexBuffer( - Impl::GetIndexBuffer(target->resourceProvider())); - InstancedHelper helper; - void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, - indexBuffer, Impl::kVertsPerInstance, - Impl::kIndicesPerInstance, instanceCount); - if (!vertices || !indexBuffer) { - SkDebugf("Could not allocate vertices\n"); - return; - } - - for (int i = 0; i < instanceCount; i++) { - intptr_t verts = reinterpret_cast(vertices) + - i * Impl::kVertsPerInstance * vertexStride; - Impl::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 { - GrTInstanceBatch* that = t->cast(); - if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), - that->bounds(), caps)) { - return false; - } - - if (!Impl::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; -}; - -#endif -- 2.7.4