xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrGeometryProcessor.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2013 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef GrGeometryProcessor_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define GrGeometryProcessor_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAlign.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkSLTypeShared.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrFragmentProcessor.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessor.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderCaps.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderVar.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
27*c8dee2aaSAndroid Build Coastguard Worker 
28*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
29*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
30*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
31*c8dee2aaSAndroid Build Coastguard Worker #include <optional>
32*c8dee2aaSAndroid Build Coastguard Worker #include <tuple>
33*c8dee2aaSAndroid Build Coastguard Worker #include <unordered_map>
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLFPFragmentBuilder;
36*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLVertexBuilder;
37*c8dee2aaSAndroid Build Coastguard Worker class GrPipeline;
38*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu {
39*c8dee2aaSAndroid Build Coastguard Worker class KeyBuilder;
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker 
42*c8dee2aaSAndroid Build Coastguard Worker /**
43*c8dee2aaSAndroid Build Coastguard Worker  * The GrGeometryProcessor represents some kind of geometric primitive.  This includes the shape
44*c8dee2aaSAndroid Build Coastguard Worker  * of the primitive and the inherent color of the primitive.  The GrGeometryProcessor is
45*c8dee2aaSAndroid Build Coastguard Worker  * responsible for providing a color and coverage input into the Ganesh rendering pipeline. Through
46*c8dee2aaSAndroid Build Coastguard Worker  * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
47*c8dee2aaSAndroid Build Coastguard Worker  * from the GrGeometryProcessor, so the GrGeometryProcessor must be able to support this
48*c8dee2aaSAndroid Build Coastguard Worker  * functionality.
49*c8dee2aaSAndroid Build Coastguard Worker  *
50*c8dee2aaSAndroid Build Coastguard Worker  * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
51*c8dee2aaSAndroid Build Coastguard Worker  * GrGeometryProcessor. These loops run on the CPU and to determine known properties of the final
52*c8dee2aaSAndroid Build Coastguard Worker  * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
53*c8dee2aaSAndroid Build Coastguard Worker  * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
54*c8dee2aaSAndroid Build Coastguard Worker  * getProcessorAnalysisInputs implementation. These seed values are processed by the
55*c8dee2aaSAndroid Build Coastguard Worker  * subsequent stages of the rendering pipeline and the output is then fed back into the GrDrawOp
56*c8dee2aaSAndroid Build Coastguard Worker  * in the applyPipelineOptimizations call, where the op can use the information to inform
57*c8dee2aaSAndroid Build Coastguard Worker  * decisions about GrGeometryProcessor creation.
58*c8dee2aaSAndroid Build Coastguard Worker  *
59*c8dee2aaSAndroid Build Coastguard Worker  * Note that all derived classes should hide their constructors and provide a Make factory
60*c8dee2aaSAndroid Build Coastguard Worker  * function that takes an arena (except for Tesselation-specific classes). This is because
61*c8dee2aaSAndroid Build Coastguard Worker  * geometry processors can be created in either the record-time or flush-time arenas which
62*c8dee2aaSAndroid Build Coastguard Worker  * define their lifetimes (i.e., a DDLs life time in the first case and a single flush in
63*c8dee2aaSAndroid Build Coastguard Worker  * the second case).
64*c8dee2aaSAndroid Build Coastguard Worker  */
65*c8dee2aaSAndroid Build Coastguard Worker class GrGeometryProcessor : public GrProcessor {
66*c8dee2aaSAndroid Build Coastguard Worker public:
67*c8dee2aaSAndroid Build Coastguard Worker     /**
68*c8dee2aaSAndroid Build Coastguard Worker      * Every GrGeometryProcessor must be capable of creating a subclass of ProgramImpl. The
69*c8dee2aaSAndroid Build Coastguard Worker      * ProgramImpl emits the shader code that implements the GrGeometryProcessor, is attached to the
70*c8dee2aaSAndroid Build Coastguard Worker      * generated backend API pipeline/program and used to extract uniform data from
71*c8dee2aaSAndroid Build Coastguard Worker      * GrGeometryProcessor instances.
72*c8dee2aaSAndroid Build Coastguard Worker      */
73*c8dee2aaSAndroid Build Coastguard Worker     class ProgramImpl;
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker     class TextureSampler;
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker     /** Describes a vertex or instance attribute. */
78*c8dee2aaSAndroid Build Coastguard Worker     class Attribute {
79*c8dee2aaSAndroid Build Coastguard Worker     public:
AlignOffset(size_t offset)80*c8dee2aaSAndroid Build Coastguard Worker         static constexpr size_t AlignOffset(size_t offset) { return SkAlign4(offset); }
81*c8dee2aaSAndroid Build Coastguard Worker 
82*c8dee2aaSAndroid Build Coastguard Worker         constexpr Attribute() = default;
83*c8dee2aaSAndroid Build Coastguard Worker         /**
84*c8dee2aaSAndroid Build Coastguard Worker          * Makes an attribute whose offset will be implicitly determined by the types and ordering
85*c8dee2aaSAndroid Build Coastguard Worker          * of an array attributes.
86*c8dee2aaSAndroid Build Coastguard Worker          */
Attribute(const char * name,GrVertexAttribType cpuType,SkSLType gpuType)87*c8dee2aaSAndroid Build Coastguard Worker         constexpr Attribute(const char* name,
88*c8dee2aaSAndroid Build Coastguard Worker                             GrVertexAttribType cpuType,
89*c8dee2aaSAndroid Build Coastguard Worker                             SkSLType gpuType)
90*c8dee2aaSAndroid Build Coastguard Worker                 : fName(name), fCPUType(cpuType), fGPUType(gpuType) {
91*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(name && gpuType != SkSLType::kVoid);
92*c8dee2aaSAndroid Build Coastguard Worker         }
93*c8dee2aaSAndroid Build Coastguard Worker         /**
94*c8dee2aaSAndroid Build Coastguard Worker          * Makes an attribute with an explicit offset.
95*c8dee2aaSAndroid Build Coastguard Worker          */
Attribute(const char * name,GrVertexAttribType cpuType,SkSLType gpuType,size_t offset)96*c8dee2aaSAndroid Build Coastguard Worker         constexpr Attribute(const char*        name,
97*c8dee2aaSAndroid Build Coastguard Worker                             GrVertexAttribType cpuType,
98*c8dee2aaSAndroid Build Coastguard Worker                             SkSLType           gpuType,
99*c8dee2aaSAndroid Build Coastguard Worker                             size_t             offset)
100*c8dee2aaSAndroid Build Coastguard Worker                 : fName(name), fCPUType(cpuType), fGPUType(gpuType), fOffset(SkToU32(offset)) {
101*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(AlignOffset(offset) == offset);
102*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(name && gpuType != SkSLType::kVoid);
103*c8dee2aaSAndroid Build Coastguard Worker         }
104*c8dee2aaSAndroid Build Coastguard Worker         constexpr Attribute(const Attribute&) = default;
105*c8dee2aaSAndroid Build Coastguard Worker 
106*c8dee2aaSAndroid Build Coastguard Worker         Attribute& operator=(const Attribute&) = default;
107*c8dee2aaSAndroid Build Coastguard Worker 
isInitialized()108*c8dee2aaSAndroid Build Coastguard Worker         constexpr bool isInitialized() const { return fGPUType != SkSLType::kVoid; }
109*c8dee2aaSAndroid Build Coastguard Worker 
name()110*c8dee2aaSAndroid Build Coastguard Worker         constexpr const char*           name() const { return fName; }
cpuType()111*c8dee2aaSAndroid Build Coastguard Worker         constexpr GrVertexAttribType cpuType() const { return fCPUType; }
gpuType()112*c8dee2aaSAndroid Build Coastguard Worker         constexpr SkSLType           gpuType() const { return fGPUType; }
113*c8dee2aaSAndroid Build Coastguard Worker         /**
114*c8dee2aaSAndroid Build Coastguard Worker          * Returns the offset if attributes were specified with explicit offsets. Otherwise,
115*c8dee2aaSAndroid Build Coastguard Worker          * offsets (and total vertex stride) are implicitly determined from attribute order and
116*c8dee2aaSAndroid Build Coastguard Worker          * types.
117*c8dee2aaSAndroid Build Coastguard Worker          */
offset()118*c8dee2aaSAndroid Build Coastguard Worker         std::optional<size_t> offset() const {
119*c8dee2aaSAndroid Build Coastguard Worker             if (fOffset != kImplicitOffset) {
120*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(AlignOffset(fOffset) == fOffset);
121*c8dee2aaSAndroid Build Coastguard Worker                 return {fOffset};
122*c8dee2aaSAndroid Build Coastguard Worker             }
123*c8dee2aaSAndroid Build Coastguard Worker             return std::nullopt;
124*c8dee2aaSAndroid Build Coastguard Worker         }
125*c8dee2aaSAndroid Build Coastguard Worker 
126*c8dee2aaSAndroid Build Coastguard Worker         inline constexpr size_t size() const;
127*c8dee2aaSAndroid Build Coastguard Worker 
asShaderVar()128*c8dee2aaSAndroid Build Coastguard Worker         GrShaderVar asShaderVar() const {
129*c8dee2aaSAndroid Build Coastguard Worker             return {fName, fGPUType, GrShaderVar::TypeModifier::In};
130*c8dee2aaSAndroid Build Coastguard Worker         }
131*c8dee2aaSAndroid Build Coastguard Worker 
132*c8dee2aaSAndroid Build Coastguard Worker     private:
133*c8dee2aaSAndroid Build Coastguard Worker         static constexpr uint32_t kImplicitOffset = 1;  // 1 is not valid because it isn't aligned.
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker         const char*        fName    = nullptr;
136*c8dee2aaSAndroid Build Coastguard Worker         GrVertexAttribType fCPUType = kFloat_GrVertexAttribType;
137*c8dee2aaSAndroid Build Coastguard Worker         SkSLType           fGPUType = SkSLType::kVoid;
138*c8dee2aaSAndroid Build Coastguard Worker         uint32_t           fOffset  = kImplicitOffset;
139*c8dee2aaSAndroid Build Coastguard Worker     };
140*c8dee2aaSAndroid Build Coastguard Worker 
141*c8dee2aaSAndroid Build Coastguard Worker     /**
142*c8dee2aaSAndroid Build Coastguard Worker      * A set of attributes that can iterated. The iterator handles hides two pieces of complexity:
143*c8dee2aaSAndroid Build Coastguard Worker      * 1) It skips uninitialized attributes.
144*c8dee2aaSAndroid Build Coastguard Worker      * 2) It always returns an attribute with a known offset.
145*c8dee2aaSAndroid Build Coastguard Worker      */
146*c8dee2aaSAndroid Build Coastguard Worker     class AttributeSet {
147*c8dee2aaSAndroid Build Coastguard Worker         class Iter {
148*c8dee2aaSAndroid Build Coastguard Worker         public:
149*c8dee2aaSAndroid Build Coastguard Worker             Iter() = default;
150*c8dee2aaSAndroid Build Coastguard Worker             Iter(const Iter& iter) = default;
151*c8dee2aaSAndroid Build Coastguard Worker             Iter& operator=(const Iter& iter) = default;
152*c8dee2aaSAndroid Build Coastguard Worker 
Iter(const Attribute * attrs,int count)153*c8dee2aaSAndroid Build Coastguard Worker             Iter(const Attribute* attrs, int count) : fCurr(attrs), fRemaining(count) {
154*c8dee2aaSAndroid Build Coastguard Worker                 this->skipUninitialized();
155*c8dee2aaSAndroid Build Coastguard Worker             }
156*c8dee2aaSAndroid Build Coastguard Worker 
157*c8dee2aaSAndroid Build Coastguard Worker             bool operator!=(const Iter& that) const { return fCurr != that.fCurr; }
158*c8dee2aaSAndroid Build Coastguard Worker             Attribute operator*() const;
159*c8dee2aaSAndroid Build Coastguard Worker             void operator++();
160*c8dee2aaSAndroid Build Coastguard Worker 
161*c8dee2aaSAndroid Build Coastguard Worker         private:
162*c8dee2aaSAndroid Build Coastguard Worker             void skipUninitialized();
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker             const Attribute* fCurr           = nullptr;
165*c8dee2aaSAndroid Build Coastguard Worker             int              fRemaining      = 0;
166*c8dee2aaSAndroid Build Coastguard Worker             size_t           fImplicitOffset = 0;
167*c8dee2aaSAndroid Build Coastguard Worker         };
168*c8dee2aaSAndroid Build Coastguard Worker 
169*c8dee2aaSAndroid Build Coastguard Worker     public:
170*c8dee2aaSAndroid Build Coastguard Worker         Iter begin() const;
171*c8dee2aaSAndroid Build Coastguard Worker         Iter end() const;
172*c8dee2aaSAndroid Build Coastguard Worker 
count()173*c8dee2aaSAndroid Build Coastguard Worker         int count() const { return fCount; }
stride()174*c8dee2aaSAndroid Build Coastguard Worker         size_t stride() const { return fStride; }
175*c8dee2aaSAndroid Build Coastguard Worker 
176*c8dee2aaSAndroid Build Coastguard Worker         // Init with implicit offsets and stride. No attributes can have a predetermined stride.
177*c8dee2aaSAndroid Build Coastguard Worker         void initImplicit(const Attribute* attrs, int count);
178*c8dee2aaSAndroid Build Coastguard Worker         // Init with explicit offsets and stride. All attributes must be initialized and have
179*c8dee2aaSAndroid Build Coastguard Worker         // an explicit offset aligned to 4 bytes and with no attribute crossing stride boundaries.
180*c8dee2aaSAndroid Build Coastguard Worker         void initExplicit(const Attribute* attrs, int count, size_t stride);
181*c8dee2aaSAndroid Build Coastguard Worker 
182*c8dee2aaSAndroid Build Coastguard Worker         void addToKey(skgpu::KeyBuilder* b) const;
183*c8dee2aaSAndroid Build Coastguard Worker 
184*c8dee2aaSAndroid Build Coastguard Worker     private:
185*c8dee2aaSAndroid Build Coastguard Worker         const Attribute* fAttributes = nullptr;
186*c8dee2aaSAndroid Build Coastguard Worker         int              fRawCount = 0;
187*c8dee2aaSAndroid Build Coastguard Worker         int              fCount = 0;
188*c8dee2aaSAndroid Build Coastguard Worker         size_t           fStride = 0;
189*c8dee2aaSAndroid Build Coastguard Worker     };
190*c8dee2aaSAndroid Build Coastguard Worker 
191*c8dee2aaSAndroid Build Coastguard Worker     GrGeometryProcessor(ClassID);
192*c8dee2aaSAndroid Build Coastguard Worker 
numTextureSamplers()193*c8dee2aaSAndroid Build Coastguard Worker     int numTextureSamplers() const { return fTextureSamplerCnt; }
194*c8dee2aaSAndroid Build Coastguard Worker     const TextureSampler& textureSampler(int index) const;
numVertexAttributes()195*c8dee2aaSAndroid Build Coastguard Worker     int numVertexAttributes() const { return fVertexAttributes.count(); }
vertexAttributes()196*c8dee2aaSAndroid Build Coastguard Worker     const AttributeSet& vertexAttributes() const { return fVertexAttributes; }
numInstanceAttributes()197*c8dee2aaSAndroid Build Coastguard Worker     int numInstanceAttributes() const { return fInstanceAttributes.count(); }
instanceAttributes()198*c8dee2aaSAndroid Build Coastguard Worker     const AttributeSet& instanceAttributes() const { return fInstanceAttributes; }
199*c8dee2aaSAndroid Build Coastguard Worker 
hasVertexAttributes()200*c8dee2aaSAndroid Build Coastguard Worker     bool hasVertexAttributes() const { return SkToBool(fVertexAttributes.count()); }
hasInstanceAttributes()201*c8dee2aaSAndroid Build Coastguard Worker     bool hasInstanceAttributes() const { return SkToBool(fInstanceAttributes.count()); }
202*c8dee2aaSAndroid Build Coastguard Worker 
203*c8dee2aaSAndroid Build Coastguard Worker     /**
204*c8dee2aaSAndroid Build Coastguard Worker      * A common practice is to populate the the vertex/instance's memory using an implicit array of
205*c8dee2aaSAndroid Build Coastguard Worker      * structs. In this case, it is best to assert that:
206*c8dee2aaSAndroid Build Coastguard Worker      *     stride == sizeof(struct)
207*c8dee2aaSAndroid Build Coastguard Worker      */
vertexStride()208*c8dee2aaSAndroid Build Coastguard Worker     size_t vertexStride() const { return fVertexAttributes.stride(); }
instanceStride()209*c8dee2aaSAndroid Build Coastguard Worker     size_t instanceStride() const { return fInstanceAttributes.stride(); }
210*c8dee2aaSAndroid Build Coastguard Worker 
211*c8dee2aaSAndroid Build Coastguard Worker     /**
212*c8dee2aaSAndroid Build Coastguard Worker      * Computes a key for the transforms owned by an FP based on the shader code that will be
213*c8dee2aaSAndroid Build Coastguard Worker      * emitted by the primitive processor to implement them.
214*c8dee2aaSAndroid Build Coastguard Worker      */
215*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t ComputeCoordTransformsKey(const GrFragmentProcessor& fp);
216*c8dee2aaSAndroid Build Coastguard Worker 
217*c8dee2aaSAndroid Build Coastguard Worker     inline static constexpr int kCoordTransformKeyBits = 4;
218*c8dee2aaSAndroid Build Coastguard Worker 
219*c8dee2aaSAndroid Build Coastguard Worker     /**
220*c8dee2aaSAndroid Build Coastguard Worker      * Adds a key on the skgpu::KeyBuilder that reflects any variety in the code that the
221*c8dee2aaSAndroid Build Coastguard Worker      * geometry processor subclass can emit.
222*c8dee2aaSAndroid Build Coastguard Worker      */
223*c8dee2aaSAndroid Build Coastguard Worker     virtual void addToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const = 0;
224*c8dee2aaSAndroid Build Coastguard Worker 
225*c8dee2aaSAndroid Build Coastguard Worker     void getAttributeKey(skgpu::KeyBuilder* b) const;
226*c8dee2aaSAndroid Build Coastguard Worker 
227*c8dee2aaSAndroid Build Coastguard Worker     /**
228*c8dee2aaSAndroid Build Coastguard Worker      * Returns a new instance of the appropriate implementation class for the given
229*c8dee2aaSAndroid Build Coastguard Worker      * GrGeometryProcessor.
230*c8dee2aaSAndroid Build Coastguard Worker      */
231*c8dee2aaSAndroid Build Coastguard Worker     virtual std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const = 0;
232*c8dee2aaSAndroid Build Coastguard Worker 
233*c8dee2aaSAndroid Build Coastguard Worker protected:
234*c8dee2aaSAndroid Build Coastguard Worker     // GPs that need to use either float or ubyte colors can just call this to get a correctly
235*c8dee2aaSAndroid Build Coastguard Worker     // configured Attribute struct
MakeColorAttribute(const char * name,bool wideColor)236*c8dee2aaSAndroid Build Coastguard Worker     static Attribute MakeColorAttribute(const char* name, bool wideColor) {
237*c8dee2aaSAndroid Build Coastguard Worker         return { name,
238*c8dee2aaSAndroid Build Coastguard Worker                  wideColor ? kFloat4_GrVertexAttribType : kUByte4_norm_GrVertexAttribType,
239*c8dee2aaSAndroid Build Coastguard Worker                  SkSLType::kHalf4 };
240*c8dee2aaSAndroid Build Coastguard Worker     }
setVertexAttributes(const Attribute * attrs,int attrCount,size_t stride)241*c8dee2aaSAndroid Build Coastguard Worker     void setVertexAttributes(const Attribute* attrs, int attrCount, size_t stride) {
242*c8dee2aaSAndroid Build Coastguard Worker         fVertexAttributes.initExplicit(attrs, attrCount, stride);
243*c8dee2aaSAndroid Build Coastguard Worker     }
setInstanceAttributes(const Attribute * attrs,int attrCount,size_t stride)244*c8dee2aaSAndroid Build Coastguard Worker     void setInstanceAttributes(const Attribute* attrs, int attrCount, size_t stride) {
245*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(attrCount >= 0);
246*c8dee2aaSAndroid Build Coastguard Worker         fInstanceAttributes.initExplicit(attrs, attrCount, stride);
247*c8dee2aaSAndroid Build Coastguard Worker     }
248*c8dee2aaSAndroid Build Coastguard Worker 
setVertexAttributesWithImplicitOffsets(const Attribute * attrs,int attrCount)249*c8dee2aaSAndroid Build Coastguard Worker     void setVertexAttributesWithImplicitOffsets(const Attribute* attrs, int attrCount) {
250*c8dee2aaSAndroid Build Coastguard Worker         fVertexAttributes.initImplicit(attrs, attrCount);
251*c8dee2aaSAndroid Build Coastguard Worker     }
setInstanceAttributesWithImplicitOffsets(const Attribute * attrs,int attrCount)252*c8dee2aaSAndroid Build Coastguard Worker     void setInstanceAttributesWithImplicitOffsets(const Attribute* attrs, int attrCount) {
253*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(attrCount >= 0);
254*c8dee2aaSAndroid Build Coastguard Worker         fInstanceAttributes.initImplicit(attrs, attrCount);
255*c8dee2aaSAndroid Build Coastguard Worker     }
setTextureSamplerCnt(int cnt)256*c8dee2aaSAndroid Build Coastguard Worker     void setTextureSamplerCnt(int cnt) {
257*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(cnt >= 0);
258*c8dee2aaSAndroid Build Coastguard Worker         fTextureSamplerCnt = cnt;
259*c8dee2aaSAndroid Build Coastguard Worker     }
260*c8dee2aaSAndroid Build Coastguard Worker 
261*c8dee2aaSAndroid Build Coastguard Worker private:
onTextureSampler(int)262*c8dee2aaSAndroid Build Coastguard Worker     virtual const TextureSampler& onTextureSampler(int) const { SK_ABORT("no texture samplers"); }
263*c8dee2aaSAndroid Build Coastguard Worker 
264*c8dee2aaSAndroid Build Coastguard Worker     AttributeSet fVertexAttributes;
265*c8dee2aaSAndroid Build Coastguard Worker     AttributeSet fInstanceAttributes;
266*c8dee2aaSAndroid Build Coastguard Worker 
267*c8dee2aaSAndroid Build Coastguard Worker     int fTextureSamplerCnt = 0;
268*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = GrProcessor;
269*c8dee2aaSAndroid Build Coastguard Worker };
270*c8dee2aaSAndroid Build Coastguard Worker 
271*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
272*c8dee2aaSAndroid Build Coastguard Worker 
273*c8dee2aaSAndroid Build Coastguard Worker class GrGeometryProcessor::ProgramImpl {
274*c8dee2aaSAndroid Build Coastguard Worker public:
275*c8dee2aaSAndroid Build Coastguard Worker     using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
276*c8dee2aaSAndroid Build Coastguard Worker     using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
277*c8dee2aaSAndroid Build Coastguard Worker     /**
278*c8dee2aaSAndroid Build Coastguard Worker      * Struct of optional varying that replaces the input coords and bool indicating whether the FP
279*c8dee2aaSAndroid Build Coastguard Worker      * should take a coord param as an argument. The latter may be false if the coords are simply
280*c8dee2aaSAndroid Build Coastguard Worker      * unused or if the GP has lifted their computation to a varying emitted by the VS.
281*c8dee2aaSAndroid Build Coastguard Worker      */
282*c8dee2aaSAndroid Build Coastguard Worker     struct FPCoords {GrShaderVar coordsVarying; bool hasCoordsParam;};
283*c8dee2aaSAndroid Build Coastguard Worker     using FPCoordsMap = std::unordered_map<const GrFragmentProcessor*, FPCoords>;
284*c8dee2aaSAndroid Build Coastguard Worker 
285*c8dee2aaSAndroid Build Coastguard Worker     virtual ~ProgramImpl() = default;
286*c8dee2aaSAndroid Build Coastguard Worker 
287*c8dee2aaSAndroid Build Coastguard Worker     struct EmitArgs {
EmitArgsEmitArgs288*c8dee2aaSAndroid Build Coastguard Worker         EmitArgs(GrGLSLVertexBuilder* vertBuilder,
289*c8dee2aaSAndroid Build Coastguard Worker                  GrGLSLFPFragmentBuilder* fragBuilder,
290*c8dee2aaSAndroid Build Coastguard Worker                  GrGLSLVaryingHandler* varyingHandler,
291*c8dee2aaSAndroid Build Coastguard Worker                  GrGLSLUniformHandler* uniformHandler,
292*c8dee2aaSAndroid Build Coastguard Worker                  const GrShaderCaps* caps,
293*c8dee2aaSAndroid Build Coastguard Worker                  const GrGeometryProcessor& geomProc,
294*c8dee2aaSAndroid Build Coastguard Worker                  const char* outputColor,
295*c8dee2aaSAndroid Build Coastguard Worker                  const char* outputCoverage,
296*c8dee2aaSAndroid Build Coastguard Worker                  const SamplerHandle* texSamplers)
297*c8dee2aaSAndroid Build Coastguard Worker                 : fVertBuilder(vertBuilder)
298*c8dee2aaSAndroid Build Coastguard Worker                 , fFragBuilder(fragBuilder)
299*c8dee2aaSAndroid Build Coastguard Worker                 , fVaryingHandler(varyingHandler)
300*c8dee2aaSAndroid Build Coastguard Worker                 , fUniformHandler(uniformHandler)
301*c8dee2aaSAndroid Build Coastguard Worker                 , fShaderCaps(caps)
302*c8dee2aaSAndroid Build Coastguard Worker                 , fGeomProc(geomProc)
303*c8dee2aaSAndroid Build Coastguard Worker                 , fOutputColor(outputColor)
304*c8dee2aaSAndroid Build Coastguard Worker                 , fOutputCoverage(outputCoverage)
305*c8dee2aaSAndroid Build Coastguard Worker                 , fTexSamplers(texSamplers) {}
306*c8dee2aaSAndroid Build Coastguard Worker         GrGLSLVertexBuilder* fVertBuilder;
307*c8dee2aaSAndroid Build Coastguard Worker         GrGLSLFPFragmentBuilder* fFragBuilder;
308*c8dee2aaSAndroid Build Coastguard Worker         GrGLSLVaryingHandler* fVaryingHandler;
309*c8dee2aaSAndroid Build Coastguard Worker         GrGLSLUniformHandler* fUniformHandler;
310*c8dee2aaSAndroid Build Coastguard Worker         const GrShaderCaps* fShaderCaps;
311*c8dee2aaSAndroid Build Coastguard Worker         const GrGeometryProcessor& fGeomProc;
312*c8dee2aaSAndroid Build Coastguard Worker         const char* fOutputColor;
313*c8dee2aaSAndroid Build Coastguard Worker         const char* fOutputCoverage;
314*c8dee2aaSAndroid Build Coastguard Worker         const SamplerHandle* fTexSamplers;
315*c8dee2aaSAndroid Build Coastguard Worker     };
316*c8dee2aaSAndroid Build Coastguard Worker 
317*c8dee2aaSAndroid Build Coastguard Worker     /**
318*c8dee2aaSAndroid Build Coastguard Worker      * Emits the code from this geometry processor into the shaders. For any FP in the pipeline that
319*c8dee2aaSAndroid Build Coastguard Worker      * has its input coords implemented by the GP as a varying, the varying will be accessible in
320*c8dee2aaSAndroid Build Coastguard Worker      * the returned map and should be used when the FP code is emitted. The FS variable containing
321*c8dee2aaSAndroid Build Coastguard Worker      * the GP's output local coords is also returned.
322*c8dee2aaSAndroid Build Coastguard Worker      **/
323*c8dee2aaSAndroid Build Coastguard Worker     std::tuple<FPCoordsMap, GrShaderVar> emitCode(EmitArgs&, const GrPipeline& pipeline);
324*c8dee2aaSAndroid Build Coastguard Worker 
325*c8dee2aaSAndroid Build Coastguard Worker     /**
326*c8dee2aaSAndroid Build Coastguard Worker      * Called after all effect emitCode() functions, to give the processor a chance to write out
327*c8dee2aaSAndroid Build Coastguard Worker      * additional transformation code now that all uniforms have been emitted.
328*c8dee2aaSAndroid Build Coastguard Worker      * It generates the final code for assigning transformed coordinates to the varyings recorded
329*c8dee2aaSAndroid Build Coastguard Worker      * in the call to collectTransforms(). This must happen after FP code emission so that it has
330*c8dee2aaSAndroid Build Coastguard Worker      * access to any uniforms the FPs registered for uniform sample matrix invocations.
331*c8dee2aaSAndroid Build Coastguard Worker      */
332*c8dee2aaSAndroid Build Coastguard Worker     void emitTransformCode(GrGLSLVertexBuilder* vb, GrGLSLUniformHandler* uniformHandler);
333*c8dee2aaSAndroid Build Coastguard Worker 
334*c8dee2aaSAndroid Build Coastguard Worker     /**
335*c8dee2aaSAndroid Build Coastguard Worker      * A ProgramImpl instance can be reused with any GrGeometryProcessor that produces the same key.
336*c8dee2aaSAndroid Build Coastguard Worker      * This function reads data from a GrGeometryProcessor and updates any uniform variables
337*c8dee2aaSAndroid Build Coastguard Worker      * required by the shaders created in emitCode(). The GrGeometryProcessor parameter is
338*c8dee2aaSAndroid Build Coastguard Worker      * guaranteed to be of the same type and to have an identical processor key as the
339*c8dee2aaSAndroid Build Coastguard Worker      * GrGeometryProcessor that created this ProgramImpl.
340*c8dee2aaSAndroid Build Coastguard Worker      */
341*c8dee2aaSAndroid Build Coastguard Worker     virtual void setData(const GrGLSLProgramDataManager&,
342*c8dee2aaSAndroid Build Coastguard Worker                          const GrShaderCaps&,
343*c8dee2aaSAndroid Build Coastguard Worker                          const GrGeometryProcessor&) = 0;
344*c8dee2aaSAndroid Build Coastguard Worker 
345*c8dee2aaSAndroid Build Coastguard Worker     // GPs that use writeOutputPosition and/or writeLocalCoord must incorporate the matrix type
346*c8dee2aaSAndroid Build Coastguard Worker     // into their key, and should use this function or one of the other related helpers.
ComputeMatrixKey(const GrShaderCaps & caps,const SkMatrix & mat)347*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t ComputeMatrixKey(const GrShaderCaps& caps, const SkMatrix& mat) {
348*c8dee2aaSAndroid Build Coastguard Worker         if (!caps.fReducedShaderMode) {
349*c8dee2aaSAndroid Build Coastguard Worker             if (mat.isIdentity()) {
350*c8dee2aaSAndroid Build Coastguard Worker                 return 0b00;
351*c8dee2aaSAndroid Build Coastguard Worker             }
352*c8dee2aaSAndroid Build Coastguard Worker             if (mat.isScaleTranslate()) {
353*c8dee2aaSAndroid Build Coastguard Worker                 return 0b01;
354*c8dee2aaSAndroid Build Coastguard Worker             }
355*c8dee2aaSAndroid Build Coastguard Worker         }
356*c8dee2aaSAndroid Build Coastguard Worker         if (!mat.hasPerspective()) {
357*c8dee2aaSAndroid Build Coastguard Worker             return 0b10;
358*c8dee2aaSAndroid Build Coastguard Worker         }
359*c8dee2aaSAndroid Build Coastguard Worker         return 0b11;
360*c8dee2aaSAndroid Build Coastguard Worker     }
361*c8dee2aaSAndroid Build Coastguard Worker 
ComputeMatrixKeys(const GrShaderCaps & shaderCaps,const SkMatrix & viewMatrix,const SkMatrix & localMatrix)362*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t ComputeMatrixKeys(const GrShaderCaps& shaderCaps,
363*c8dee2aaSAndroid Build Coastguard Worker                                       const SkMatrix& viewMatrix,
364*c8dee2aaSAndroid Build Coastguard Worker                                       const SkMatrix& localMatrix) {
365*c8dee2aaSAndroid Build Coastguard Worker         return (ComputeMatrixKey(shaderCaps, viewMatrix) << kMatrixKeyBits) |
366*c8dee2aaSAndroid Build Coastguard Worker                ComputeMatrixKey(shaderCaps, localMatrix);
367*c8dee2aaSAndroid Build Coastguard Worker     }
368*c8dee2aaSAndroid Build Coastguard Worker 
AddMatrixKeys(const GrShaderCaps & shaderCaps,uint32_t flags,const SkMatrix & viewMatrix,const SkMatrix & localMatrix)369*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t AddMatrixKeys(const GrShaderCaps& shaderCaps,
370*c8dee2aaSAndroid Build Coastguard Worker                                   uint32_t flags,
371*c8dee2aaSAndroid Build Coastguard Worker                                   const SkMatrix& viewMatrix,
372*c8dee2aaSAndroid Build Coastguard Worker                                   const SkMatrix& localMatrix) {
373*c8dee2aaSAndroid Build Coastguard Worker         // Shifting to make room for the matrix keys shouldn't lose bits
374*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(((flags << (2 * kMatrixKeyBits)) >> (2 * kMatrixKeyBits)) == flags);
375*c8dee2aaSAndroid Build Coastguard Worker         return (flags << (2 * kMatrixKeyBits)) |
376*c8dee2aaSAndroid Build Coastguard Worker                ComputeMatrixKeys(shaderCaps, viewMatrix, localMatrix);
377*c8dee2aaSAndroid Build Coastguard Worker     }
378*c8dee2aaSAndroid Build Coastguard Worker     inline static constexpr int kMatrixKeyBits = 2;
379*c8dee2aaSAndroid Build Coastguard Worker 
380*c8dee2aaSAndroid Build Coastguard Worker protected:
381*c8dee2aaSAndroid Build Coastguard Worker     void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
382*c8dee2aaSAndroid Build Coastguard Worker                            GrGLSLUniformHandler* uniformHandler,
383*c8dee2aaSAndroid Build Coastguard Worker                            const char* outputName,
384*c8dee2aaSAndroid Build Coastguard Worker                            UniformHandle* colorUniform);
385*c8dee2aaSAndroid Build Coastguard Worker 
386*c8dee2aaSAndroid Build Coastguard Worker     // A helper for setting the matrix on a uniform handle initialized through
387*c8dee2aaSAndroid Build Coastguard Worker     // writeOutputPosition or writeLocalCoord. Automatically handles elided uniforms,
388*c8dee2aaSAndroid Build Coastguard Worker     // scale+translate matrices, and state tracking (if provided state pointer is non-null).
389*c8dee2aaSAndroid Build Coastguard Worker     static void SetTransform(const GrGLSLProgramDataManager&,
390*c8dee2aaSAndroid Build Coastguard Worker                              const GrShaderCaps&,
391*c8dee2aaSAndroid Build Coastguard Worker                              const UniformHandle& uniform,
392*c8dee2aaSAndroid Build Coastguard Worker                              const SkMatrix& matrix,
393*c8dee2aaSAndroid Build Coastguard Worker                              SkMatrix* state = nullptr);
394*c8dee2aaSAndroid Build Coastguard Worker 
395*c8dee2aaSAndroid Build Coastguard Worker     struct GrGPArgs {
396*c8dee2aaSAndroid Build Coastguard Worker         // Used to specify the output variable used by the GP to store its device position. It can
397*c8dee2aaSAndroid Build Coastguard Worker         // either be a float2 or a float3 (in order to handle perspective). The subclass sets this
398*c8dee2aaSAndroid Build Coastguard Worker         // in its onEmitCode().
399*c8dee2aaSAndroid Build Coastguard Worker         GrShaderVar fPositionVar;
400*c8dee2aaSAndroid Build Coastguard Worker         // Used to specify the variable storing the draw's local coordinates. It can be either a
401*c8dee2aaSAndroid Build Coastguard Worker         // float2, float3, or void. It can only be void when no FP needs local coordinates. This
402*c8dee2aaSAndroid Build Coastguard Worker         // variable can be an attribute or local variable, but should not itself be a varying.
403*c8dee2aaSAndroid Build Coastguard Worker         // ProgramImpl automatically determines if this must be passed to a FS.
404*c8dee2aaSAndroid Build Coastguard Worker         GrShaderVar fLocalCoordVar;
405*c8dee2aaSAndroid Build Coastguard Worker         // The GP can specify the local coord var either in the VS or FS. When either is possible
406*c8dee2aaSAndroid Build Coastguard Worker         // the VS is preferable. It may allow derived coordinates to be interpolated from the VS
407*c8dee2aaSAndroid Build Coastguard Worker         // instead of computed in the FS per pixel.
408*c8dee2aaSAndroid Build Coastguard Worker         GrShaderType fLocalCoordShader = kVertex_GrShaderType;
409*c8dee2aaSAndroid Build Coastguard Worker     };
410*c8dee2aaSAndroid Build Coastguard Worker 
411*c8dee2aaSAndroid Build Coastguard Worker     // Helpers for adding code to write the transformed vertex position. The first simple version
412*c8dee2aaSAndroid Build Coastguard Worker     // just writes a variable named by 'posName' into the position output variable with the
413*c8dee2aaSAndroid Build Coastguard Worker     // assumption that the position is 2D. The second version transforms the input position by a
414*c8dee2aaSAndroid Build Coastguard Worker     // view matrix and the output variable is 2D or 3D depending on whether the view matrix is
415*c8dee2aaSAndroid Build Coastguard Worker     // perspective. Both versions declare the output position variable and will set
416*c8dee2aaSAndroid Build Coastguard Worker     // GrGPArgs::fPositionVar.
417*c8dee2aaSAndroid Build Coastguard Worker     static void WriteOutputPosition(GrGLSLVertexBuilder*, GrGPArgs*, const char* posName);
418*c8dee2aaSAndroid Build Coastguard Worker     static void WriteOutputPosition(GrGLSLVertexBuilder*,
419*c8dee2aaSAndroid Build Coastguard Worker                                     GrGLSLUniformHandler*,
420*c8dee2aaSAndroid Build Coastguard Worker                                     const GrShaderCaps&,
421*c8dee2aaSAndroid Build Coastguard Worker                                     GrGPArgs*,
422*c8dee2aaSAndroid Build Coastguard Worker                                     const char* posName,
423*c8dee2aaSAndroid Build Coastguard Worker                                     const SkMatrix& viewMatrix,
424*c8dee2aaSAndroid Build Coastguard Worker                                     UniformHandle* viewMatrixUniform);
425*c8dee2aaSAndroid Build Coastguard Worker 
426*c8dee2aaSAndroid Build Coastguard Worker     // Helper to transform an existing variable by a given local matrix (e.g. the inverse view
427*c8dee2aaSAndroid Build Coastguard Worker     // matrix). It will declare the transformed local coord variable and will set
428*c8dee2aaSAndroid Build Coastguard Worker     // GrGPArgs::fLocalCoordVar.
429*c8dee2aaSAndroid Build Coastguard Worker     static void WriteLocalCoord(GrGLSLVertexBuilder*,
430*c8dee2aaSAndroid Build Coastguard Worker                                 GrGLSLUniformHandler*,
431*c8dee2aaSAndroid Build Coastguard Worker                                 const GrShaderCaps&,
432*c8dee2aaSAndroid Build Coastguard Worker                                 GrGPArgs*,
433*c8dee2aaSAndroid Build Coastguard Worker                                 GrShaderVar localVar,
434*c8dee2aaSAndroid Build Coastguard Worker                                 const SkMatrix& localMatrix,
435*c8dee2aaSAndroid Build Coastguard Worker                                 UniformHandle* localMatrixUniform);
436*c8dee2aaSAndroid Build Coastguard Worker 
437*c8dee2aaSAndroid Build Coastguard Worker private:
438*c8dee2aaSAndroid Build Coastguard Worker     virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0;
439*c8dee2aaSAndroid Build Coastguard Worker 
440*c8dee2aaSAndroid Build Coastguard Worker     // Iterates over the FPs beginning with the passed iter to register additional varyings and
441*c8dee2aaSAndroid Build Coastguard Worker     // uniforms to support VS-promoted local coord evaluation for the FPs.
442*c8dee2aaSAndroid Build Coastguard Worker     //
443*c8dee2aaSAndroid Build Coastguard Worker     // This must happen before FP code emission so that the FPs can find the appropriate varying
444*c8dee2aaSAndroid Build Coastguard Worker     // handles they use in place of explicit coord sampling; it is automatically called after
445*c8dee2aaSAndroid Build Coastguard Worker     // onEmitCode() returns using the value stored in GpArgs::fLocalCoordVar and
446*c8dee2aaSAndroid Build Coastguard Worker     // GpArgs::fPositionVar.
447*c8dee2aaSAndroid Build Coastguard Worker     FPCoordsMap collectTransforms(GrGLSLVertexBuilder* vb,
448*c8dee2aaSAndroid Build Coastguard Worker                                   GrGLSLVaryingHandler* varyingHandler,
449*c8dee2aaSAndroid Build Coastguard Worker                                   GrGLSLUniformHandler* uniformHandler,
450*c8dee2aaSAndroid Build Coastguard Worker                                   GrShaderType localCoordsShader,
451*c8dee2aaSAndroid Build Coastguard Worker                                   const GrShaderVar& localCoordsVar,
452*c8dee2aaSAndroid Build Coastguard Worker                                   const GrShaderVar& positionVar,
453*c8dee2aaSAndroid Build Coastguard Worker                                   const GrPipeline& pipeline);
454*c8dee2aaSAndroid Build Coastguard Worker     struct TransformInfo {
455*c8dee2aaSAndroid Build Coastguard Worker         // The varying that conveys the coordinates to one or more FPs in the FS.
456*c8dee2aaSAndroid Build Coastguard Worker         GrGLSLVarying varying;
457*c8dee2aaSAndroid Build Coastguard Worker         // The coordinate to be transformed. varying is computed from this.
458*c8dee2aaSAndroid Build Coastguard Worker         GrShaderVar   inputCoords;
459*c8dee2aaSAndroid Build Coastguard Worker         // Used to sort so that ancestor FP varyings are initialized before descendant FP varyings.
460*c8dee2aaSAndroid Build Coastguard Worker         int           traversalOrder;
461*c8dee2aaSAndroid Build Coastguard Worker     };
462*c8dee2aaSAndroid Build Coastguard Worker     // Populated by collectTransforms() for use in emitTransformCode(). When we lift the computation
463*c8dee2aaSAndroid Build Coastguard Worker     // of a FP's input coord to a varying we propagate that varying up the FP tree to the highest
464*c8dee2aaSAndroid Build Coastguard Worker     // node that shares the same coordinates. This allows multiple FPs in a subtree to share a
465*c8dee2aaSAndroid Build Coastguard Worker     // varying.
466*c8dee2aaSAndroid Build Coastguard Worker     std::unordered_map<const GrFragmentProcessor*, TransformInfo> fTransformVaryingsMap;
467*c8dee2aaSAndroid Build Coastguard Worker 
468*c8dee2aaSAndroid Build Coastguard Worker     // Move back into collectTransforms when /std=c++20 can be used with msvc.
469*c8dee2aaSAndroid Build Coastguard Worker     enum class BaseCoord { kNone, kLocal, kPosition };
470*c8dee2aaSAndroid Build Coastguard Worker };
471*c8dee2aaSAndroid Build Coastguard Worker 
472*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
473*c8dee2aaSAndroid Build Coastguard Worker 
474*c8dee2aaSAndroid Build Coastguard Worker /**
475*c8dee2aaSAndroid Build Coastguard Worker  * Used to capture the properties of the GrTextureProxies required/expected by a primitiveProcessor
476*c8dee2aaSAndroid Build Coastguard Worker  * along with an associated GrSamplerState. The actual proxies used are stored in either the
477*c8dee2aaSAndroid Build Coastguard Worker  * fixed or dynamic state arrays. TextureSamplers don't perform any coord manipulation to account
478*c8dee2aaSAndroid Build Coastguard Worker  * for texture origin.
479*c8dee2aaSAndroid Build Coastguard Worker  */
480*c8dee2aaSAndroid Build Coastguard Worker class GrGeometryProcessor::TextureSampler {
481*c8dee2aaSAndroid Build Coastguard Worker public:
482*c8dee2aaSAndroid Build Coastguard Worker     TextureSampler() = default;
483*c8dee2aaSAndroid Build Coastguard Worker 
484*c8dee2aaSAndroid Build Coastguard Worker     TextureSampler(GrSamplerState, const GrBackendFormat&, const skgpu::Swizzle&);
485*c8dee2aaSAndroid Build Coastguard Worker 
486*c8dee2aaSAndroid Build Coastguard Worker     TextureSampler(const TextureSampler&) = delete;
487*c8dee2aaSAndroid Build Coastguard Worker     TextureSampler& operator=(const TextureSampler&) = delete;
488*c8dee2aaSAndroid Build Coastguard Worker 
489*c8dee2aaSAndroid Build Coastguard Worker     TextureSampler(TextureSampler&&) = default;
490*c8dee2aaSAndroid Build Coastguard Worker     TextureSampler& operator=(TextureSampler&&) = default;
491*c8dee2aaSAndroid Build Coastguard Worker 
492*c8dee2aaSAndroid Build Coastguard Worker     void reset(GrSamplerState, const GrBackendFormat&, const skgpu::Swizzle&);
493*c8dee2aaSAndroid Build Coastguard Worker 
backendFormat()494*c8dee2aaSAndroid Build Coastguard Worker     const GrBackendFormat& backendFormat() const { return fBackendFormat; }
textureType()495*c8dee2aaSAndroid Build Coastguard Worker     GrTextureType textureType() const { return fBackendFormat.textureType(); }
496*c8dee2aaSAndroid Build Coastguard Worker 
samplerState()497*c8dee2aaSAndroid Build Coastguard Worker     GrSamplerState samplerState() const { return fSamplerState; }
swizzle()498*c8dee2aaSAndroid Build Coastguard Worker     const skgpu::Swizzle& swizzle() const { return fSwizzle; }
499*c8dee2aaSAndroid Build Coastguard Worker 
isInitialized()500*c8dee2aaSAndroid Build Coastguard Worker     bool isInitialized() const { return fIsInitialized; }
501*c8dee2aaSAndroid Build Coastguard Worker 
502*c8dee2aaSAndroid Build Coastguard Worker private:
503*c8dee2aaSAndroid Build Coastguard Worker     GrSamplerState  fSamplerState;
504*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat fBackendFormat;
505*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Swizzle  fSwizzle;
506*c8dee2aaSAndroid Build Coastguard Worker     bool            fIsInitialized = false;
507*c8dee2aaSAndroid Build Coastguard Worker };
508*c8dee2aaSAndroid Build Coastguard Worker 
509*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
510*c8dee2aaSAndroid Build Coastguard Worker 
511*c8dee2aaSAndroid Build Coastguard Worker /**
512*c8dee2aaSAndroid Build Coastguard Worker  * Returns the size of the attrib type in bytes.
513*c8dee2aaSAndroid Build Coastguard Worker  * This was moved from include/private/gpu/ganesh/GrTypesPriv.h in service of Skia dependents that build
514*c8dee2aaSAndroid Build Coastguard Worker  * with C++11.
515*c8dee2aaSAndroid Build Coastguard Worker  */
GrVertexAttribTypeSize(GrVertexAttribType type)516*c8dee2aaSAndroid Build Coastguard Worker static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
517*c8dee2aaSAndroid Build Coastguard Worker     switch (type) {
518*c8dee2aaSAndroid Build Coastguard Worker         case kFloat_GrVertexAttribType:
519*c8dee2aaSAndroid Build Coastguard Worker             return sizeof(float);
520*c8dee2aaSAndroid Build Coastguard Worker         case kFloat2_GrVertexAttribType:
521*c8dee2aaSAndroid Build Coastguard Worker             return 2 * sizeof(float);
522*c8dee2aaSAndroid Build Coastguard Worker         case kFloat3_GrVertexAttribType:
523*c8dee2aaSAndroid Build Coastguard Worker             return 3 * sizeof(float);
524*c8dee2aaSAndroid Build Coastguard Worker         case kFloat4_GrVertexAttribType:
525*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(float);
526*c8dee2aaSAndroid Build Coastguard Worker         case kHalf_GrVertexAttribType:
527*c8dee2aaSAndroid Build Coastguard Worker             return sizeof(uint16_t);
528*c8dee2aaSAndroid Build Coastguard Worker         case kHalf2_GrVertexAttribType:
529*c8dee2aaSAndroid Build Coastguard Worker             return 2 * sizeof(uint16_t);
530*c8dee2aaSAndroid Build Coastguard Worker         case kHalf4_GrVertexAttribType:
531*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(uint16_t);
532*c8dee2aaSAndroid Build Coastguard Worker         case kInt2_GrVertexAttribType:
533*c8dee2aaSAndroid Build Coastguard Worker             return 2 * sizeof(int32_t);
534*c8dee2aaSAndroid Build Coastguard Worker         case kInt3_GrVertexAttribType:
535*c8dee2aaSAndroid Build Coastguard Worker             return 3 * sizeof(int32_t);
536*c8dee2aaSAndroid Build Coastguard Worker         case kInt4_GrVertexAttribType:
537*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(int32_t);
538*c8dee2aaSAndroid Build Coastguard Worker         case kByte_GrVertexAttribType:
539*c8dee2aaSAndroid Build Coastguard Worker             return 1 * sizeof(char);
540*c8dee2aaSAndroid Build Coastguard Worker         case kByte2_GrVertexAttribType:
541*c8dee2aaSAndroid Build Coastguard Worker             return 2 * sizeof(char);
542*c8dee2aaSAndroid Build Coastguard Worker         case kByte4_GrVertexAttribType:
543*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(char);
544*c8dee2aaSAndroid Build Coastguard Worker         case kUByte_GrVertexAttribType:
545*c8dee2aaSAndroid Build Coastguard Worker             return 1 * sizeof(char);
546*c8dee2aaSAndroid Build Coastguard Worker         case kUByte2_GrVertexAttribType:
547*c8dee2aaSAndroid Build Coastguard Worker             return 2 * sizeof(char);
548*c8dee2aaSAndroid Build Coastguard Worker         case kUByte4_GrVertexAttribType:
549*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(char);
550*c8dee2aaSAndroid Build Coastguard Worker         case kUByte_norm_GrVertexAttribType:
551*c8dee2aaSAndroid Build Coastguard Worker             return 1 * sizeof(char);
552*c8dee2aaSAndroid Build Coastguard Worker         case kUByte4_norm_GrVertexAttribType:
553*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(char);
554*c8dee2aaSAndroid Build Coastguard Worker         case kShort2_GrVertexAttribType:
555*c8dee2aaSAndroid Build Coastguard Worker             return 2 * sizeof(int16_t);
556*c8dee2aaSAndroid Build Coastguard Worker         case kShort4_GrVertexAttribType:
557*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(int16_t);
558*c8dee2aaSAndroid Build Coastguard Worker         case kUShort2_GrVertexAttribType: // fall through
559*c8dee2aaSAndroid Build Coastguard Worker         case kUShort2_norm_GrVertexAttribType:
560*c8dee2aaSAndroid Build Coastguard Worker             return 2 * sizeof(uint16_t);
561*c8dee2aaSAndroid Build Coastguard Worker         case kInt_GrVertexAttribType:
562*c8dee2aaSAndroid Build Coastguard Worker             return sizeof(int32_t);
563*c8dee2aaSAndroid Build Coastguard Worker         case kUInt_GrVertexAttribType:
564*c8dee2aaSAndroid Build Coastguard Worker             return sizeof(uint32_t);
565*c8dee2aaSAndroid Build Coastguard Worker         case kUShort_norm_GrVertexAttribType:
566*c8dee2aaSAndroid Build Coastguard Worker             return sizeof(uint16_t);
567*c8dee2aaSAndroid Build Coastguard Worker         case kUShort4_norm_GrVertexAttribType:
568*c8dee2aaSAndroid Build Coastguard Worker             return 4 * sizeof(uint16_t);
569*c8dee2aaSAndroid Build Coastguard Worker     }
570*c8dee2aaSAndroid Build Coastguard Worker     // GCC fails because SK_ABORT evaluates to non constexpr. clang and cl.exe think this is
571*c8dee2aaSAndroid Build Coastguard Worker     // unreachable and don't complain.
572*c8dee2aaSAndroid Build Coastguard Worker #if defined(__clang__) || !defined(__GNUC__)
573*c8dee2aaSAndroid Build Coastguard Worker     SK_ABORT("Unsupported type conversion");
574*c8dee2aaSAndroid Build Coastguard Worker #endif
575*c8dee2aaSAndroid Build Coastguard Worker     return 0;
576*c8dee2aaSAndroid Build Coastguard Worker }
577*c8dee2aaSAndroid Build Coastguard Worker 
size()578*c8dee2aaSAndroid Build Coastguard Worker constexpr size_t GrGeometryProcessor::Attribute::size() const {
579*c8dee2aaSAndroid Build Coastguard Worker     return GrVertexAttribTypeSize(fCPUType);
580*c8dee2aaSAndroid Build Coastguard Worker }
581*c8dee2aaSAndroid Build Coastguard Worker 
582*c8dee2aaSAndroid Build Coastguard Worker #endif
583