blob: 31667b4b1a40976ff0a322ec0bfbbaa226ebf94b [file] [log] [blame]
joshualittb0a8a372014-09-23 09:50:21 -07001/*
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 GrGeometryProcessor_DEFINED
9#define GrGeometryProcessor_DEFINED
10
Robert Phillips787fd9d2021-03-22 14:48:09 -040011#include "src/gpu/GrColor.h"
Brian Salomon48959462021-08-11 13:01:06 -040012#include "src/gpu/GrFragmentProcessor.h"
Robert Phillips787fd9d2021-03-22 14:48:09 -040013#include "src/gpu/GrProcessor.h"
Brian Salomon48959462021-08-11 13:01:06 -040014#include "src/gpu/GrShaderCaps.h"
Robert Phillips787fd9d2021-03-22 14:48:09 -040015#include "src/gpu/GrShaderVar.h"
16#include "src/gpu/GrSwizzle.h"
Brian Salomon48959462021-08-11 13:01:06 -040017#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
18#include "src/gpu/glsl/GrGLSLUniformHandler.h"
19#include "src/gpu/glsl/GrGLSLVarying.h"
Robert Phillips787fd9d2021-03-22 14:48:09 -040020
Brian Salomon48959462021-08-11 13:01:06 -040021#include <unordered_map>
22
23class GrGLSLFPFragmentBuilder;
Brian Salomon48959462021-08-11 13:01:06 -040024class GrGLSLVaryingHandler;
Robert Phillips787fd9d2021-03-22 14:48:09 -040025class GrGLSLUniformHandler;
Brian Salomon48959462021-08-11 13:01:06 -040026class GrGLSLVertexBuilder;
Robert Phillips787fd9d2021-03-22 14:48:09 -040027
joshualitt9b989322014-12-15 14:16:27 -080028/**
Robert Phillips787fd9d2021-03-22 14:48:09 -040029 * The GrGeometryProcessor represents some kind of geometric primitive. This includes the shape
30 * of the primitive and the inherent color of the primitive. The GrGeometryProcessor is
31 * responsible for providing a color and coverage input into the Ganesh rendering pipeline. Through
32 * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
33 * from the GrGeometryProcessor, so the GrGeometryProcessor must be able to support this
34 * functionality.
35 *
36 * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
37 * GrGeometryProcessor. These loops run on the CPU and to determine known properties of the final
38 * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
39 * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
40 * getProcessorAnalysisInputs implementation. These seed values are processed by the
41 * subsequent stages of the rendering pipeline and the output is then fed back into the GrDrawOp
42 * in the applyPipelineOptimizations call, where the op can use the information to inform
43 * decisions about GrGeometryProcessor creation.
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050044 *
45 * Note that all derived classes should hide their constructors and provide a Make factory
Robert Phillips787fd9d2021-03-22 14:48:09 -040046 * function that takes an arena (except for Tesselation-specific classes). This is because
47 * geometry processors can be created in either the record-time or flush-time arenas which
48 * define their lifetimes (i.e., a DDLs life time in the first case and a single flush in
49 * the second case).
joshualitt9b989322014-12-15 14:16:27 -080050 */
Brian Salomon8c8379b2021-08-11 16:19:06 -040051class GrGeometryProcessor : public GrProcessor {
joshualitt9b989322014-12-15 14:16:27 -080052public:
Brian Salomonf95940b2021-08-09 15:56:24 -040053 /**
Brian Salomond89d4452021-08-09 16:42:36 -040054 * Every GrGeometryProcessor must be capable of creating a subclass of ProgramImpl. The
55 * ProgramImpl emits the shader code that implements the GrGeometryProcessor, is attached to the
56 * generated backend API pipeline/program and used to extract uniform data from
57 * GrGeometryProcessor instances.
Brian Salomonf95940b2021-08-09 15:56:24 -040058 */
59 class ProgramImpl;
60
Robert Phillips787fd9d2021-03-22 14:48:09 -040061 class TextureSampler;
62
63 /** Describes a vertex or instance attribute. */
64 class Attribute {
65 public:
66 constexpr Attribute() = default;
67 constexpr Attribute(const char* name,
68 GrVertexAttribType cpuType,
69 GrSLType gpuType)
70 : fName(name), fCPUType(cpuType), fGPUType(gpuType) {
71 SkASSERT(name && gpuType != kVoid_GrSLType);
72 }
73 constexpr Attribute(const Attribute&) = default;
74
75 Attribute& operator=(const Attribute&) = default;
76
77 constexpr bool isInitialized() const { return fGPUType != kVoid_GrSLType; }
78
79 constexpr const char* name() const { return fName; }
80 constexpr GrVertexAttribType cpuType() const { return fCPUType; }
81 constexpr GrSLType gpuType() const { return fGPUType; }
82
83 inline constexpr size_t size() const;
84 constexpr size_t sizeAlign4() const { return SkAlign4(this->size()); }
85
86 GrShaderVar asShaderVar() const {
87 return {fName, fGPUType, GrShaderVar::TypeModifier::In};
88 }
89
90 private:
91 const char* fName = nullptr;
92 GrVertexAttribType fCPUType = kFloat_GrVertexAttribType;
93 GrSLType fGPUType = kVoid_GrSLType;
94 };
95
96 class Iter {
97 public:
98 Iter() : fCurr(nullptr), fRemaining(0) {}
99 Iter(const Iter& iter) : fCurr(iter.fCurr), fRemaining(iter.fRemaining) {}
100 Iter& operator= (const Iter& iter) {
101 fCurr = iter.fCurr;
102 fRemaining = iter.fRemaining;
103 return *this;
104 }
105 Iter(const Attribute* attrs, int count) : fCurr(attrs), fRemaining(count) {
106 this->skipUninitialized();
107 }
108
109 bool operator!=(const Iter& that) const { return fCurr != that.fCurr; }
110 const Attribute& operator*() const { return *fCurr; }
111 void operator++() {
112 if (fRemaining) {
113 fRemaining--;
114 fCurr++;
115 this->skipUninitialized();
116 }
117 }
118
119 private:
120 void skipUninitialized() {
121 if (!fRemaining) {
122 fCurr = nullptr;
123 } else {
124 while (!fCurr->isInitialized()) {
125 ++fCurr;
126 }
127 }
128 }
129
130 const Attribute* fCurr;
131 int fRemaining;
132 };
133
134 class AttributeSet {
135 public:
136 Iter begin() const { return Iter(fAttributes, fCount); }
137 Iter end() const { return Iter(); }
138
139 int count() const { return fCount; }
140 size_t stride() const { return fStride; }
141
142 private:
143 friend class GrGeometryProcessor;
144
145 void init(const Attribute* attrs, int count) {
146 fAttributes = attrs;
147 fRawCount = count;
148 fCount = 0;
149 fStride = 0;
150 for (int i = 0; i < count; ++i) {
151 if (attrs[i].isInitialized()) {
152 fCount++;
153 fStride += attrs[i].sizeAlign4();
154 }
155 }
156 }
157
158 const Attribute* fAttributes = nullptr;
159 int fRawCount = 0;
160 int fCount = 0;
161 size_t fStride = 0;
162 };
163
164 GrGeometryProcessor(ClassID);
165
166 int numTextureSamplers() const { return fTextureSamplerCnt; }
167 const TextureSampler& textureSampler(int index) const;
168 int numVertexAttributes() const { return fVertexAttributes.fCount; }
169 const AttributeSet& vertexAttributes() const { return fVertexAttributes; }
170 int numInstanceAttributes() const { return fInstanceAttributes.fCount; }
171 const AttributeSet& instanceAttributes() const { return fInstanceAttributes; }
172
173 bool hasVertexAttributes() const { return SkToBool(fVertexAttributes.fCount); }
174 bool hasInstanceAttributes() const { return SkToBool(fInstanceAttributes.fCount); }
175
176 /**
177 * A common practice is to populate the the vertex/instance's memory using an implicit array of
178 * structs. In this case, it is best to assert that:
179 * stride == sizeof(struct)
180 */
181 size_t vertexStride() const { return fVertexAttributes.fStride; }
182 size_t instanceStride() const { return fInstanceAttributes.fStride; }
183
184 bool willUseTessellationShaders() const {
185 return fShaders & (kTessControl_GrShaderFlag | kTessEvaluation_GrShaderFlag);
186 }
187
Robert Phillips787fd9d2021-03-22 14:48:09 -0400188 /**
189 * Computes a key for the transforms owned by an FP based on the shader code that will be
190 * emitted by the primitive processor to implement them.
191 */
192 static uint32_t ComputeCoordTransformsKey(const GrFragmentProcessor& fp);
193
194 static constexpr int kCoordTransformKeyBits = 4;
195
196 /**
Brian Salomon13b28732021-08-06 15:33:58 -0400197 * Adds a key on the GrProcessorKeyBuilder that reflects any variety in the code that the
198 * geometry processor subclass can emit.
Robert Phillips787fd9d2021-03-22 14:48:09 -0400199 */
Brian Salomon13b28732021-08-06 15:33:58 -0400200 virtual void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
Robert Phillips787fd9d2021-03-22 14:48:09 -0400201
202 void getAttributeKey(GrProcessorKeyBuilder* b) const {
203 // Ensure that our CPU and GPU type fields fit together in a 32-bit value, and we never
204 // collide with the "uninitialized" value.
205 static_assert(kGrVertexAttribTypeCount < (1 << 8), "");
206 static_assert(kGrSLTypeCount < (1 << 8), "");
207
208 auto add_attributes = [=](const Attribute* attrs, int attrCount) {
209 for (int i = 0; i < attrCount; ++i) {
210 const Attribute& attr = attrs[i];
211 b->appendComment(attr.isInitialized() ? attr.name() : "unusedAttr");
Jim Van Verth14a9b082021-09-20 14:09:52 +0000212 b->addBits(8, attr.isInitialized() ? attr.cpuType() : 0xff, "attrType");
213 b->addBits(8, attr.isInitialized() ? attr.gpuType() : 0xff, "attrGpuType");
Robert Phillips787fd9d2021-03-22 14:48:09 -0400214 }
215 };
216 b->add32(fVertexAttributes.fRawCount, "numVertexAttributes");
217 add_attributes(fVertexAttributes.fAttributes, fVertexAttributes.fRawCount);
218 b->add32(fInstanceAttributes.fRawCount, "numInstanceAttributes");
219 add_attributes(fInstanceAttributes.fAttributes, fInstanceAttributes.fRawCount);
220 }
221
Brian Salomonf95940b2021-08-09 15:56:24 -0400222 /**
223 * Returns a new instance of the appropriate implementation class for the given
224 * GrGeometryProcessor.
225 */
226 virtual std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const = 0;
Robert Phillips787fd9d2021-03-22 14:48:09 -0400227
joshualittb0a8a372014-09-23 09:50:21 -0700228protected:
Brian Osman2715bf52019-12-06 14:38:47 -0500229 // GPs that need to use either float or ubyte colors can just call this to get a correctly
Brian Osmanc906d252018-12-04 11:17:46 -0500230 // configured Attribute struct
231 static Attribute MakeColorAttribute(const char* name, bool wideColor) {
232 return { name,
Brian Osman2715bf52019-12-06 14:38:47 -0500233 wideColor ? kFloat4_GrVertexAttribType : kUByte4_norm_GrVertexAttribType,
Brian Osmanc906d252018-12-04 11:17:46 -0500234 kHalf4_GrSLType };
235 }
236
Robert Phillips787fd9d2021-03-22 14:48:09 -0400237 void setVertexAttributes(const Attribute* attrs, int attrCount) {
238 fVertexAttributes.init(attrs, attrCount);
239 }
240 void setInstanceAttributes(const Attribute* attrs, int attrCount) {
241 SkASSERT(attrCount >= 0);
242 fInstanceAttributes.init(attrs, attrCount);
243 }
244 void setWillUseTessellationShaders() {
245 fShaders |= kTessControl_GrShaderFlag | kTessEvaluation_GrShaderFlag;
246 }
Robert Phillips787fd9d2021-03-22 14:48:09 -0400247 void setTextureSamplerCnt(int cnt) {
248 SkASSERT(cnt >= 0);
249 fTextureSamplerCnt = cnt;
250 }
251
252 /**
253 * Helper for implementing onTextureSampler(). E.g.:
254 * return IthTexureSampler(i, fMyFirstSampler, fMySecondSampler, fMyThirdSampler);
255 */
256 template <typename... Args>
257 static const TextureSampler& IthTextureSampler(int i, const TextureSampler& samp0,
258 const Args&... samps) {
259 return (0 == i) ? samp0 : IthTextureSampler(i - 1, samps...);
260 }
261 inline static const TextureSampler& IthTextureSampler(int i);
262
joshualittb0a8a372014-09-23 09:50:21 -0700263private:
Robert Phillips787fd9d2021-03-22 14:48:09 -0400264 virtual const TextureSampler& onTextureSampler(int) const { return IthTextureSampler(0); }
265
266 GrShaderFlags fShaders = kVertex_GrShaderFlag | kFragment_GrShaderFlag;
267
268 AttributeSet fVertexAttributes;
269 AttributeSet fInstanceAttributes;
270
271 int fTextureSamplerCnt = 0;
272 using INHERITED = GrProcessor;
joshualittb0a8a372014-09-23 09:50:21 -0700273};
joshualitt56995b52014-12-11 15:44:02 -0800274
Robert Phillips787fd9d2021-03-22 14:48:09 -0400275//////////////////////////////////////////////////////////////////////////////
276
Brian Salomon48959462021-08-11 13:01:06 -0400277class GrGeometryProcessor::ProgramImpl {
278public:
279 using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
280 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
281 /**
282 * Struct of optional varying that replaces the input coords and bool indicating whether the FP
283 * should take a coord param as an argument. The latter may be false if the coords are simply
284 * unused or if the GP has lifted their computation to a varying emitted by the VS.
285 */
286 struct FPCoords {GrShaderVar coordsVarying; bool hasCoordsParam;};
287 using FPCoordsMap = std::unordered_map<const GrFragmentProcessor*, FPCoords>;
288
289 virtual ~ProgramImpl() = default;
290
291 struct EmitArgs {
292 EmitArgs(GrGLSLVertexBuilder* vertBuilder,
Brian Salomon48959462021-08-11 13:01:06 -0400293 GrGLSLFPFragmentBuilder* fragBuilder,
294 GrGLSLVaryingHandler* varyingHandler,
295 GrGLSLUniformHandler* uniformHandler,
296 const GrShaderCaps* caps,
297 const GrGeometryProcessor& geomProc,
298 const char* outputColor,
299 const char* outputCoverage,
300 const SamplerHandle* texSamplers)
301 : fVertBuilder(vertBuilder)
Brian Salomon48959462021-08-11 13:01:06 -0400302 , fFragBuilder(fragBuilder)
303 , fVaryingHandler(varyingHandler)
304 , fUniformHandler(uniformHandler)
305 , fShaderCaps(caps)
306 , fGeomProc(geomProc)
307 , fOutputColor(outputColor)
308 , fOutputCoverage(outputCoverage)
309 , fTexSamplers(texSamplers) {}
310 GrGLSLVertexBuilder* fVertBuilder;
Brian Salomon48959462021-08-11 13:01:06 -0400311 GrGLSLFPFragmentBuilder* fFragBuilder;
312 GrGLSLVaryingHandler* fVaryingHandler;
313 GrGLSLUniformHandler* fUniformHandler;
314 const GrShaderCaps* fShaderCaps;
315 const GrGeometryProcessor& fGeomProc;
316 const char* fOutputColor;
317 const char* fOutputCoverage;
318 const SamplerHandle* fTexSamplers;
319 };
320
321 /**
322 * Emits the code from this geometry processor into the shaders. For any FP in the pipeline that
323 * has its input coords implemented by the GP as a varying, the varying will be accessible in
324 * the returned map and should be used when the FP code is emitted.
325 **/
326 FPCoordsMap emitCode(EmitArgs&, const GrPipeline& pipeline);
327
328 /**
329 * Called after all effect emitCode() functions, to give the processor a chance to write out
330 * additional transformation code now that all uniforms have been emitted.
331 * It generates the final code for assigning transformed coordinates to the varyings recorded
332 * in the call to collectTransforms(). This must happen after FP code emission so that it has
333 * access to any uniforms the FPs registered for uniform sample matrix invocations.
334 */
335 void emitTransformCode(GrGLSLVertexBuilder* vb, GrGLSLUniformHandler* uniformHandler);
336
337 /**
338 * A ProgramImpl instance can be reused with any GrGeometryProcessor that produces the same key.
339 * This function reads data from a GrGeometryProcessor and updates any uniform variables
340 * required by the shaders created in emitCode(). The GrGeometryProcessor parameter is
341 * guaranteed to be of the same type and to have an identical processor key as the
342 * GrGeometryProcessor that created this ProgramImpl.
343 */
344 virtual void setData(const GrGLSLProgramDataManager&,
345 const GrShaderCaps&,
346 const GrGeometryProcessor&) = 0;
347
348 // We use these methods as a temporary back door to inject OpenGL tessellation code. Once
349 // tessellation is supported by SkSL we can remove these.
350 virtual SkString getTessControlShaderGLSL(const GrGeometryProcessor&,
351 const char* versionAndExtensionDecls,
352 const GrGLSLUniformHandler&,
353 const GrShaderCaps&) const {
354 SK_ABORT("Not implemented.");
355 }
356 virtual SkString getTessEvaluationShaderGLSL(const GrGeometryProcessor&,
357 const char* versionAndExtensionDecls,
358 const GrGLSLUniformHandler&,
359 const GrShaderCaps&) const {
360 SK_ABORT("Not implemented.");
361 }
362
363 // GPs that use writeOutputPosition and/or writeLocalCoord must incorporate the matrix type
364 // into their key, and should use this function or one of the other related helpers.
365 static uint32_t ComputeMatrixKey(const GrShaderCaps& caps, const SkMatrix& mat) {
366 if (!caps.reducedShaderMode()) {
367 if (mat.isIdentity()) {
368 return 0b00;
369 }
370 if (mat.isScaleTranslate()) {
371 return 0b01;
372 }
373 }
374 if (!mat.hasPerspective()) {
375 return 0b10;
376 }
377 return 0b11;
378 }
379
380 static uint32_t ComputeMatrixKeys(const GrShaderCaps& shaderCaps,
381 const SkMatrix& viewMatrix,
382 const SkMatrix& localMatrix) {
383 return (ComputeMatrixKey(shaderCaps, viewMatrix) << kMatrixKeyBits) |
384 ComputeMatrixKey(shaderCaps, localMatrix);
385 }
386
387 static uint32_t AddMatrixKeys(const GrShaderCaps& shaderCaps,
388 uint32_t flags,
389 const SkMatrix& viewMatrix,
390 const SkMatrix& localMatrix) {
391 // Shifting to make room for the matrix keys shouldn't lose bits
392 SkASSERT(((flags << (2 * kMatrixKeyBits)) >> (2 * kMatrixKeyBits)) == flags);
393 return (flags << (2 * kMatrixKeyBits)) |
394 ComputeMatrixKeys(shaderCaps, viewMatrix, localMatrix);
395 }
396 static constexpr int kMatrixKeyBits = 2;
397
398protected:
399 void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
400 GrGLSLUniformHandler* uniformHandler,
401 const char* outputName,
402 UniformHandle* colorUniform);
403
404 // A helper for setting the matrix on a uniform handle initialized through
405 // writeOutputPosition or writeLocalCoord. Automatically handles elided uniforms,
406 // scale+translate matrices, and state tracking (if provided state pointer is non-null).
407 static void SetTransform(const GrGLSLProgramDataManager&,
408 const GrShaderCaps&,
409 const UniformHandle& uniform,
410 const SkMatrix& matrix,
411 SkMatrix* state = nullptr);
412
413 struct GrGPArgs {
414 // Used to specify the output variable used by the GP to store its device position. It can
415 // either be a float2 or a float3 (in order to handle perspective). The subclass sets this
416 // in its onEmitCode().
417 GrShaderVar fPositionVar;
418 // Used to specify the variable storing the draw's local coordinates. It can be either a
419 // float2, float3, or void. It can only be void when no FP needs local coordinates. This
420 // variable can be an attribute or local variable, but should not itself be a varying.
421 // ProgramImpl automatically determines if this must be passed to a FS.
422 GrShaderVar fLocalCoordVar;
423 };
424
425 // Helpers for adding code to write the transformed vertex position. The first simple version
426 // just writes a variable named by 'posName' into the position output variable with the
427 // assumption that the position is 2D. The second version transforms the input position by a
428 // view matrix and the output variable is 2D or 3D depending on whether the view matrix is
429 // perspective. Both versions declare the output position variable and will set
430 // GrGPArgs::fPositionVar.
431 static void WriteOutputPosition(GrGLSLVertexBuilder*, GrGPArgs*, const char* posName);
432 static void WriteOutputPosition(GrGLSLVertexBuilder*,
433 GrGLSLUniformHandler*,
434 const GrShaderCaps&,
435 GrGPArgs*,
436 const char* posName,
437 const SkMatrix& viewMatrix,
438 UniformHandle* viewMatrixUniform);
439
440 // Helper to transform an existing variable by a given local matrix (e.g. the inverse view
441 // matrix). It will declare the transformed local coord variable and will set
442 // GrGPArgs::fLocalCoordVar.
443 static void WriteLocalCoord(GrGLSLVertexBuilder*,
444 GrGLSLUniformHandler*,
445 const GrShaderCaps&,
446 GrGPArgs*,
447 GrShaderVar localVar,
448 const SkMatrix& localMatrix,
449 UniformHandle* localMatrixUniform);
450
451private:
452 virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0;
453
454 // Iterates over the FPs beginning with the passed iter to register additional varyings and
455 // uniforms to support VS-promoted local coord evaluation for the FPs.
456 //
457 // This must happen before FP code emission so that the FPs can find the appropriate varying
458 // handles they use in place of explicit coord sampling; it is automatically called after
459 // onEmitCode() returns using the value stored in GpArgs::fLocalCoordVar and
460 // GpArgs::fPositionVar.
461 FPCoordsMap collectTransforms(GrGLSLVertexBuilder* vb,
462 GrGLSLVaryingHandler* varyingHandler,
463 GrGLSLUniformHandler* uniformHandler,
464 const GrShaderVar& localCoordsVar,
465 const GrShaderVar& positionVar,
466 const GrPipeline& pipeline);
467 struct TransformInfo {
468 // The varying that conveys the coordinates to one or more FPs in the FS.
469 GrGLSLVarying varying;
470 // The coordinate to be transformed. varying is computed from this.
471 GrShaderVar inputCoords;
472 // Used to sort so that ancestor FP varyings are initialized before descendant FP varyings.
473 int traversalOrder;
474 };
475 // Populated by collectTransforms() for use in emitTransformCode(). When we lift the computation
476 // of a FP's input coord to a varying we propagate that varying up the FP tree to the highest
477 // node that shares the same coordinates. This allows multiple FPs in a subtree to share a
478 // varying.
479 std::unordered_map<const GrFragmentProcessor*, TransformInfo> fTransformVaryingsMap;
480};
481
482///////////////////////////////////////////////////////////////////////////
483
Robert Phillips787fd9d2021-03-22 14:48:09 -0400484/**
485 * Used to capture the properties of the GrTextureProxies required/expected by a primitiveProcessor
486 * along with an associated GrSamplerState. The actual proxies used are stored in either the
487 * fixed or dynamic state arrays. TextureSamplers don't perform any coord manipulation to account
488 * for texture origin.
489 */
490class GrGeometryProcessor::TextureSampler {
491public:
492 TextureSampler() = default;
493
494 TextureSampler(GrSamplerState, const GrBackendFormat&, const GrSwizzle&);
495
496 TextureSampler(const TextureSampler&) = delete;
497 TextureSampler& operator=(const TextureSampler&) = delete;
498
499 void reset(GrSamplerState, const GrBackendFormat&, const GrSwizzle&);
500
501 const GrBackendFormat& backendFormat() const { return fBackendFormat; }
502 GrTextureType textureType() const { return fBackendFormat.textureType(); }
503
504 GrSamplerState samplerState() const { return fSamplerState; }
505 const GrSwizzle& swizzle() const { return fSwizzle; }
506
507 bool isInitialized() const { return fIsInitialized; }
508
509private:
510 GrSamplerState fSamplerState;
511 GrBackendFormat fBackendFormat;
512 GrSwizzle fSwizzle;
513 bool fIsInitialized = false;
514};
515
516const GrGeometryProcessor::TextureSampler& GrGeometryProcessor::IthTextureSampler(int i) {
517 SK_ABORT("Illegal texture sampler index");
518 static const TextureSampler kBogus;
519 return kBogus;
520}
521
522//////////////////////////////////////////////////////////////////////////////
523
524/**
525 * Returns the size of the attrib type in bytes.
526 * This was moved from include/private/GrTypesPriv.h in service of Skia dependents that build
527 * with C++11.
528 */
529static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
530 switch (type) {
531 case kFloat_GrVertexAttribType:
532 return sizeof(float);
533 case kFloat2_GrVertexAttribType:
534 return 2 * sizeof(float);
535 case kFloat3_GrVertexAttribType:
536 return 3 * sizeof(float);
537 case kFloat4_GrVertexAttribType:
538 return 4 * sizeof(float);
539 case kHalf_GrVertexAttribType:
540 return sizeof(uint16_t);
541 case kHalf2_GrVertexAttribType:
542 return 2 * sizeof(uint16_t);
543 case kHalf4_GrVertexAttribType:
544 return 4 * sizeof(uint16_t);
545 case kInt2_GrVertexAttribType:
546 return 2 * sizeof(int32_t);
547 case kInt3_GrVertexAttribType:
548 return 3 * sizeof(int32_t);
549 case kInt4_GrVertexAttribType:
550 return 4 * sizeof(int32_t);
551 case kByte_GrVertexAttribType:
552 return 1 * sizeof(char);
553 case kByte2_GrVertexAttribType:
554 return 2 * sizeof(char);
555 case kByte4_GrVertexAttribType:
556 return 4 * sizeof(char);
557 case kUByte_GrVertexAttribType:
558 return 1 * sizeof(char);
559 case kUByte2_GrVertexAttribType:
560 return 2 * sizeof(char);
561 case kUByte4_GrVertexAttribType:
562 return 4 * sizeof(char);
563 case kUByte_norm_GrVertexAttribType:
564 return 1 * sizeof(char);
565 case kUByte4_norm_GrVertexAttribType:
566 return 4 * sizeof(char);
567 case kShort2_GrVertexAttribType:
568 return 2 * sizeof(int16_t);
569 case kShort4_GrVertexAttribType:
570 return 4 * sizeof(int16_t);
571 case kUShort2_GrVertexAttribType: // fall through
572 case kUShort2_norm_GrVertexAttribType:
573 return 2 * sizeof(uint16_t);
574 case kInt_GrVertexAttribType:
575 return sizeof(int32_t);
576 case kUint_GrVertexAttribType:
577 return sizeof(uint32_t);
578 case kUShort_norm_GrVertexAttribType:
579 return sizeof(uint16_t);
580 case kUShort4_norm_GrVertexAttribType:
581 return 4 * sizeof(uint16_t);
582 }
583 // GCC fails because SK_ABORT evaluates to non constexpr. clang and cl.exe think this is
584 // unreachable and don't complain.
585#if defined(__clang__) || !defined(__GNUC__)
586 SK_ABORT("Unsupported type conversion");
587#endif
588 return 0;
589}
590
591constexpr size_t GrGeometryProcessor::Attribute::size() const {
592 return GrVertexAttribTypeSize(fCPUType);
593}
594
joshualittb0a8a372014-09-23 09:50:21 -0700595#endif