GrOp.h revision 1b55a963a2374a14bb82eb887bb99ee91680f0eb
14d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt/* 24d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * Copyright 2015 Google Inc. 34d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * 44d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * Use of this source code is governed by a BSD-style license that can be 54d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * found in the LICENSE file. 64d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt */ 74d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 84d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt#ifndef GrBatch_DEFINED 94d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt#define GrBatch_DEFINED 104d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 114d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt#include <new> 12dbe1e6f0c32bd07b7669b1b1ac3c7f58c9b8d773joshualitt#include "GrNonAtomicRef.h" 134d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 1416b991390bb988b194a868ab8de66db4c21c7c13bsalomon#include "SkRect.h" 155346983b2e0726b4009cc546b01c58a8919e6c36bsalomon#include "SkString.h" 164d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 1716b991390bb988b194a868ab8de66db4c21c7c13bsalomonclass GrCaps; 185346983b2e0726b4009cc546b01c58a8919e6c36bsalomonclass GrBatchFlushState; 194d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 20abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon/** 214d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * GrBatch is the base class for all Ganesh deferred geometry generators. To facilitate 224d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * reorderable batching, Ganesh does not generate geometry inline with draw calls. Instead, it 234d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * captures the arguments to the draw and then generates the geometry on demand. This gives GrBatch 244d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * subclasses complete freedom to decide how / what they can batch. 254d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * 264d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * Batches are created when GrContext processes a draw call. Batches of the same subclass may be 274d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * merged using combineIfPossible. When two batches merge, one takes on the union of the data 284d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * and the other is left empty. The merged batch becomes responsible for drawing the data from both 294d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * the original batches. 304d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * 314d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * If there are any possible optimizations which might require knowing more about the full state of 324d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * the draw, ie whether or not the GrBatch is allowed to tweak alpha for coverage, then this 334d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * information will be communicated to the GrBatch prior to geometry generation. 344d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt */ 35ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#define GR_BATCH_SPEW 0 36ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#if GR_BATCH_SPEW 37ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt #define GrBATCH_INFO(...) SkDebugf(__VA_ARGS__) 38ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt #define GrBATCH_SPEW(code) code 39ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#else 40ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt #define GrBATCH_SPEW(code) 41ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt #define GrBATCH_INFO(...) 42ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#endif 434d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 441b55a963a2374a14bb82eb887bb99ee91680f0ebreed// A helper macro to generate a class static id 451b55a963a2374a14bb82eb887bb99ee91680f0ebreed#define DEFINE_BATCH_CLASS_ID \ 461b55a963a2374a14bb82eb887bb99ee91680f0ebreed static uint32_t ClassID() { \ 471b55a963a2374a14bb82eb887bb99ee91680f0ebreed static uint32_t kClassID = GenBatchClassID(); \ 481b55a963a2374a14bb82eb887bb99ee91680f0ebreed return kClassID; \ 491b55a963a2374a14bb82eb887bb99ee91680f0ebreed } 501b55a963a2374a14bb82eb887bb99ee91680f0ebreed 51dbe1e6f0c32bd07b7669b1b1ac3c7f58c9b8d773joshualittclass GrBatch : public GrNonAtomicRef { 524d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittpublic: 531b55a963a2374a14bb82eb887bb99ee91680f0ebreed GrBatch(uint32_t classID); 54a387a11f9e10ee828fd0e0257cc3ee3f6262f7cabsalomon ~GrBatch() override; 554d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 564d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt virtual const char* name() const = 0; 574d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 58cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon bool combineIfPossible(GrBatch* that, const GrCaps& caps) { 594d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt if (this->classID() != that->classID()) { 604d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt return false; 614d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 624d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 63cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon return this->onCombineIfPossible(that, caps); 644d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 654d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 6699c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt const SkRect& bounds() const { return fBounds; } 6799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 684d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void* operator new(size_t size); 694d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void operator delete(void* target); 704d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 714d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void* operator new(size_t size, void* placement) { 724d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt return ::operator new(size, placement); 734d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 744d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void operator delete(void* target, void* placement) { 754d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt ::operator delete(target, placement); 764d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 774d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 784d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt /** 791b55a963a2374a14bb82eb887bb99ee91680f0ebreed * Helper for safely down-casting to a GrBatch subclass 80abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon */ 811b55a963a2374a14bb82eb887bb99ee91680f0ebreed template <typename T> const T& cast() const { 821b55a963a2374a14bb82eb887bb99ee91680f0ebreed SkASSERT(T::ClassID() == this->classID()); 831b55a963a2374a14bb82eb887bb99ee91680f0ebreed return *static_cast<const T*>(this); 841b55a963a2374a14bb82eb887bb99ee91680f0ebreed } 851b55a963a2374a14bb82eb887bb99ee91680f0ebreed 861b55a963a2374a14bb82eb887bb99ee91680f0ebreed template <typename T> T* cast() { 871b55a963a2374a14bb82eb887bb99ee91680f0ebreed SkASSERT(T::ClassID() == this->classID()); 881b55a963a2374a14bb82eb887bb99ee91680f0ebreed return static_cast<T*>(this); 891b55a963a2374a14bb82eb887bb99ee91680f0ebreed } 904d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 91ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt uint32_t classID() const { SkASSERT(kIllegalBatchID != fClassID); return fClassID; } 924d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 93ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#if GR_BATCH_SPEW 94ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt uint32_t uniqueID() const { return fUniqueID; } 95ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#endif 96abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon SkDEBUGCODE(bool isUsed() const { return fUsed; }) 97ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt 985346983b2e0726b4009cc546b01c58a8919e6c36bsalomon /** Called prior to drawing. The batch should perform any resource creation necessary to 995346983b2e0726b4009cc546b01c58a8919e6c36bsalomon to quickly issue its draw when draw is called. */ 1005346983b2e0726b4009cc546b01c58a8919e6c36bsalomon void prepare(GrBatchFlushState* state) { this->onPrepare(state); } 1015346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 1025346983b2e0726b4009cc546b01c58a8919e6c36bsalomon /** Issues the batches commands to GrGpu. */ 1035346983b2e0726b4009cc546b01c58a8919e6c36bsalomon void draw(GrBatchFlushState* state) { this->onDraw(state); } 1045346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 1055346983b2e0726b4009cc546b01c58a8919e6c36bsalomon /** Used to block batching across render target changes. Remove this once we store 1065346983b2e0726b4009cc546b01c58a8919e6c36bsalomon GrBatches for different RTs in different targets. */ 1075346983b2e0726b4009cc546b01c58a8919e6c36bsalomon virtual uint32_t renderTargetUniqueID() const = 0; 1085346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 1095346983b2e0726b4009cc546b01c58a8919e6c36bsalomon /** Used for spewing information about batches when debugging. */ 1105346983b2e0726b4009cc546b01c58a8919e6c36bsalomon virtual SkString dumpInfo() const = 0; 1115346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 1124d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittprotected: 11399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt // NOTE, compute some bounds, even if extremely conservative. Do *NOT* setLargest on the bounds 11499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt // rect because we outset it for dst copy textures 11599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt void setBounds(const SkRect& newBounds) { fBounds = newBounds; } 11699c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 11799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt void joinBounds(const SkRect& otherBounds) { 11899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt return fBounds.joinPossiblyEmptyRect(otherBounds); 11999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt } 12099c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 1211b55a963a2374a14bb82eb887bb99ee91680f0ebreed static uint32_t GenBatchClassID() { return GenID(&gCurrBatchClassID); } 1221b55a963a2374a14bb82eb887bb99ee91680f0ebreed 123abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon SkRect fBounds; 124abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 125abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonprivate: 126abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon virtual bool onCombineIfPossible(GrBatch*, const GrCaps& caps) = 0; 127abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 1285346983b2e0726b4009cc546b01c58a8919e6c36bsalomon virtual void onPrepare(GrBatchFlushState*) = 0; 1295346983b2e0726b4009cc546b01c58a8919e6c36bsalomon virtual void onDraw(GrBatchFlushState*) = 0; 1305346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 131abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon static uint32_t GenID(int32_t* idCounter) { 1321b55a963a2374a14bb82eb887bb99ee91680f0ebreed // The atomic inc returns the old value not the incremented value. So we add 133abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon // 1 to the returned value. 134abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon uint32_t id = static_cast<uint32_t>(sk_atomic_inc(idCounter)) + 1; 135abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon if (!id) { 136abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon SkFAIL("This should never wrap as it should only be called once for each GrBatch " 137abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon "subclass."); 138abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon } 139abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon return id; 140abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon } 141abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 142abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon enum { 143abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon kIllegalBatchID = 0, 144abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon }; 145abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 146abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon SkDEBUGCODE(bool fUsed;) 1471b55a963a2374a14bb82eb887bb99ee91680f0ebreed const uint32_t fClassID; 148abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon#if GR_BATCH_SPEW 1491b55a963a2374a14bb82eb887bb99ee91680f0ebreed static uint32_t GenBatchID() { return GenID(&gCurrBatchUniqueID); } 1501b55a963a2374a14bb82eb887bb99ee91680f0ebreed const uint32_t fUniqueID; 1511b55a963a2374a14bb82eb887bb99ee91680f0ebreed static int32_t gCurrBatchUniqueID; 152abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon#endif 1531b55a963a2374a14bb82eb887bb99ee91680f0ebreed static int32_t gCurrBatchClassID; 154abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon typedef GrNonAtomicRef INHERITED; 155abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon}; 156abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 1574d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt#endif 158