12ad37be2b1f596a163e889ae0282227055c6b661joshualitt/* 22ad37be2b1f596a163e889ae0282227055c6b661joshualitt * Copyright 2015 Google Inc. 32ad37be2b1f596a163e889ae0282227055c6b661joshualitt * 42ad37be2b1f596a163e889ae0282227055c6b661joshualitt * Use of this source code is governed by a BSD-style license that can be 52ad37be2b1f596a163e889ae0282227055c6b661joshualitt * found in the LICENSE file. 62ad37be2b1f596a163e889ae0282227055c6b661joshualitt */ 72ad37be2b1f596a163e889ae0282227055c6b661joshualitt 82ad37be2b1f596a163e889ae0282227055c6b661joshualitt#ifndef GrTInstanceBatch_DEFINED 92ad37be2b1f596a163e889ae0282227055c6b661joshualitt#define GrTInstanceBatch_DEFINED 102ad37be2b1f596a163e889ae0282227055c6b661joshualitt 112ad37be2b1f596a163e889ae0282227055c6b661joshualitt#include "GrVertexBatch.h" 122ad37be2b1f596a163e889ae0282227055c6b661joshualitt 132ad37be2b1f596a163e889ae0282227055c6b661joshualitt#include "GrBatchFlushState.h" 142ad37be2b1f596a163e889ae0282227055c6b661joshualitt 152ad37be2b1f596a163e889ae0282227055c6b661joshualitt/** 162ad37be2b1f596a163e889ae0282227055c6b661joshualitt * GrTInstanceBatch is an optional template to help with writing batches 172ad37be2b1f596a163e889ae0282227055c6b661joshualitt * To use this template, The 'Impl' must define the following statics: 182ad37be2b1f596a163e889ae0282227055c6b661joshualitt * A Geometry struct 192ad37be2b1f596a163e889ae0282227055c6b661joshualitt * 202ad37be2b1f596a163e889ae0282227055c6b661joshualitt * static const int kVertsPerInstance 212ad37be2b1f596a163e889ae0282227055c6b661joshualitt * static const int kIndicesPerInstance 222ad37be2b1f596a163e889ae0282227055c6b661joshualitt * 232ad37be2b1f596a163e889ae0282227055c6b661joshualitt * const char* Name() 242ad37be2b1f596a163e889ae0282227055c6b661joshualitt * 252244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt * void InvariantOutputCoverage(GrInitInvariantOutput* out) 262244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt * 272244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt * void SetBounds(const Geometry& seedGeometry, SkRect* outBounds) 282244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt * 29aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt * void UpdateBoundsAfterAppend(const Geometry& lastGeometry, SkRect* currentBounds) 30aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt * 312ad37be2b1f596a163e889ae0282227055c6b661joshualitt * bool CanCombine(const Geometry& mine, const Geometry& theirs, 32ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas * const GrXPOverridesForBatch&) 332ad37be2b1f596a163e889ae0282227055c6b661joshualitt * 342ad37be2b1f596a163e889ae0282227055c6b661joshualitt * const GrGeometryProcessor* CreateGP(const Geometry& seedGeometry, 35ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas * const GrXPOverridesForBatch& overrides) 362ad37be2b1f596a163e889ae0282227055c6b661joshualitt * 372ad37be2b1f596a163e889ae0282227055c6b661joshualitt * const GrIndexBuffer* GetIndexBuffer(GrResourceProvider*) 382ad37be2b1f596a163e889ae0282227055c6b661joshualitt * 392ad37be2b1f596a163e889ae0282227055c6b661joshualitt * Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo, 40ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas * const GrXPOverridesForBatch& overrides) 412ad37be2b1f596a163e889ae0282227055c6b661joshualitt */ 422ad37be2b1f596a163e889ae0282227055c6b661joshualitttemplate <typename Impl> 432ad37be2b1f596a163e889ae0282227055c6b661joshualittclass GrTInstanceBatch : public GrVertexBatch { 442ad37be2b1f596a163e889ae0282227055c6b661joshualittpublic: 451b55a963a2374a14bb82eb887bb99ee91680f0ebreed DEFINE_BATCH_CLASS_ID 461b55a963a2374a14bb82eb887bb99ee91680f0ebreed 472ad37be2b1f596a163e889ae0282227055c6b661joshualitt typedef typename Impl::Geometry Geometry; 482ad37be2b1f596a163e889ae0282227055c6b661joshualitt 49385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary static GrTInstanceBatch* Create() { return new GrTInstanceBatch; } 502ad37be2b1f596a163e889ae0282227055c6b661joshualitt 512ad37be2b1f596a163e889ae0282227055c6b661joshualitt const char* name() const override { return Impl::Name(); } 522ad37be2b1f596a163e889ae0282227055c6b661joshualitt 53e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips SkString dumpInfo() const override { 54e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips SkString str; 55e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips for (int i = 0; i < fGeoData.count(); ++i) { 56783a4da10ba08187a5029d74cfa1507ac1b13307robertphillips str.append(Impl::DumpInfo(fGeoData[i], i)); 57e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips } 58e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips str.append(INHERITED::dumpInfo()); 59e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips return str; 60e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips } 61e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips 62ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas void computePipelineOptimizations(GrInitInvariantOutput* color, 63ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrInitInvariantOutput* coverage, 64ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrBatchToXPOverrides* overrides) const override { 652ad37be2b1f596a163e889ae0282227055c6b661joshualitt // When this is called on a batch, there is only one geometry bundle 66ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas color->setKnownFourComponents(fGeoData[0].fColor); 67ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas Impl::InitInvariantOutputCoverage(coverage); 682ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 692ad37be2b1f596a163e889ae0282227055c6b661joshualitt 70ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 71ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 72ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas fOverrides = overrides; 732ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 742ad37be2b1f596a163e889ae0282227055c6b661joshualitt 752ad37be2b1f596a163e889ae0282227055c6b661joshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 762ad37be2b1f596a163e889ae0282227055c6b661joshualitt 77aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt // After seeding, the client should call init() so the Batch can initialize itself 782ad37be2b1f596a163e889ae0282227055c6b661joshualitt void init() { 792ad37be2b1f596a163e889ae0282227055c6b661joshualitt const Geometry& geo = fGeoData[0]; 802244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt Impl::SetBounds(geo, &fBounds); 812ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 822ad37be2b1f596a163e889ae0282227055c6b661joshualitt 83aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt void updateBoundsAfterAppend() { 84aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const Geometry& geo = fGeoData.back(); 85aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt Impl::UpdateBoundsAfterAppend(geo, &fBounds); 862ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 872ad37be2b1f596a163e889ae0282227055c6b661joshualitt 88aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualittprivate: 89aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt GrTInstanceBatch() : INHERITED(ClassID()) {} 90aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 91144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt void onPrepareDraws(Target* target) const override { 92ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas SkAutoTUnref<const GrGeometryProcessor> gp(Impl::CreateGP(this->seedGeometry(), 93ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas fOverrides)); 942ad37be2b1f596a163e889ae0282227055c6b661joshualitt if (!gp) { 952ad37be2b1f596a163e889ae0282227055c6b661joshualitt SkDebugf("Couldn't create GrGeometryProcessor\n"); 962ad37be2b1f596a163e889ae0282227055c6b661joshualitt return; 972ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 982ad37be2b1f596a163e889ae0282227055c6b661joshualitt 992ad37be2b1f596a163e889ae0282227055c6b661joshualitt target->initDraw(gp, this->pipeline()); 1002ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1012ad37be2b1f596a163e889ae0282227055c6b661joshualitt size_t vertexStride = gp->getVertexStride(); 1022ad37be2b1f596a163e889ae0282227055c6b661joshualitt int instanceCount = fGeoData.count(); 1032ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1042ad37be2b1f596a163e889ae0282227055c6b661joshualitt SkAutoTUnref<const GrIndexBuffer> indexBuffer( 1052ad37be2b1f596a163e889ae0282227055c6b661joshualitt Impl::GetIndexBuffer(target->resourceProvider())); 1062ad37be2b1f596a163e889ae0282227055c6b661joshualitt InstancedHelper helper; 1072ad37be2b1f596a163e889ae0282227055c6b661joshualitt void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, 1082ad37be2b1f596a163e889ae0282227055c6b661joshualitt indexBuffer, Impl::kVertsPerInstance, 1092ad37be2b1f596a163e889ae0282227055c6b661joshualitt Impl::kIndicesPerInstance, instanceCount); 1102ad37be2b1f596a163e889ae0282227055c6b661joshualitt if (!vertices || !indexBuffer) { 1112ad37be2b1f596a163e889ae0282227055c6b661joshualitt SkDebugf("Could not allocate vertices\n"); 1122ad37be2b1f596a163e889ae0282227055c6b661joshualitt return; 1132ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 1142ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1152ad37be2b1f596a163e889ae0282227055c6b661joshualitt for (int i = 0; i < instanceCount; i++) { 1162ad37be2b1f596a163e889ae0282227055c6b661joshualitt intptr_t verts = reinterpret_cast<intptr_t>(vertices) + 1172ad37be2b1f596a163e889ae0282227055c6b661joshualitt i * Impl::kVertsPerInstance * vertexStride; 118ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas Impl::Tesselate(verts, vertexStride, fGeoData[i], fOverrides); 1192ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 1202ad37be2b1f596a163e889ae0282227055c6b661joshualitt helper.recordDraw(target); 1212ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 1222ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1232ad37be2b1f596a163e889ae0282227055c6b661joshualitt const Geometry& seedGeometry() const { return fGeoData[0]; } 1242ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1252ad37be2b1f596a163e889ae0282227055c6b661joshualitt bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 1262ad37be2b1f596a163e889ae0282227055c6b661joshualitt GrTInstanceBatch* that = t->cast<GrTInstanceBatch>(); 1272ad37be2b1f596a163e889ae0282227055c6b661joshualitt if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 1282ad37be2b1f596a163e889ae0282227055c6b661joshualitt that->bounds(), caps)) { 1292ad37be2b1f596a163e889ae0282227055c6b661joshualitt return false; 1302ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 1312ad37be2b1f596a163e889ae0282227055c6b661joshualitt 132ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas if (!Impl::CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides)) { 1332ad37be2b1f596a163e889ae0282227055c6b661joshualitt return false; 1342ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 1352ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1362ad37be2b1f596a163e889ae0282227055c6b661joshualitt // In the event of two batches, one who can tweak, one who cannot, we just fall back to 1372ad37be2b1f596a163e889ae0282227055c6b661joshualitt // not tweaking 138ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) { 139ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas fOverrides = that->fOverrides; 1402ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 1412ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1422ad37be2b1f596a163e889ae0282227055c6b661joshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 1432ad37be2b1f596a163e889ae0282227055c6b661joshualitt this->joinBounds(that->bounds()); 1442ad37be2b1f596a163e889ae0282227055c6b661joshualitt return true; 1452ad37be2b1f596a163e889ae0282227055c6b661joshualitt } 1462ad37be2b1f596a163e889ae0282227055c6b661joshualitt 147ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrXPOverridesForBatch fOverrides; 1482ad37be2b1f596a163e889ae0282227055c6b661joshualitt SkSTArray<1, Geometry, true> fGeoData; 1491b55a963a2374a14bb82eb887bb99ee91680f0ebreed 1501b55a963a2374a14bb82eb887bb99ee91680f0ebreed typedef GrVertexBatch INHERITED; 1512ad37be2b1f596a163e889ae0282227055c6b661joshualitt}; 1522ad37be2b1f596a163e889ae0282227055c6b661joshualitt 1532ad37be2b1f596a163e889ae0282227055c6b661joshualitt#endif 154