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