blob: 4cc1112820d6680a914fd94c024a756af06bd9ec [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
Brian Salomon92aee3d2016-12-21 09:20:25 -050028 * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
29 * the applyPipelineOptimizations call, where the op can use the information to inform decisions
30 * about GrPrimitiveProcessor creation.
joshualitt8072caa2015-02-12 14:20:52 -080031 */
32
egdaniele659a582015-11-13 09:55:43 -080033class GrGLSLPrimitiveProcessor;
joshualitt8072caa2015-02-12 14:20:52 -080034
35struct GrInitInvariantOutput;
36
halcanary9d524f22016-03-29 09:03:52 -070037// Describes the state of pixel local storage with respect to the current draw.
ethannicholas22793252016-01-30 09:59:10 -080038enum GrPixelLocalStorageState {
39 // The draw is actively updating PLS.
40 kDraw_GrPixelLocalStorageState,
41 // The draw is a "finish" operation which is reading from PLS and writing color.
42 kFinish_GrPixelLocalStorageState,
43 // The draw does not use PLS.
44 kDisabled_GrPixelLocalStorageState
45};
46
joshualitt8072caa2015-02-12 14:20:52 -080047/*
Brian Salomon92aee3d2016-12-21 09:20:25 -050048 * This class allows the GrPipeline to communicate information about the pipeline to a GrOp which
49 * inform its decisions for GrPrimitiveProcessor setup. These are not properly part of the pipeline
50 * because they reflect the specific inputs that the op provided to perform the analysis (e.g. that
51 * the GrGeometryProcessor would output an opaque color).
52 *
53 * The pipeline analysis that produced this may have decided to elide some GrProcessors. However,
54 * those elisions may depend upon changing the color output by the GrGeometryProcessor used by the
55 * GrDrawOp. The op must check getOverrideColorIfSet() for this.
joshualitt8072caa2015-02-12 14:20:52 -080056 */
Brian Salomon92aee3d2016-12-21 09:20:25 -050057class GrPipelineOptimizations {
bsalomon7765a472015-07-08 11:26:37 -070058public:
59 /** Does the pipeline require the GrPrimitiveProcessor's color? */
bsalomonc6998732015-08-10 12:01:15 -070060 bool readsColor() const { return SkToBool(kReadsColor_Flag & fFlags); }
bsalomon7765a472015-07-08 11:26:37 -070061
62 /** Does the pipeline require the GrPrimitiveProcessor's coverage? */
bsalomon91d844d2015-08-10 10:47:29 -070063 bool readsCoverage() const { return
bsalomonc6998732015-08-10 12:01:15 -070064 SkToBool(kReadsCoverage_Flag & fFlags); }
bsalomon7765a472015-07-08 11:26:37 -070065
66 /** Does the pipeline require access to (implicit or explicit) local coordinates? */
67 bool readsLocalCoords() const {
bsalomonc6998732015-08-10 12:01:15 -070068 return SkToBool(kReadsLocalCoords_Flag & fFlags);
bsalomon7765a472015-07-08 11:26:37 -070069 }
70
71 /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
72 color output ? */
73 bool canTweakAlphaForCoverage() const {
bsalomonc6998732015-08-10 12:01:15 -070074 return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
bsalomon7765a472015-07-08 11:26:37 -070075 }
76
77 /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
78 so get the color)? */
79 bool getOverrideColorIfSet(GrColor* overrideColor) const {
bsalomonc6998732015-08-10 12:01:15 -070080 if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
81 SkASSERT(SkToBool(kReadsColor_Flag & fFlags));
bsalomon7765a472015-07-08 11:26:37 -070082 if (overrideColor) {
83 *overrideColor = fOverrideColor;
84 }
85 return true;
86 }
87 return false;
88 }
89
bsalomon2d563032015-08-13 07:08:31 -070090 /**
91 * Returns true if the pipeline's color output will be affected by the existing render target
92 * destination pixel values (meaning we need to be careful with overlapping draws). Note that we
93 * can conflate coverage and color, so the destination color may still bleed into pixels that
94 * have partial coverage, even if this function returns false.
95 *
Brian Salomon92aee3d2016-12-21 09:20:25 -050096 * The above comment seems incorrect for the use case. This function is used to turn two
bsalomon2d563032015-08-13 07:08:31 -070097 * overlapping draws into a single draw (really to stencil multiple paths and do a single
98 * cover). It seems that what really matters is whether the dst is read for color OR for
99 * coverage.
100 */
101 bool willColorBlendWithDst() const { return SkToBool(kWillColorBlendWithDst_Flag & fFlags); }
102
bsalomon7765a472015-07-08 11:26:37 -0700103private:
104 enum {
105 // If this is not set the primitive processor need not produce a color output
bsalomonc6998732015-08-10 12:01:15 -0700106 kReadsColor_Flag = 0x1,
bsalomon7765a472015-07-08 11:26:37 -0700107
108 // If this is not set the primitive processor need not produce a coverage output
bsalomonc6998732015-08-10 12:01:15 -0700109 kReadsCoverage_Flag = 0x2,
bsalomon7765a472015-07-08 11:26:37 -0700110
111 // If this is not set the primitive processor need not produce local coordinates
bsalomonc6998732015-08-10 12:01:15 -0700112 kReadsLocalCoords_Flag = 0x4,
bsalomon7765a472015-07-08 11:26:37 -0700113
114 // If this flag is set then the primitive processor may produce color*coverage as
115 // its color output (and not output a separate coverage).
bsalomonc6998732015-08-10 12:01:15 -0700116 kCanTweakAlphaForCoverage_Flag = 0x8,
bsalomon7765a472015-07-08 11:26:37 -0700117
118 // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
119 // output color. If not set fOverrideColor is to be ignored.
bsalomonc6998732015-08-10 12:01:15 -0700120 kUseOverrideColor_Flag = 0x10,
bsalomon2d563032015-08-13 07:08:31 -0700121
122 kWillColorBlendWithDst_Flag = 0x20,
bsalomon7765a472015-07-08 11:26:37 -0700123 };
124
125 uint32_t fFlags;
126 GrColor fOverrideColor;
127
128 friend class GrPipeline; // To initialize this
joshualitt8072caa2015-02-12 14:20:52 -0800129};
130
131/*
joshualitt8072caa2015-02-12 14:20:52 -0800132 * GrPrimitiveProcessor defines an interface which all subclasses must implement. All
133 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
134 * pipelines, and they must provide some notion of equality
135 */
136class GrPrimitiveProcessor : public GrProcessor {
137public:
joshualitt8072caa2015-02-12 14:20:52 -0800138 // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
139 // we put these calls on the base class to prevent having to cast
140 virtual bool willUseGeoShader() const = 0;
141
joshualitt8072caa2015-02-12 14:20:52 -0800142 struct Attribute {
143 Attribute()
halcanary96fcdcc2015-08-27 07:41:13 -0700144 : fName(nullptr)
joshualitt8072caa2015-02-12 14:20:52 -0800145 , fType(kFloat_GrVertexAttribType)
146 , fOffset(0) {}
bsalomon6cb807b2016-08-17 11:33:39 -0700147 Attribute(const char* name, GrVertexAttribType type, GrSLPrecision precision)
joshualitt8072caa2015-02-12 14:20:52 -0800148 : fName(name)
149 , fType(type)
senorblancof2539d52015-05-20 14:03:42 -0700150 , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
151 , fPrecision(precision) {}
joshualitt8072caa2015-02-12 14:20:52 -0800152 const char* fName;
153 GrVertexAttribType fType;
154 size_t fOffset;
senorblancof2539d52015-05-20 14:03:42 -0700155 GrSLPrecision fPrecision;
joshualitt8072caa2015-02-12 14:20:52 -0800156 };
157
bsalomon7dbd45d2016-03-23 10:40:53 -0700158 int numAttribs() const { return fAttribs.count(); }
159 const Attribute& getAttrib(int index) const { return fAttribs[index]; }
joshualitt8072caa2015-02-12 14:20:52 -0800160
161 // Returns the vertex stride of the GP. A common use case is to request geometry from a
Robert Phillipsf2361d22016-10-25 14:20:06 -0400162 // GrOpList based off of the stride, and to populate this memory using an implicit array of
joshualitt8072caa2015-02-12 14:20:52 -0800163 // structs. In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
164 size_t getVertexStride() const { return fVertexStride; }
165
166 /**
wangyixa7f4c432015-08-20 07:25:02 -0700167 * Computes a transformKey from an array of coord transforms. Will only look at the first
168 * <numCoords> transforms in the array.
169 *
170 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800171 */
wangyixa7f4c432015-08-20 07:25:02 -0700172 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
173 int numCoords) const;
joshualitt8072caa2015-02-12 14:20:52 -0800174
175 /**
176 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
177 * processor's GL backend implementation.
wangyixa7f4c432015-08-20 07:25:02 -0700178 *
179 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800180 */
Brian Salomon94efbf52016-11-29 13:43:05 -0500181 virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800182
183
184 /** Returns a new instance of the appropriate *GL* implementation class
185 for the given GrProcessor; caller is responsible for deleting
186 the object. */
Brian Salomon94efbf52016-11-29 13:43:05 -0500187 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800188
ethannicholas22793252016-01-30 09:59:10 -0800189 virtual bool isPathRendering() const { return false; }
joshualitt8072caa2015-02-12 14:20:52 -0800190
halcanary9d524f22016-03-29 09:03:52 -0700191 virtual GrPixelLocalStorageState getPixelLocalStorageState() const {
ethannicholas22793252016-01-30 09:59:10 -0800192 return kDisabled_GrPixelLocalStorageState;
193 }
194
195 /**
196 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
197 */
198 virtual const char* getDestColorOverride() const { return nullptr; }
halcanary9d524f22016-03-29 09:03:52 -0700199
ethannicholas28ef4452016-03-25 09:26:03 -0700200 virtual float getSampleShading() const {
201 return 0.0;
202 }
203
dvonbeck9b03e7b2016-08-01 11:01:56 -0700204 /* Sub-class should override and return true if this primitive processor implements the distance
205 * vector field, a field of vectors to the nearest point in the edge of the shape. */
206 virtual bool implementsDistanceVector() const { return false; }
207
joshualitt8072caa2015-02-12 14:20:52 -0800208protected:
bsalomon7dbd45d2016-03-23 10:40:53 -0700209 GrPrimitiveProcessor() : fVertexStride(0) {}
joshualitt8072caa2015-02-12 14:20:52 -0800210
bsalomon7dbd45d2016-03-23 10:40:53 -0700211 enum { kPreallocAttribCnt = 8 };
212 SkSTArray<kPreallocAttribCnt, Attribute> fAttribs;
joshualitt8072caa2015-02-12 14:20:52 -0800213 size_t fVertexStride;
214
215private:
Mike Kleinfc6c37b2016-09-27 09:34:10 -0400216 void notifyRefCntIsZero() const final {}
joshualitt8072caa2015-02-12 14:20:52 -0800217 virtual bool hasExplicitLocalCoords() const = 0;
218
joshualitt8072caa2015-02-12 14:20:52 -0800219 typedef GrProcessor INHERITED;
220};
221
222#endif