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 class GrGLSLCaps;
46 class GrGLSLPrimitiveProcessor;
47 
48 struct GrInitInvariantOutput;
49 
50 // Describes the state of pixel local storage with respect to the current draw.
51 enum GrPixelLocalStorageState {
52     // The draw is actively updating PLS.
53     kDraw_GrPixelLocalStorageState,
54     // The draw is a "finish" operation which is reading from PLS and writing color.
55     kFinish_GrPixelLocalStorageState,
56     // The draw does not use PLS.
57     kDisabled_GrPixelLocalStorageState
58 };
59 
60 /*
61  * This class allows the GrPipeline to communicate information about the pipeline to a
62  * GrBatch which should be forwarded to the GrPrimitiveProcessor(s) created by the batch.
63  * These are not properly part of the pipeline because they assume the specific inputs
64  * that the batch provided when it created the pipeline. Identical pipelines may be
65  * created by different batches with different input assumptions and therefore different
66  * computed optimizations. It is the batch-specific optimizations that allow the pipelines
67  * to be equal.
68  */
69 class GrXPOverridesForBatch {
70 public:
71     /** Does the pipeline require the GrPrimitiveProcessor's color? */
readsColor()72     bool readsColor() const { return SkToBool(kReadsColor_Flag & fFlags); }
73 
74     /** Does the pipeline require the GrPrimitiveProcessor's coverage? */
readsCoverage()75     bool readsCoverage() const { return
76         SkToBool(kReadsCoverage_Flag & fFlags); }
77 
78     /** Does the pipeline require access to (implicit or explicit) local coordinates? */
readsLocalCoords()79     bool readsLocalCoords() const {
80         return SkToBool(kReadsLocalCoords_Flag & fFlags);
81     }
82 
83     /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
84         color output ? */
canTweakAlphaForCoverage()85     bool canTweakAlphaForCoverage() const {
86         return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
87     }
88 
89     /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
90         so get the color)? */
getOverrideColorIfSet(GrColor * overrideColor)91     bool getOverrideColorIfSet(GrColor* overrideColor) const {
92         if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
93             SkASSERT(SkToBool(kReadsColor_Flag & fFlags));
94             if (overrideColor) {
95                 *overrideColor = fOverrideColor;
96             }
97             return true;
98         }
99         return false;
100     }
101 
102     /**
103      * Returns true if the pipeline's color output will be affected by the existing render target
104      * destination pixel values (meaning we need to be careful with overlapping draws). Note that we
105      * can conflate coverage and color, so the destination color may still bleed into pixels that
106      * have partial coverage, even if this function returns false.
107      *
108      * The above comment seems incorrect for the use case. This funciton is used to turn two
109      * overlapping draws into a single draw (really to stencil multiple paths and do a single
110      * cover). It seems that what really matters is whether the dst is read for color OR for
111      * coverage.
112      */
willColorBlendWithDst()113     bool willColorBlendWithDst() const { return SkToBool(kWillColorBlendWithDst_Flag & fFlags); }
114 
115 private:
116     enum {
117         // If this is not set the primitive processor need not produce a color output
118         kReadsColor_Flag                = 0x1,
119 
120         // If this is not set the primitive processor need not produce a coverage output
121         kReadsCoverage_Flag             = 0x2,
122 
123         // If this is not set the primitive processor need not produce local coordinates
124         kReadsLocalCoords_Flag          = 0x4,
125 
126         // If this flag is set then the primitive processor may produce color*coverage as
127         // its color output (and not output a separate coverage).
128         kCanTweakAlphaForCoverage_Flag  = 0x8,
129 
130         // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
131         // output color. If not set fOverrideColor is to be ignored.
132         kUseOverrideColor_Flag          = 0x10,
133 
134         kWillColorBlendWithDst_Flag     = 0x20,
135     };
136 
137     uint32_t    fFlags;
138     GrColor     fOverrideColor;
139 
140     friend class GrPipeline; // To initialize this
141 };
142 
143 /*
144  * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
145  * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
146  * pipelines, and they must provide some notion of equality
147  */
148 class GrPrimitiveProcessor : public GrProcessor {
149 public:
150     // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
151     // we put these calls on the base class to prevent having to cast
152     virtual bool willUseGeoShader() const = 0;
153 
154     struct Attribute {
AttributeAttribute155         Attribute()
156             : fName(nullptr)
157             , fType(kFloat_GrVertexAttribType)
158             , fOffset(0) {}
AttributeAttribute159         Attribute(const char* name, GrVertexAttribType type, GrSLPrecision precision)
160             : fName(name)
161             , fType(type)
162             , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
163             , fPrecision(precision) {}
164         const char* fName;
165         GrVertexAttribType fType;
166         size_t fOffset;
167         GrSLPrecision fPrecision;
168     };
169 
numAttribs()170     int numAttribs() const { return fAttribs.count(); }
getAttrib(int index)171     const Attribute& getAttrib(int index) const { return fAttribs[index]; }
172 
173     // Returns the vertex stride of the GP.  A common use case is to request geometry from a
174     // drawtarget based off of the stride, and to populate this memory using an implicit array of
175     // structs.  In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
getVertexStride()176     size_t getVertexStride() const { return fVertexStride; }
177 
178     /**
179      * Computes a transformKey from an array of coord transforms. Will only look at the first
180      * <numCoords> transforms in the array.
181      *
182      * TODO: A better name for this function  would be "compute" instead of "get".
183      */
184     uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
185                              int numCoords) const;
186 
187     /**
188      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
189      * processor's GL backend implementation.
190      *
191      * TODO: A better name for this function  would be "compute" instead of "get".
192      */
193     virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
194                                      GrProcessorKeyBuilder* b) const = 0;
195 
196 
197     /** Returns a new instance of the appropriate *GL* implementation class
198         for the given GrProcessor; caller is responsible for deleting
199         the object. */
200     virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps& caps) const = 0;
201 
isPathRendering()202     virtual bool isPathRendering() const { return false; }
203 
getPixelLocalStorageState()204     virtual GrPixelLocalStorageState getPixelLocalStorageState() const {
205         return kDisabled_GrPixelLocalStorageState;
206     }
207 
208     /**
209      * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
210      */
getDestColorOverride()211     virtual const char* getDestColorOverride() const { return nullptr; }
212 
getSampleShading()213     virtual float getSampleShading() const {
214         return 0.0;
215     }
216 
217     /* Sub-class should override and return true if this primitive processor implements the distance
218      * vector field, a field of vectors to the nearest point in the edge of the shape.  */
implementsDistanceVector()219     virtual bool implementsDistanceVector() const { return false; }
220 
221 protected:
GrPrimitiveProcessor()222     GrPrimitiveProcessor() : fVertexStride(0) {}
223 
224     enum { kPreallocAttribCnt = 8 };
225     SkSTArray<kPreallocAttribCnt, Attribute> fAttribs;
226     size_t fVertexStride;
227 
228 private:
notifyRefCntIsZero()229     void notifyRefCntIsZero() const final {}
230     virtual bool hasExplicitLocalCoords() const = 0;
231 
232     typedef GrProcessor INHERITED;
233 };
234 
235 #endif
236