• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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 GrPrimitiveProcessor_DEFINED
9 #define GrPrimitiveProcessor_DEFINED
10 
11 #include "GrColor.h"
12 #include "GrProcessor.h"
13 #include "GrShaderVar.h"
14 
15 /*
16  * The GrPrimitiveProcessor represents some kind of geometric primitive.  This includes the shape
17  * of the primitive and the inherent color of the primitive.  The GrPrimitiveProcessor is
18  * responsible for providing a color and coverage input into the Ganesh rendering pipeline.  Through
19  * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
20  * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
21  * functionality.  We also use the GrPrimitiveProcessor to make batching decisions.
22  *
23  * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
24  * GrPrimitiveProcessor.  These loops run on the CPU and compute any invariant components which
25  * might be useful for correctness / optimization decisions.  The GrPrimitiveProcessor seeds these
26  * loops, one with initial color and one with initial coverage, in its
27  * onComputeInvariantColor / Coverage calls.  These seed values are processed by the subsequent
28  * stages of the rendering pipeline and the output is then fed back into the GrPrimitiveProcessor in
29  * the initBatchTracker call, where the GrPrimitiveProcessor can then initialize the GrBatchTracker
30  * struct with the appropriate values.
31  *
32  * We are evolving this system to move towards generating geometric meshes and their associated
33  * vertex data after we have batched and reordered draws.  This system, known as 'deferred geometry'
34  * will allow the GrPrimitiveProcessor much greater control over how data is transmitted to shaders.
35  *
36  * In a deferred geometry world, the GrPrimitiveProcessor can always 'batch'  To do this, each
37  * primitive type is associated with one GrPrimitiveProcessor, who has complete control of how
38  * it draws.  Each primitive draw will bundle all required data to perform the draw, and these
39  * bundles of data will be owned by an instance of the associated GrPrimitiveProcessor.  Bundles
40  * can be updated alongside the GrBatchTracker struct itself, ultimately allowing the
41  * GrPrimitiveProcessor complete control of how it gets data into the fragment shader as long as
42  * it emits the appropriate color, or none at all, as directed.
43  */
44 
45 /*
46  * A struct for tracking batching decisions.  While this lives on GrOptState, it is managed
47  * entirely by the derived classes of the GP.
48  * // TODO this was an early attempt at handling out of order batching.  It should be
49  * used carefully as it is being replaced by GrBatch
50  */
51 class GrBatchTracker {
52 public:
cast()53     template <typename T> const T& cast() const {
54         SkASSERT(sizeof(T) <= kMaxSize);
55         return *reinterpret_cast<const T*>(fData.get());
56     }
57 
cast()58     template <typename T> T* cast() {
59         SkASSERT(sizeof(T) <= kMaxSize);
60         return reinterpret_cast<T*>(fData.get());
61     }
62 
63     static const size_t kMaxSize = 32;
64 
65 private:
66     SkAlignedSStorage<kMaxSize> fData;
67 };
68 
69 class GrGLSLCaps;
70 class GrGLPrimitiveProcessor;
71 
72 struct GrInitInvariantOutput;
73 
74 /*
75  * This struct allows the GrPipeline to communicate information about the pipeline.  Most of this
76  * is overrides, but some of it is general information.  Logically it should live in GrPipeline.h,
77  * but this is problematic due to circular dependencies.
78  */
79 struct GrPipelineInfo {
80     bool fColorIgnored;
81     bool fCoverageIgnored;
82     GrColor fOverrideColor;
83     bool fUsesLocalCoords;
84     bool fCanTweakAlphaForCoverage;
85 };
86 
87 /*
88  * This enum is shared by GrPrimitiveProcessors and GrGLPrimitiveProcessors to coordinate shaders
89  * with vertex attributes / uniforms.
90  */
91 enum GrGPInput {
92     kAllOnes_GrGPInput,
93     kAttribute_GrGPInput,
94     kUniform_GrGPInput,
95     kIgnored_GrGPInput,
96 };
97 
98 /*
99  * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
100  * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
101  * pipelines, and they must provide some notion of equality
102  */
103 class GrPrimitiveProcessor : public GrProcessor {
104 public:
105     virtual void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const = 0;
106 
107     virtual bool canMakeEqual(const GrBatchTracker& mine,
108                               const GrPrimitiveProcessor& that,
109                               const GrBatchTracker& theirs) const = 0;
110 
111     virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
112     virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
113 
114     // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
115     // we put these calls on the base class to prevent having to cast
116     virtual bool willUseGeoShader() const = 0;
117 
118     /*
119      * This is a safeguard to prevent GrPrimitiveProcessor's from going beyond platform specific
120      * attribute limits. This number can almost certainly be raised if required.
121      */
122     static const int kMaxVertexAttribs = 6;
123 
124     struct Attribute {
AttributeAttribute125         Attribute()
126             : fName(NULL)
127             , fType(kFloat_GrVertexAttribType)
128             , fOffset(0) {}
129         Attribute(const char* name, GrVertexAttribType type,
130                   GrSLPrecision precision = kDefault_GrSLPrecision)
fNameAttribute131             : fName(name)
132             , fType(type)
133             , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
134             , fPrecision(precision) {}
135         const char* fName;
136         GrVertexAttribType fType;
137         size_t fOffset;
138         GrSLPrecision fPrecision;
139     };
140 
numAttribs()141     int numAttribs() const { return fNumAttribs; }
getAttrib(int index)142     const Attribute& getAttrib(int index) const {
143         SkASSERT(index < fNumAttribs);
144         return fAttribs[index];
145     }
146 
147     // Returns the vertex stride of the GP.  A common use case is to request geometry from a
148     // drawtarget based off of the stride, and to populate this memory using an implicit array of
149     // structs.  In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
getVertexStride()150     size_t getVertexStride() const { return fVertexStride; }
151 
152     /**
153      * Gets a transformKey from an array of coord transforms
154      */
155     uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>&) const;
156 
157     /**
158      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
159      * processor's GL backend implementation.
160      */
161     virtual void getGLProcessorKey(const GrBatchTracker& bt,
162                                    const GrGLSLCaps& caps,
163                                    GrProcessorKeyBuilder* b) const = 0;
164 
165 
166     /** Returns a new instance of the appropriate *GL* implementation class
167         for the given GrProcessor; caller is responsible for deleting
168         the object. */
169     virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
170                                                      const GrGLSLCaps& caps) const = 0;
171 
isPathRendering()172     bool isPathRendering() const { return fIsPathRendering; }
173 
174 protected:
GrPrimitiveProcessor(bool isPathRendering)175     GrPrimitiveProcessor(bool isPathRendering)
176         : fNumAttribs(0)
177         , fVertexStride(0)
178         , fIsPathRendering(isPathRendering) {}
179 
180     Attribute fAttribs[kMaxVertexAttribs];
181     int fNumAttribs;
182     size_t fVertexStride;
183 
184 private:
185     virtual bool hasExplicitLocalCoords() const = 0;
186 
187     bool fIsPathRendering;
188 
189     typedef GrProcessor INHERITED;
190 };
191 
192 #endif
193