blob: ddebd2171f2e903dffb733599fb7df945717c4dc [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"
Brian Salomonee783962018-08-01 09:55:10 -040013#include "GrProxyRef.h"
joshualitt8072caa2015-02-12 14:20:52 -080014#include "GrShaderVar.h"
15
Brian Salomonf7dcd762018-07-30 14:48:15 -040016class GrCoordTransform;
17
joshualitt8072caa2015-02-12 14:20:52 -080018/*
19 * The GrPrimitiveProcessor represents some kind of geometric primitive. This includes the shape
20 * of the primitive and the inherent color of the primitive. The GrPrimitiveProcessor is
21 * responsible for providing a color and coverage input into the Ganesh rendering pipeline. Through
22 * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
23 * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
Brian Salomon09d994e2016-12-21 11:14:46 -050024 * functionality.
joshualitt8072caa2015-02-12 14:20:52 -080025 *
26 * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
Brian Salomoncb30bb22017-02-12 09:28:54 -050027 * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final
28 * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
29 * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
Brian Salomona811b122017-03-30 08:21:32 -040030 * getProcessorAnalysisInputs implementation. These seed values are processed by the
Brian Salomon5298dc82017-02-22 11:52:03 -050031 * subsequent
Brian Salomon92aee3d2016-12-21 09:20:25 -050032 * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
33 * the applyPipelineOptimizations call, where the op can use the information to inform decisions
34 * about GrPrimitiveProcessor creation.
joshualitt8072caa2015-02-12 14:20:52 -080035 */
36
egdaniele659a582015-11-13 09:55:43 -080037class GrGLSLPrimitiveProcessor;
joshualitt8072caa2015-02-12 14:20:52 -080038
joshualitt8072caa2015-02-12 14:20:52 -080039/*
joshualitt8072caa2015-02-12 14:20:52 -080040 * GrPrimitiveProcessor defines an interface which all subclasses must implement. All
41 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
42 * pipelines, and they must provide some notion of equality
43 */
Brian Salomone782f842018-07-31 13:53:11 -040044class GrPrimitiveProcessor : public GrProcessor, public GrProgramElement {
joshualitt8072caa2015-02-12 14:20:52 -080045public:
Brian Salomone782f842018-07-31 13:53:11 -040046 class TextureSampler;
47
Brian Salomon92be2f72018-06-19 14:33:47 -040048 /** Describes a vertex or instance attribute. */
Brian Salomon70132d02018-05-29 15:33:06 -040049 class Attribute {
50 public:
Brian Salomon70132d02018-05-29 15:33:06 -040051 constexpr Attribute() = default;
Brian Salomon92be2f72018-06-19 14:33:47 -040052 constexpr Attribute(const char* name, GrVertexAttribType type) : fName(name), fType(type) {}
53 constexpr Attribute(const Attribute&) = default;
Brian Salomon70132d02018-05-29 15:33:06 -040054
Brian Salomon92be2f72018-06-19 14:33:47 -040055 Attribute& operator=(const Attribute&) = default;
Brian Salomon70132d02018-05-29 15:33:06 -040056
Brian Salomon92be2f72018-06-19 14:33:47 -040057 constexpr bool isInitialized() const { return SkToBool(fName); }
58
59 constexpr const char* name() const { return fName; }
60 constexpr GrVertexAttribType type() const { return fType; }
61
62 inline constexpr size_t size() const;
63 constexpr size_t sizeAlign4() const { return SkAlign4(this->size()); }
Brian Salomon70132d02018-05-29 15:33:06 -040064
65 GrShaderVar asShaderVar() const {
66 return {fName, GrVertexAttribTypeToSLType(fType), GrShaderVar::kIn_TypeModifier};
67 }
68
69 private:
70 const char* fName = nullptr;
71 GrVertexAttribType fType = kFloat_GrVertexAttribType;
joshualitt8072caa2015-02-12 14:20:52 -080072 };
73
Brian Salomon92be2f72018-06-19 14:33:47 -040074 GrPrimitiveProcessor(ClassID);
Ethan Nicholasabff9562017-10-09 10:54:08 -040075
Brian Salomone782f842018-07-31 13:53:11 -040076 int numTextureSamplers() const { return fTextureSamplerCnt; }
77 const TextureSampler& textureSampler(int index) const;
Brian Salomon92be2f72018-06-19 14:33:47 -040078 int numVertexAttributes() const { return fVertexAttributeCnt; }
79 const Attribute& vertexAttribute(int i) const;
80 int numInstanceAttributes() const { return fInstanceAttributeCnt; }
81 const Attribute& instanceAttribute(int i) const;
joshualitt8072caa2015-02-12 14:20:52 -080082
Brian Salomon92be2f72018-06-19 14:33:47 -040083 bool hasVertexAttributes() const { return SkToBool(fVertexAttributeCnt); }
84 bool hasInstanceAttributes() const { return SkToBool(fInstanceAttributeCnt); }
Chris Dalton1d616352017-05-31 12:51:23 -060085
Brian Salomon92be2f72018-06-19 14:33:47 -040086#ifdef SK_DEBUG
Chris Dalton1d616352017-05-31 12:51:23 -060087 /**
Brian Salomon92be2f72018-06-19 14:33:47 -040088 * A common practice is to populate the the vertex/instance's memory using an implicit array of
89 * structs. In this case, it is best to assert that:
90 * debugOnly_stride == sizeof(struct) and
91 * offsetof(struct, field[i]) == debugOnly_AttributeOffset(i)
92 * In general having Op subclasses assert that attribute offsets and strides agree with their
93 * tessellation code's expectations is good practice.
94 * However, these functions walk the attributes to compute offsets and call virtual functions
95 * to access the attributes. Thus, they are only available in debug builds.
Chris Dalton1d616352017-05-31 12:51:23 -060096 */
Brian Salomon92be2f72018-06-19 14:33:47 -040097 size_t debugOnly_vertexStride() const;
98 size_t debugOnly_instanceStride() const;
99 size_t debugOnly_vertexAttributeOffset(int) const;
100 size_t debugOnly_instanceAttributeOffset(int) const;
101#endif
Chris Dalton1d616352017-05-31 12:51:23 -0600102
103 // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
104 // we put these calls on the base class to prevent having to cast
105 virtual bool willUseGeoShader() const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800106
107 /**
wangyixa7f4c432015-08-20 07:25:02 -0700108 * Computes a transformKey from an array of coord transforms. Will only look at the first
109 * <numCoords> transforms in the array.
110 *
111 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800112 */
wangyixa7f4c432015-08-20 07:25:02 -0700113 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
114 int numCoords) const;
joshualitt8072caa2015-02-12 14:20:52 -0800115
116 /**
117 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
118 * processor's GL backend implementation.
wangyixa7f4c432015-08-20 07:25:02 -0700119 *
120 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800121 */
Brian Salomon94efbf52016-11-29 13:43:05 -0500122 virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800123
124
125 /** Returns a new instance of the appropriate *GL* implementation class
126 for the given GrProcessor; caller is responsible for deleting
127 the object. */
Brian Salomon94efbf52016-11-29 13:43:05 -0500128 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800129
ethannicholas22793252016-01-30 09:59:10 -0800130 virtual bool isPathRendering() const { return false; }
joshualitt8072caa2015-02-12 14:20:52 -0800131
ethannicholas22793252016-01-30 09:59:10 -0800132 /**
133 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
134 */
135 virtual const char* getDestColorOverride() const { return nullptr; }
halcanary9d524f22016-03-29 09:03:52 -0700136
Brian Salomon92be2f72018-06-19 14:33:47 -0400137 virtual float getSampleShading() const { return 0.0; }
ethannicholas28ef4452016-03-25 09:26:03 -0700138
Brian Salomone782f842018-07-31 13:53:11 -0400139 bool instantiate(GrResourceProvider*) const;
140
joshualitt8072caa2015-02-12 14:20:52 -0800141protected:
Brian Salomone782f842018-07-31 13:53:11 -0400142 void setVertexAttributeCnt(int cnt) {
143 SkASSERT(cnt >= 0);
144 fVertexAttributeCnt = cnt;
145 }
146 void setInstanceAttributeCnt(int cnt) {
147 SkASSERT(cnt >= 0);
148 fInstanceAttributeCnt = cnt;
149 }
150 void setTextureSamplerCnt(int cnt) {
151 SkASSERT(cnt >= 0);
152 fTextureSamplerCnt = cnt;
153 }
154
155 /**
156 * Helper for implementing onTextureSampler(). E.g.:
157 * return IthTexureSampler(i, fMyFirstSampler, fMySecondSampler, fMyThirdSampler);
158 */
159 template <typename... Args>
160 static const TextureSampler& IthTextureSampler(int i, const TextureSampler& samp0,
161 const Args&... samps) {
162 return (0 == i) ? samp0 : IthTextureSampler(i - 1, samps...);
163 }
164 inline static const TextureSampler& IthTextureSampler(int i);
joshualitt8072caa2015-02-12 14:20:52 -0800165
166private:
Brian Salomone782f842018-07-31 13:53:11 -0400167 void addPendingIOs() const final;
168 void removeRefs() const final;
169 void pendingIOComplete() const final;
Mike Kleinfc6c37b2016-09-27 09:34:10 -0400170 void notifyRefCntIsZero() const final {}
joshualitt8072caa2015-02-12 14:20:52 -0800171
Brian Salomon92be2f72018-06-19 14:33:47 -0400172 virtual const Attribute& onVertexAttribute(int) const = 0;
173 virtual const Attribute& onInstanceAttribute(int) const = 0;
Brian Salomone782f842018-07-31 13:53:11 -0400174 virtual const TextureSampler& onTextureSampler(int) const { return IthTextureSampler(0); }
Chris Dalton1d616352017-05-31 12:51:23 -0600175
Brian Salomon92be2f72018-06-19 14:33:47 -0400176 int fVertexAttributeCnt = 0;
177 int fInstanceAttributeCnt = 0;
Brian Salomone782f842018-07-31 13:53:11 -0400178 int fTextureSamplerCnt = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800179 typedef GrProcessor INHERITED;
180};
181
Brian Salomon92be2f72018-06-19 14:33:47 -0400182//////////////////////////////////////////////////////////////////////////////
183
184/**
Brian Salomone782f842018-07-31 13:53:11 -0400185 * Used to represent a texture that is required by a GrPrimitiveProcessor. It holds a GrTextureProxy
186 * along with an associated GrSamplerState. TextureSamplers don't perform any coord manipulation to
187 * account for texture origin.
188 */
189class GrPrimitiveProcessor::TextureSampler {
190public:
191 TextureSampler() = default;
192
193 TextureSampler(sk_sp<GrTextureProxy>, const GrSamplerState&, GrShaderFlags visibility);
194
195 explicit TextureSampler(sk_sp<GrTextureProxy>,
196 GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
197 GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
198 GrShaderFlags visibility = kFragment_GrShaderFlag);
199
200 TextureSampler(const TextureSampler&) = delete;
201 TextureSampler& operator=(const TextureSampler&) = delete;
202
203 void reset(sk_sp<GrTextureProxy>, const GrSamplerState&,
204 GrShaderFlags visibility = kFragment_GrShaderFlag);
205 void reset(sk_sp<GrTextureProxy>,
206 GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
207 GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
208 GrShaderFlags visibility = kFragment_GrShaderFlag);
209
210 bool instantiate(GrResourceProvider* resourceProvider) const {
211 return SkToBool(fProxyRef.get()->instantiate(resourceProvider));
212 }
213
214 // 'peekTexture' should only ever be called after a successful 'instantiate' call
215 GrTexture* peekTexture() const {
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400216 SkASSERT(fProxyRef.get()->peekTexture());
217 return fProxyRef.get()->peekTexture();
Brian Salomone782f842018-07-31 13:53:11 -0400218 }
219
Brian Salomonee783962018-08-01 09:55:10 -0400220 GrTextureProxy* proxy() const { return fProxyRef.get(); }
Brian Salomone782f842018-07-31 13:53:11 -0400221 GrShaderFlags visibility() const { return fVisibility; }
222 const GrSamplerState& samplerState() const { return fSamplerState; }
223
224 bool isInitialized() const { return SkToBool(fProxyRef.get()); }
225 /**
226 * For internal use by GrPrimitiveProcessor.
227 */
Brian Salomonee783962018-08-01 09:55:10 -0400228 const GrTextureProxyRef* proxyRef() const { return &fProxyRef; }
Brian Salomone782f842018-07-31 13:53:11 -0400229
230private:
Brian Salomonee783962018-08-01 09:55:10 -0400231 GrTextureProxyRef fProxyRef;
Brian Salomone782f842018-07-31 13:53:11 -0400232 GrSamplerState fSamplerState;
233 GrShaderFlags fVisibility = kNone_GrShaderFlags;
234};
235
236const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::IthTextureSampler(int i) {
237 SK_ABORT("Illegal texture sampler index");
238 static const TextureSampler kBogus;
239 return kBogus;
240}
241
242//////////////////////////////////////////////////////////////////////////////
243
244/**
Brian Salomon92be2f72018-06-19 14:33:47 -0400245 * Returns the size of the attrib type in bytes.
246 * This was moved from include/private/GrTypesPriv.h in service of Skia dependents that build
247 * with C++11.
248 */
249static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
250 switch (type) {
251 case kFloat_GrVertexAttribType:
252 return sizeof(float);
253 case kFloat2_GrVertexAttribType:
254 return 2 * sizeof(float);
255 case kFloat3_GrVertexAttribType:
256 return 3 * sizeof(float);
257 case kFloat4_GrVertexAttribType:
258 return 4 * sizeof(float);
259 case kHalf_GrVertexAttribType:
260 return sizeof(float);
261 case kHalf2_GrVertexAttribType:
262 return 2 * sizeof(float);
263 case kHalf3_GrVertexAttribType:
264 return 3 * sizeof(float);
265 case kHalf4_GrVertexAttribType:
266 return 4 * sizeof(float);
267 case kInt2_GrVertexAttribType:
268 return 2 * sizeof(int32_t);
269 case kInt3_GrVertexAttribType:
270 return 3 * sizeof(int32_t);
271 case kInt4_GrVertexAttribType:
272 return 4 * sizeof(int32_t);
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400273 case kByte_GrVertexAttribType:
274 return 1 * sizeof(char);
275 case kByte2_GrVertexAttribType:
276 return 2 * sizeof(char);
277 case kByte3_GrVertexAttribType:
278 return 3 * sizeof(char);
279 case kByte4_GrVertexAttribType:
280 return 4 * sizeof(char);
281 case kUByte_GrVertexAttribType:
282 return 1 * sizeof(char);
283 case kUByte2_GrVertexAttribType:
284 return 2 * sizeof(char);
285 case kUByte3_GrVertexAttribType:
286 return 3 * sizeof(char);
287 case kUByte4_GrVertexAttribType:
288 return 4 * sizeof(char);
Brian Salomon92be2f72018-06-19 14:33:47 -0400289 case kUByte_norm_GrVertexAttribType:
290 return 1 * sizeof(char);
291 case kUByte4_norm_GrVertexAttribType:
292 return 4 * sizeof(char);
293 case kShort2_GrVertexAttribType:
294 return 2 * sizeof(int16_t);
295 case kUShort2_GrVertexAttribType: // fall through
296 case kUShort2_norm_GrVertexAttribType:
297 return 2 * sizeof(uint16_t);
298 case kInt_GrVertexAttribType:
299 return sizeof(int32_t);
300 case kUint_GrVertexAttribType:
301 return sizeof(uint32_t);
302 }
303 // GCC fails because SK_ABORT evaluates to non constexpr. clang and cl.exe think this is
304 // unreachable and don't complain.
305#if defined(__clang__) || !defined(__GNUC__)
306 SK_ABORT("Unsupported type conversion");
307#endif
308 return 0;
309}
310
311constexpr size_t GrPrimitiveProcessor::Attribute::size() const {
312 return GrVertexAttribTypeSize(fType);
313}
314
joshualitt8072caa2015-02-12 14:20:52 -0800315#endif