blob: 4becb547ccb9e14429be836351f12949a8944976 [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"
Brian Salomon7eae3e02018-08-07 14:02:38 +000012#include "GrNonAtomicRef.h"
joshualitt8072caa2015-02-12 14:20:52 -080013#include "GrProcessor.h"
Brian Salomonee783962018-08-01 09:55:10 -040014#include "GrProxyRef.h"
joshualitt8072caa2015-02-12 14:20:52 -080015#include "GrShaderVar.h"
16
Brian Salomonf7dcd762018-07-30 14:48:15 -040017class GrCoordTransform;
18
joshualitt8072caa2015-02-12 14:20:52 -080019/*
20 * The GrPrimitiveProcessor represents some kind of geometric primitive. This includes the shape
21 * of the primitive and the inherent color of the primitive. The GrPrimitiveProcessor is
22 * responsible for providing a color and coverage input into the Ganesh rendering pipeline. Through
23 * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
24 * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
Brian Salomon09d994e2016-12-21 11:14:46 -050025 * functionality.
joshualitt8072caa2015-02-12 14:20:52 -080026 *
27 * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
Brian Salomoncb30bb22017-02-12 09:28:54 -050028 * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final
29 * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
30 * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
Brian Salomona811b122017-03-30 08:21:32 -040031 * getProcessorAnalysisInputs implementation. These seed values are processed by the
Brian Salomon5298dc82017-02-22 11:52:03 -050032 * subsequent
Brian Salomon92aee3d2016-12-21 09:20:25 -050033 * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
34 * the applyPipelineOptimizations call, where the op can use the information to inform decisions
35 * about GrPrimitiveProcessor creation.
joshualitt8072caa2015-02-12 14:20:52 -080036 */
37
egdaniele659a582015-11-13 09:55:43 -080038class GrGLSLPrimitiveProcessor;
joshualitt8072caa2015-02-12 14:20:52 -080039
Brian Salomon7eae3e02018-08-07 14:02:38 +000040/**
joshualitt8072caa2015-02-12 14:20:52 -080041 * GrPrimitiveProcessor defines an interface which all subclasses must implement. All
42 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
43 * pipelines, and they must provide some notion of equality
Brian Salomon7eae3e02018-08-07 14:02:38 +000044 *
45 * TODO: This class does not really need to be ref counted. Instances should be allocated using
46 * GrOpFlushState's arena and destroyed when the arena is torn down.
joshualitt8072caa2015-02-12 14:20:52 -080047 */
Brian Salomon7eae3e02018-08-07 14:02:38 +000048class GrPrimitiveProcessor : public GrProcessor, public GrNonAtomicRef<GrPrimitiveProcessor> {
joshualitt8072caa2015-02-12 14:20:52 -080049public:
Brian Salomone782f842018-07-31 13:53:11 -040050 class TextureSampler;
51
Brian Salomon92be2f72018-06-19 14:33:47 -040052 /** Describes a vertex or instance attribute. */
Brian Salomon70132d02018-05-29 15:33:06 -040053 class Attribute {
54 public:
Brian Salomon70132d02018-05-29 15:33:06 -040055 constexpr Attribute() = default;
Brian Salomon92be2f72018-06-19 14:33:47 -040056 constexpr Attribute(const char* name, GrVertexAttribType type) : fName(name), fType(type) {}
57 constexpr Attribute(const Attribute&) = default;
Brian Salomon70132d02018-05-29 15:33:06 -040058
Brian Salomon92be2f72018-06-19 14:33:47 -040059 Attribute& operator=(const Attribute&) = default;
Brian Salomon70132d02018-05-29 15:33:06 -040060
Brian Salomon92be2f72018-06-19 14:33:47 -040061 constexpr bool isInitialized() const { return SkToBool(fName); }
62
63 constexpr const char* name() const { return fName; }
64 constexpr GrVertexAttribType type() const { return fType; }
65
66 inline constexpr size_t size() const;
67 constexpr size_t sizeAlign4() const { return SkAlign4(this->size()); }
Brian Salomon70132d02018-05-29 15:33:06 -040068
69 GrShaderVar asShaderVar() const {
70 return {fName, GrVertexAttribTypeToSLType(fType), GrShaderVar::kIn_TypeModifier};
71 }
72
73 private:
74 const char* fName = nullptr;
75 GrVertexAttribType fType = kFloat_GrVertexAttribType;
joshualitt8072caa2015-02-12 14:20:52 -080076 };
77
Brian Salomon92be2f72018-06-19 14:33:47 -040078 GrPrimitiveProcessor(ClassID);
Ethan Nicholasabff9562017-10-09 10:54:08 -040079
Brian Salomone782f842018-07-31 13:53:11 -040080 int numTextureSamplers() const { return fTextureSamplerCnt; }
81 const TextureSampler& textureSampler(int index) const;
Brian Salomon92be2f72018-06-19 14:33:47 -040082 int numVertexAttributes() const { return fVertexAttributeCnt; }
83 const Attribute& vertexAttribute(int i) const;
84 int numInstanceAttributes() const { return fInstanceAttributeCnt; }
85 const Attribute& instanceAttribute(int i) const;
joshualitt8072caa2015-02-12 14:20:52 -080086
Brian Salomon92be2f72018-06-19 14:33:47 -040087 bool hasVertexAttributes() const { return SkToBool(fVertexAttributeCnt); }
88 bool hasInstanceAttributes() const { return SkToBool(fInstanceAttributeCnt); }
Chris Dalton1d616352017-05-31 12:51:23 -060089
Brian Salomon92be2f72018-06-19 14:33:47 -040090#ifdef SK_DEBUG
Chris Dalton1d616352017-05-31 12:51:23 -060091 /**
Brian Salomon92be2f72018-06-19 14:33:47 -040092 * A common practice is to populate the the vertex/instance's memory using an implicit array of
93 * structs. In this case, it is best to assert that:
94 * debugOnly_stride == sizeof(struct) and
95 * offsetof(struct, field[i]) == debugOnly_AttributeOffset(i)
96 * In general having Op subclasses assert that attribute offsets and strides agree with their
97 * tessellation code's expectations is good practice.
98 * However, these functions walk the attributes to compute offsets and call virtual functions
99 * to access the attributes. Thus, they are only available in debug builds.
Chris Dalton1d616352017-05-31 12:51:23 -0600100 */
Brian Salomon92be2f72018-06-19 14:33:47 -0400101 size_t debugOnly_vertexStride() const;
102 size_t debugOnly_instanceStride() const;
103 size_t debugOnly_vertexAttributeOffset(int) const;
104 size_t debugOnly_instanceAttributeOffset(int) const;
105#endif
Chris Dalton1d616352017-05-31 12:51:23 -0600106
107 // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
108 // we put these calls on the base class to prevent having to cast
109 virtual bool willUseGeoShader() const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800110
111 /**
wangyixa7f4c432015-08-20 07:25:02 -0700112 * Computes a transformKey from an array of coord transforms. Will only look at the first
113 * <numCoords> transforms in the array.
114 *
115 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800116 */
wangyixa7f4c432015-08-20 07:25:02 -0700117 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
118 int numCoords) const;
joshualitt8072caa2015-02-12 14:20:52 -0800119
120 /**
121 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
122 * processor's GL backend implementation.
wangyixa7f4c432015-08-20 07:25:02 -0700123 *
124 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800125 */
Brian Salomon94efbf52016-11-29 13:43:05 -0500126 virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800127
128
129 /** Returns a new instance of the appropriate *GL* implementation class
130 for the given GrProcessor; caller is responsible for deleting
131 the object. */
Brian Salomon94efbf52016-11-29 13:43:05 -0500132 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800133
ethannicholas22793252016-01-30 09:59:10 -0800134 virtual bool isPathRendering() const { return false; }
joshualitt8072caa2015-02-12 14:20:52 -0800135
ethannicholas22793252016-01-30 09:59:10 -0800136 /**
137 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
138 */
139 virtual const char* getDestColorOverride() const { return nullptr; }
halcanary9d524f22016-03-29 09:03:52 -0700140
Brian Salomon92be2f72018-06-19 14:33:47 -0400141 virtual float getSampleShading() const { return 0.0; }
ethannicholas28ef4452016-03-25 09:26:03 -0700142
joshualitt8072caa2015-02-12 14:20:52 -0800143protected:
Brian Salomone782f842018-07-31 13:53:11 -0400144 void setVertexAttributeCnt(int cnt) {
145 SkASSERT(cnt >= 0);
146 fVertexAttributeCnt = cnt;
147 }
148 void setInstanceAttributeCnt(int cnt) {
149 SkASSERT(cnt >= 0);
150 fInstanceAttributeCnt = cnt;
151 }
152 void setTextureSamplerCnt(int cnt) {
153 SkASSERT(cnt >= 0);
154 fTextureSamplerCnt = cnt;
155 }
156
157 /**
158 * Helper for implementing onTextureSampler(). E.g.:
159 * return IthTexureSampler(i, fMyFirstSampler, fMySecondSampler, fMyThirdSampler);
160 */
161 template <typename... Args>
162 static const TextureSampler& IthTextureSampler(int i, const TextureSampler& samp0,
163 const Args&... samps) {
164 return (0 == i) ? samp0 : IthTextureSampler(i - 1, samps...);
165 }
166 inline static const TextureSampler& IthTextureSampler(int i);
joshualitt8072caa2015-02-12 14:20:52 -0800167
168private:
Brian Salomon92be2f72018-06-19 14:33:47 -0400169 virtual const Attribute& onVertexAttribute(int) const = 0;
170 virtual const Attribute& onInstanceAttribute(int) const = 0;
Brian Salomone782f842018-07-31 13:53:11 -0400171 virtual const TextureSampler& onTextureSampler(int) const { return IthTextureSampler(0); }
Chris Dalton1d616352017-05-31 12:51:23 -0600172
Brian Salomon92be2f72018-06-19 14:33:47 -0400173 int fVertexAttributeCnt = 0;
174 int fInstanceAttributeCnt = 0;
Brian Salomone782f842018-07-31 13:53:11 -0400175 int fTextureSamplerCnt = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800176 typedef GrProcessor INHERITED;
177};
178
Brian Salomon92be2f72018-06-19 14:33:47 -0400179//////////////////////////////////////////////////////////////////////////////
180
181/**
Brian Salomone782f842018-07-31 13:53:11 -0400182 * Used to represent a texture that is required by a GrPrimitiveProcessor. It holds a GrTextureProxy
183 * along with an associated GrSamplerState. TextureSamplers don't perform any coord manipulation to
184 * account for texture origin.
185 */
186class GrPrimitiveProcessor::TextureSampler {
187public:
188 TextureSampler() = default;
189
Brian Salomon7eae3e02018-08-07 14:02:38 +0000190 TextureSampler(GrTextureType, GrPixelConfig, const GrSamplerState&, GrShaderFlags visibility);
Brian Salomone782f842018-07-31 13:53:11 -0400191
Brian Salomon7eae3e02018-08-07 14:02:38 +0000192 explicit TextureSampler(GrTextureType, GrPixelConfig,
Brian Salomone782f842018-07-31 13:53:11 -0400193 GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
194 GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
195 GrShaderFlags visibility = kFragment_GrShaderFlag);
196
197 TextureSampler(const TextureSampler&) = delete;
198 TextureSampler& operator=(const TextureSampler&) = delete;
199
Brian Salomon7eae3e02018-08-07 14:02:38 +0000200 void reset(GrTextureType, GrPixelConfig, const GrSamplerState&,
Brian Salomone782f842018-07-31 13:53:11 -0400201 GrShaderFlags visibility = kFragment_GrShaderFlag);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000202 void reset(GrTextureType, GrPixelConfig,
Brian Salomone782f842018-07-31 13:53:11 -0400203 GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
204 GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
205 GrShaderFlags visibility = kFragment_GrShaderFlag);
206
Brian Salomon7eae3e02018-08-07 14:02:38 +0000207 GrTextureType textureType() const { return fTextureType; }
208 GrPixelConfig config() const { return fConfig; }
Brian Salomone782f842018-07-31 13:53:11 -0400209
Brian Salomone782f842018-07-31 13:53:11 -0400210 GrShaderFlags visibility() const { return fVisibility; }
211 const GrSamplerState& samplerState() const { return fSamplerState; }
212
Brian Salomon7eae3e02018-08-07 14:02:38 +0000213 bool isInitialized() const { return fConfig != kUnknown_GrPixelConfig; }
Brian Salomone782f842018-07-31 13:53:11 -0400214
215private:
Brian Salomone782f842018-07-31 13:53:11 -0400216 GrSamplerState fSamplerState;
Brian Salomon7eae3e02018-08-07 14:02:38 +0000217 GrTextureType fTextureType = GrTextureType::k2D;
218 GrPixelConfig fConfig = kUnknown_GrPixelConfig;
Brian Salomone782f842018-07-31 13:53:11 -0400219 GrShaderFlags fVisibility = kNone_GrShaderFlags;
220};
221
222const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::IthTextureSampler(int i) {
223 SK_ABORT("Illegal texture sampler index");
224 static const TextureSampler kBogus;
225 return kBogus;
226}
227
228//////////////////////////////////////////////////////////////////////////////
229
230/**
Brian Salomon92be2f72018-06-19 14:33:47 -0400231 * Returns the size of the attrib type in bytes.
232 * This was moved from include/private/GrTypesPriv.h in service of Skia dependents that build
233 * with C++11.
234 */
235static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
236 switch (type) {
237 case kFloat_GrVertexAttribType:
238 return sizeof(float);
239 case kFloat2_GrVertexAttribType:
240 return 2 * sizeof(float);
241 case kFloat3_GrVertexAttribType:
242 return 3 * sizeof(float);
243 case kFloat4_GrVertexAttribType:
244 return 4 * sizeof(float);
245 case kHalf_GrVertexAttribType:
246 return sizeof(float);
247 case kHalf2_GrVertexAttribType:
248 return 2 * sizeof(float);
249 case kHalf3_GrVertexAttribType:
250 return 3 * sizeof(float);
251 case kHalf4_GrVertexAttribType:
252 return 4 * sizeof(float);
253 case kInt2_GrVertexAttribType:
254 return 2 * sizeof(int32_t);
255 case kInt3_GrVertexAttribType:
256 return 3 * sizeof(int32_t);
257 case kInt4_GrVertexAttribType:
258 return 4 * sizeof(int32_t);
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400259 case kByte_GrVertexAttribType:
260 return 1 * sizeof(char);
261 case kByte2_GrVertexAttribType:
262 return 2 * sizeof(char);
263 case kByte3_GrVertexAttribType:
264 return 3 * sizeof(char);
265 case kByte4_GrVertexAttribType:
266 return 4 * sizeof(char);
267 case kUByte_GrVertexAttribType:
268 return 1 * sizeof(char);
269 case kUByte2_GrVertexAttribType:
270 return 2 * sizeof(char);
271 case kUByte3_GrVertexAttribType:
272 return 3 * sizeof(char);
273 case kUByte4_GrVertexAttribType:
274 return 4 * sizeof(char);
Brian Salomon92be2f72018-06-19 14:33:47 -0400275 case kUByte_norm_GrVertexAttribType:
276 return 1 * sizeof(char);
277 case kUByte4_norm_GrVertexAttribType:
278 return 4 * sizeof(char);
279 case kShort2_GrVertexAttribType:
280 return 2 * sizeof(int16_t);
281 case kUShort2_GrVertexAttribType: // fall through
282 case kUShort2_norm_GrVertexAttribType:
283 return 2 * sizeof(uint16_t);
284 case kInt_GrVertexAttribType:
285 return sizeof(int32_t);
286 case kUint_GrVertexAttribType:
287 return sizeof(uint32_t);
288 }
289 // GCC fails because SK_ABORT evaluates to non constexpr. clang and cl.exe think this is
290 // unreachable and don't complain.
291#if defined(__clang__) || !defined(__GNUC__)
292 SK_ABORT("Unsupported type conversion");
293#endif
294 return 0;
295}
296
297constexpr size_t GrPrimitiveProcessor::Attribute::size() const {
298 return GrVertexAttribTypeSize(fType);
299}
300
joshualitt8072caa2015-02-12 14:20:52 -0800301#endif