blob: 561f54be035e1aaeaeadd03de6a507f03938521a [file] [log] [blame]
joshualitt8072caa2015-02-12 14:20:52 -08001/*
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
jvanverthe9c0fc62015-04-29 11:18:05 -070045class GrGLSLCaps;
egdaniele659a582015-11-13 09:55:43 -080046class GrGLSLPrimitiveProcessor;
joshualitt8072caa2015-02-12 14:20:52 -080047
48struct GrInitInvariantOutput;
49
halcanary9d524f22016-03-29 09:03:52 -070050// Describes the state of pixel local storage with respect to the current draw.
ethannicholas22793252016-01-30 09:59:10 -080051enum 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
joshualitt8072caa2015-02-12 14:20:52 -080060/*
bsalomon7765a472015-07-08 11:26:37 -070061 * This class allows the GrPipeline to communicate information about the pipeline to a
bsalomon91d844d2015-08-10 10:47:29 -070062 * 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.
joshualitt8072caa2015-02-12 14:20:52 -080068 */
ethannicholasff210322015-11-24 12:10:10 -080069class GrXPOverridesForBatch {
bsalomon7765a472015-07-08 11:26:37 -070070public:
71 /** Does the pipeline require the GrPrimitiveProcessor's color? */
bsalomonc6998732015-08-10 12:01:15 -070072 bool readsColor() const { return SkToBool(kReadsColor_Flag & fFlags); }
bsalomon7765a472015-07-08 11:26:37 -070073
74 /** Does the pipeline require the GrPrimitiveProcessor's coverage? */
bsalomon91d844d2015-08-10 10:47:29 -070075 bool readsCoverage() const { return
bsalomonc6998732015-08-10 12:01:15 -070076 SkToBool(kReadsCoverage_Flag & fFlags); }
bsalomon7765a472015-07-08 11:26:37 -070077
78 /** Does the pipeline require access to (implicit or explicit) local coordinates? */
79 bool readsLocalCoords() const {
bsalomonc6998732015-08-10 12:01:15 -070080 return SkToBool(kReadsLocalCoords_Flag & fFlags);
bsalomon7765a472015-07-08 11:26:37 -070081 }
82
83 /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
84 color output ? */
85 bool canTweakAlphaForCoverage() const {
bsalomonc6998732015-08-10 12:01:15 -070086 return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
bsalomon7765a472015-07-08 11:26:37 -070087 }
88
89 /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
90 so get the color)? */
91 bool getOverrideColorIfSet(GrColor* overrideColor) const {
bsalomonc6998732015-08-10 12:01:15 -070092 if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
93 SkASSERT(SkToBool(kReadsColor_Flag & fFlags));
bsalomon7765a472015-07-08 11:26:37 -070094 if (overrideColor) {
95 *overrideColor = fOverrideColor;
96 }
97 return true;
98 }
99 return false;
100 }
101
bsalomon2d563032015-08-13 07:08:31 -0700102 /**
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 */
113 bool willColorBlendWithDst() const { return SkToBool(kWillColorBlendWithDst_Flag & fFlags); }
114
bsalomon7765a472015-07-08 11:26:37 -0700115private:
116 enum {
117 // If this is not set the primitive processor need not produce a color output
bsalomonc6998732015-08-10 12:01:15 -0700118 kReadsColor_Flag = 0x1,
bsalomon7765a472015-07-08 11:26:37 -0700119
120 // If this is not set the primitive processor need not produce a coverage output
bsalomonc6998732015-08-10 12:01:15 -0700121 kReadsCoverage_Flag = 0x2,
bsalomon7765a472015-07-08 11:26:37 -0700122
123 // If this is not set the primitive processor need not produce local coordinates
bsalomonc6998732015-08-10 12:01:15 -0700124 kReadsLocalCoords_Flag = 0x4,
bsalomon7765a472015-07-08 11:26:37 -0700125
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).
bsalomonc6998732015-08-10 12:01:15 -0700128 kCanTweakAlphaForCoverage_Flag = 0x8,
bsalomon7765a472015-07-08 11:26:37 -0700129
130 // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
131 // output color. If not set fOverrideColor is to be ignored.
bsalomonc6998732015-08-10 12:01:15 -0700132 kUseOverrideColor_Flag = 0x10,
bsalomon2d563032015-08-13 07:08:31 -0700133
134 kWillColorBlendWithDst_Flag = 0x20,
bsalomon7765a472015-07-08 11:26:37 -0700135 };
136
137 uint32_t fFlags;
138 GrColor fOverrideColor;
139
140 friend class GrPipeline; // To initialize this
joshualitt8072caa2015-02-12 14:20:52 -0800141};
142
143/*
joshualitt8072caa2015-02-12 14:20:52 -0800144 * 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 */
148class GrPrimitiveProcessor : public GrProcessor {
149public:
joshualitt8072caa2015-02-12 14:20:52 -0800150 // 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
joshualitt8072caa2015-02-12 14:20:52 -0800154 struct Attribute {
155 Attribute()
halcanary96fcdcc2015-08-27 07:41:13 -0700156 : fName(nullptr)
joshualitt8072caa2015-02-12 14:20:52 -0800157 , fType(kFloat_GrVertexAttribType)
158 , fOffset(0) {}
bsalomon6cb807b2016-08-17 11:33:39 -0700159 Attribute(const char* name, GrVertexAttribType type, GrSLPrecision precision)
joshualitt8072caa2015-02-12 14:20:52 -0800160 : fName(name)
161 , fType(type)
senorblancof2539d52015-05-20 14:03:42 -0700162 , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
163 , fPrecision(precision) {}
joshualitt8072caa2015-02-12 14:20:52 -0800164 const char* fName;
165 GrVertexAttribType fType;
166 size_t fOffset;
senorblancof2539d52015-05-20 14:03:42 -0700167 GrSLPrecision fPrecision;
joshualitt8072caa2015-02-12 14:20:52 -0800168 };
169
bsalomon7dbd45d2016-03-23 10:40:53 -0700170 int numAttribs() const { return fAttribs.count(); }
171 const Attribute& getAttrib(int index) const { return fAttribs[index]; }
joshualitt8072caa2015-02-12 14:20:52 -0800172
173 // Returns the vertex stride of the GP. A common use case is to request geometry from a
Robert Phillipsf2361d22016-10-25 14:20:06 -0400174 // GrOpList based off of the stride, and to populate this memory using an implicit array of
joshualitt8072caa2015-02-12 14:20:52 -0800175 // structs. In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
176 size_t getVertexStride() const { return fVertexStride; }
177
178 /**
wangyixa7f4c432015-08-20 07:25:02 -0700179 * 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".
joshualitt8072caa2015-02-12 14:20:52 -0800183 */
wangyixa7f4c432015-08-20 07:25:02 -0700184 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
185 int numCoords) const;
joshualitt8072caa2015-02-12 14:20:52 -0800186
187 /**
188 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
189 * processor's GL backend implementation.
wangyixa7f4c432015-08-20 07:25:02 -0700190 *
191 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800192 */
egdaniel57d3b032015-11-13 11:57:27 -0800193 virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
194 GrProcessorKeyBuilder* b) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800195
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. */
egdaniel57d3b032015-11-13 11:57:27 -0800200 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps& caps) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800201
ethannicholas22793252016-01-30 09:59:10 -0800202 virtual bool isPathRendering() const { return false; }
joshualitt8072caa2015-02-12 14:20:52 -0800203
halcanary9d524f22016-03-29 09:03:52 -0700204 virtual GrPixelLocalStorageState getPixelLocalStorageState() const {
ethannicholas22793252016-01-30 09:59:10 -0800205 return kDisabled_GrPixelLocalStorageState;
206 }
207
208 /**
209 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
210 */
211 virtual const char* getDestColorOverride() const { return nullptr; }
halcanary9d524f22016-03-29 09:03:52 -0700212
ethannicholas28ef4452016-03-25 09:26:03 -0700213 virtual float getSampleShading() const {
214 return 0.0;
215 }
216
dvonbeck9b03e7b2016-08-01 11:01:56 -0700217 /* 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. */
219 virtual bool implementsDistanceVector() const { return false; }
220
joshualitt8072caa2015-02-12 14:20:52 -0800221protected:
bsalomon7dbd45d2016-03-23 10:40:53 -0700222 GrPrimitiveProcessor() : fVertexStride(0) {}
joshualitt8072caa2015-02-12 14:20:52 -0800223
bsalomon7dbd45d2016-03-23 10:40:53 -0700224 enum { kPreallocAttribCnt = 8 };
225 SkSTArray<kPreallocAttribCnt, Attribute> fAttribs;
joshualitt8072caa2015-02-12 14:20:52 -0800226 size_t fVertexStride;
227
228private:
Mike Kleinfc6c37b2016-09-27 09:34:10 -0400229 void notifyRefCntIsZero() const final {}
joshualitt8072caa2015-02-12 14:20:52 -0800230 virtual bool hasExplicitLocalCoords() const = 0;
231
joshualitt8072caa2015-02-12 14:20:52 -0800232 typedef GrProcessor INHERITED;
233};
234
235#endif