aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2015-08-18 10:16:01 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-08-18 10:16:01 -0700
commit2ad37be2b1f596a163e889ae0282227055c6b661 (patch)
treeadbf98a6d1822b8eadb57d0abc0a0f58583c40b5 /src
parentb2a327094f2b9a072fddfd440481b1c0a8b0bc80 (diff)
Move GrTBatchTesselator to its own file
Diffstat (limited to 'src')
-rw-r--r--src/gpu/batches/GrAAFillRectBatch.cpp143
-rw-r--r--src/gpu/batches/GrTInstanceBatch.h139
2 files changed, 159 insertions, 123 deletions
diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp
index c6eb5ab9ed..8760896604 100644
--- a/src/gpu/batches/GrAAFillRectBatch.cpp
+++ b/src/gpu/batches/GrAAFillRectBatch.cpp
@@ -7,13 +7,12 @@
#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 "GrVertexBatch.h"
#include "SkMatrix.h"
#include "SkRect.h"
@@ -45,123 +44,6 @@ const GrIndexBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
gAAFillRectIndexBufferKey);
}
-/*
- * AAFillRectBatch is templated to optionally allow the insertion of an additional
- * attribute for explicit local coordinates.
- * To use this template, an implementation must define the following static functions:
- * A Geometry struct
- *
- * bool CanCombine(const Geometry& mine, const Geometry& theirs,
- * const GrPipelineOptimizations&)
- *
- * const GrGeometryProcessor* CreateGP(const Geometry& seedGeometry,
- * const GrPipelineOptimizations& opts)
- *
- * Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
- * const GrPipelineOptimizations& opts)
- */
-template <typename Base>
-class AAFillRectBatch : public GrVertexBatch {
-public:
- typedef typename Base::Geometry Geometry;
-
- static AAFillRectBatch* Create() {
- return SkNEW(AAFillRectBatch);
- }
-
- const char* name() const override { return "AAFillRectBatch"; }
-
- void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
- // When this is called on a batch, there is only one geometry bundle
- out->setKnownFourComponents(fGeoData[0].fColor);
- }
-
- void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
- out->setUnknownSingleComponent();
- }
-
- void initBatchTracker(const GrPipelineOptimizations& opt) override {
- opt.getOverrideColorIfSet(&fGeoData[0].fColor);
- fOpts = opt;
- }
-
- SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
-
- // to avoid even the initial copy of the struct, we have a getter for the first item which
- // is used to seed the batch with its initial geometry. After seeding, the client should call
- // init() so the Batch can initialize itself
- Geometry* geometry() { return &fGeoData[0]; }
- void init() {
- const Geometry& geo = fGeoData[0];
- this->setBounds(geo.fDevRect);
- }
-
-private:
- AAFillRectBatch() {
- this->initClassID<AAFillRectBatch<Base>>();
-
- // Push back an initial geometry
- fGeoData.push_back();
- }
-
- void onPrepareDraws(Target* target) override {
- SkAutoTUnref<const GrGeometryProcessor> gp(Base::CreateGP(this->seedGeometry(), fOpts));
- if (!gp) {
- SkDebugf("Couldn't create GrGeometryProcessor\n");
- return;
- }
-
- target->initDraw(gp, this->pipeline());
-
- size_t vertexStride = gp->getVertexStride();
- int instanceCount = fGeoData.count();
-
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(get_index_buffer(target->resourceProvider()));
- InstancedHelper helper;
- void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
- indexBuffer, kVertsPerAAFillRect, kIndicesPerAAFillRect,
- 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 * kVertsPerAAFillRect * vertexStride;
- Base::Tesselate(verts, vertexStride, fGeoData[i], fOpts);
- }
- helper.recordDraw(target);
- }
-
- const Geometry& seedGeometry() const { return fGeoData[0]; }
-
- bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
- AAFillRectBatch* that = t->cast<AAFillRectBatch>();
- if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
- that->bounds(), caps)) {
- return false;
- }
-
- if (!Base::CanCombine(this->seedGeometry(), that->seedGeometry(), fOpts)) {
- return false;
- }
-
- // In the event of two batches, one who can tweak, one who cannot, we just fall back to
- // not tweaking
- if (fOpts.canTweakAlphaForCoverage() && !that->fOpts.canTweakAlphaForCoverage()) {
- fOpts = that->fOpts;
- }
-
- fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
- this->joinBounds(that->bounds());
- return true;
- }
-
- GrPipelineOptimizations fOpts;
- SkSTArray<1, Geometry, true> fGeoData;
-};
-
static const GrGeometryProcessor* create_fill_rect_gp(
const SkMatrix& viewMatrix,
const GrPipelineOptimizations& opts,
@@ -299,7 +181,18 @@ static void generate_aa_fill_rect_geometry(intptr_t verts,
}
}
-class AAFillRectBatchNoLocalMatrixImp {
+// Common functions
+class AAFillRectBatchBase {
+public:
+ static const int kVertsPerInstance = kVertsPerAAFillRect;
+ static const int kIndicesPerInstance = kIndicesPerAAFillRect;
+
+ inline static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* rp) {
+ return get_index_buffer(rp);
+ }
+};
+
+class AAFillRectBatchNoLocalMatrixImp : public AAFillRectBatchBase {
public:
struct Geometry {
SkMatrix fViewMatrix;
@@ -308,6 +201,8 @@ public:
GrColor fColor;
};
+ inline static const char* Name() { return "AAFillRectBatchNoLocalMatrix"; }
+
inline static bool CanCombine(const Geometry& mine, const Geometry& theirs,
const GrPipelineOptimizations& opts) {
// We apply the viewmatrix to the rect points on the cpu. However, if the pipeline uses
@@ -337,7 +232,7 @@ public:
}
};
-class AAFillRectBatchLocalMatrixImp {
+class AAFillRectBatchLocalMatrixImp : public AAFillRectBatchBase {
public:
struct Geometry {
SkMatrix fViewMatrix;
@@ -347,6 +242,8 @@ public:
GrColor fColor;
};
+ inline static const char* Name() { return "AAFillRectBatchLocalMatrix"; }
+
inline static bool CanCombine(const Geometry& mine, const Geometry& theirs,
const GrPipelineOptimizations&) {
return true;
@@ -374,8 +271,8 @@ public:
}
};
-typedef AAFillRectBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalMatrix;
-typedef AAFillRectBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatrix;
+typedef GrTInstanceBatch<AAFillRectBatchNoLocalMatrixImp> AAFillRectBatchNoLocalMatrix;
+typedef GrTInstanceBatch<AAFillRectBatchLocalMatrixImp> AAFillRectBatchLocalMatrix;
namespace GrAAFillRectBatch {
diff --git a/src/gpu/batches/GrTInstanceBatch.h b/src/gpu/batches/GrTInstanceBatch.h
new file mode 100644
index 0000000000..420f873d26
--- /dev/null
+++ b/src/gpu/batches/GrTInstanceBatch.h
@@ -0,0 +1,139 @@
+/*
+ * 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()
+ *
+ * bool CanCombine(const Geometry& mine, const Geometry& theirs,
+ * const GrPipelineOptimizations&)
+ *
+ * const GrGeometryProcessor* CreateGP(const Geometry& seedGeometry,
+ * const GrPipelineOptimizations& opts)
+ *
+ * const GrIndexBuffer* GetIndexBuffer(GrResourceProvider*)
+ *
+ * Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
+ * const GrPipelineOptimizations& opts)
+ */
+template <typename Impl>
+class GrTInstanceBatch : public GrVertexBatch {
+public:
+ typedef typename Impl::Geometry Geometry;
+
+ static GrTInstanceBatch* Create() {
+ return SkNEW(GrTInstanceBatch);
+ }
+
+ const char* name() const override { return Impl::Name(); }
+
+ void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+ // When this is called on a batch, there is only one geometry bundle
+ out->setKnownFourComponents(fGeoData[0].fColor);
+ }
+
+ void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
+ out->setUnknownSingleComponent();
+ }
+
+ void initBatchTracker(const GrPipelineOptimizations& opt) override {
+ opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+ fOpts = opt;
+ }
+
+ SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
+
+ // to avoid even the initial copy of the struct, we have a getter for the first item which
+ // is used to seed the batch with its initial geometry. After seeding, the client should call
+ // init() so the Batch can initialize itself
+ Geometry* geometry() { return &fGeoData[0]; }
+ void init() {
+ const Geometry& geo = fGeoData[0];
+ this->setBounds(geo.fDevRect);
+ }
+
+private:
+ GrTInstanceBatch() {
+ this->initClassID<GrTInstanceBatch<Impl>>();
+
+ // Push back an initial geometry
+ fGeoData.push_back();
+ }
+
+ void onPrepareDraws(Target* target) override {
+ SkAutoTUnref<const GrGeometryProcessor> gp(Impl::CreateGP(this->seedGeometry(), fOpts));
+ if (!gp) {
+ SkDebugf("Couldn't create GrGeometryProcessor\n");
+ return;
+ }
+
+ target->initDraw(gp, this->pipeline());
+
+ size_t vertexStride = gp->getVertexStride();
+ int instanceCount = fGeoData.count();
+
+ SkAutoTUnref<const GrIndexBuffer> 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<intptr_t>(vertices) +
+ i * Impl::kVertsPerInstance * vertexStride;
+ Impl::Tesselate(verts, vertexStride, fGeoData[i], fOpts);
+ }
+ helper.recordDraw(target);
+ }
+
+ const Geometry& seedGeometry() const { return fGeoData[0]; }
+
+ bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
+ GrTInstanceBatch* that = t->cast<GrTInstanceBatch>();
+ if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
+ that->bounds(), caps)) {
+ return false;
+ }
+
+ if (!Impl::CanCombine(this->seedGeometry(), that->seedGeometry(), fOpts)) {
+ return false;
+ }
+
+ // In the event of two batches, one who can tweak, one who cannot, we just fall back to
+ // not tweaking
+ if (fOpts.canTweakAlphaForCoverage() && !that->fOpts.canTweakAlphaForCoverage()) {
+ fOpts = that->fOpts;
+ }
+
+ fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
+ this->joinBounds(that->bounds());
+ return true;
+ }
+
+ GrPipelineOptimizations fOpts;
+ SkSTArray<1, Geometry, true> fGeoData;
+};
+
+#endif