blob: 2f1afee1e42b8faf92b2d85c9bf52efbb8d13734 [file] [log] [blame]
joshualitt4d8da812015-01-28 12:53:54 -08001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrBatch_DEFINED
9#define GrBatch_DEFINED
10
11#include <new>
12// TODO remove this header when we move entirely to batch
13#include "GrGeometryProcessor.h"
14#include "SkRefCnt.h"
15#include "SkThread.h"
16#include "SkTypes.h"
17
18class GrBatchTarget;
19class GrGpu;
20class GrIndexBufferAllocPool;
21class GrPipeline;
22class GrVertexBufferAllocPool;
23
24struct GrInitInvariantOutput;
25
26/*
27 * GrBatch is the base class for all Ganesh deferred geometry generators. To facilitate
28 * reorderable batching, Ganesh does not generate geometry inline with draw calls. Instead, it
29 * captures the arguments to the draw and then generates the geometry on demand. This gives GrBatch
30 * subclasses complete freedom to decide how / what they can batch.
31 *
32 * Batches are created when GrContext processes a draw call. Batches of the same subclass may be
33 * merged using combineIfPossible. When two batches merge, one takes on the union of the data
34 * and the other is left empty. The merged batch becomes responsible for drawing the data from both
35 * the original batches.
36 *
37 * If there are any possible optimizations which might require knowing more about the full state of
38 * the draw, ie whether or not the GrBatch is allowed to tweak alpha for coverage, then this
39 * information will be communicated to the GrBatch prior to geometry generation.
40 */
41
42struct GrBatchOpt {
43 bool fCanTweakAlphaForCoverage;
44};
45
46class GrBatch : public SkRefCnt {
47public:
48 SK_DECLARE_INST_COUNT(GrBatch)
joshualitt7bc18b72015-02-03 16:41:41 -080049 GrBatch() : fNumberOfDraws(0) { SkDEBUGCODE(fUsed = false;) }
joshualitt4d8da812015-01-28 12:53:54 -080050 virtual ~GrBatch() {}
51
52 virtual const char* name() const = 0;
53 virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
54 virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
55
56 /*
57 * initBatchOpt is used to communicate possible optimizations to the GrBatch. initBatchTracker
58 * is a hook for the some additional overrides from the GrXferProcessor. This is a bit
59 * confusing but has to be like this until GrBatch is everywhere.
60 *
61 * TODO combine to a single init call when GrBatch is everywhere.
62 */
63 virtual void initBatchOpt(const GrBatchOpt&) = 0;
64 virtual void initBatchTracker(const GrPipelineInfo& init) = 0;
65
66 bool combineIfPossible(GrBatch* that) {
67 if (this->classID() != that->classID()) {
68 return false;
69 }
70
71 return onCombineIfPossible(that);
72 }
73
74 virtual bool onCombineIfPossible(GrBatch*) = 0;
75
76 virtual void generateGeometry(GrBatchTarget*, const GrPipeline*) = 0;
77
joshualitt7bc18b72015-02-03 16:41:41 -080078 // TODO this goes away when batches are everywhere
79 void setNumberOfDraws(int numberOfDraws) { fNumberOfDraws = numberOfDraws; }
80 int numberOfDraws() const { return fNumberOfDraws; }
81
joshualitt4d8da812015-01-28 12:53:54 -080082 void* operator new(size_t size);
83 void operator delete(void* target);
84
85 void* operator new(size_t size, void* placement) {
86 return ::operator new(size, placement);
87 }
88 void operator delete(void* target, void* placement) {
89 ::operator delete(target, placement);
90 }
91
92 /**
93 * Helper for down-casting to a GrBatch subclass
94 */
95 template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
96 template <typename T> T* cast() { return static_cast<T*>(this); }
97
98 uint32_t classID() const { SkASSERT(kIllegalBatchClassID != fClassID); return fClassID; }
99
100 // TODO no GrPrimitiveProcessors yet read fragment position
101 bool willReadFragmentPosition() const { return false; }
102
103 SkDEBUGCODE(bool isUsed() const { return fUsed; })
104
105protected:
106 template <typename PROC_SUBCLASS> void initClassID() {
107 static uint32_t kClassID = GenClassID();
108 fClassID = kClassID;
109 }
110
111 uint32_t fClassID;
112
113private:
114 static uint32_t GenClassID() {
115 // fCurrProcessorClassID has been initialized to kIllegalProcessorClassID. The
116 // atomic inc returns the old value not the incremented value. So we add
117 // 1 to the returned value.
118 uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&gCurrBatchClassID)) + 1;
119 if (!id) {
120 SkFAIL("This should never wrap as it should only be called once for each GrBatch "
121 "subclass.");
122 }
123 return id;
124 }
125
126 enum {
127 kIllegalBatchClassID = 0,
128 };
129 static int32_t gCurrBatchClassID;
130
131 SkDEBUGCODE(bool fUsed;)
132
joshualitt7bc18b72015-02-03 16:41:41 -0800133 int fNumberOfDraws;
134
joshualitt4d8da812015-01-28 12:53:54 -0800135 typedef SkRefCnt INHERITED;
136};
137
138#endif