1 /*
2  * Copyright 2015 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 GrGLSLUniformHandler_DEFINED
9 #define GrGLSLUniformHandler_DEFINED
10 
11 #include "src/gpu/GrShaderVar.h"
12 #include "src/gpu/GrSwizzle.h"
13 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
14 
15 // variable names beginning with this prefix will not be mangled
16 #define GR_NO_MANGLE_PREFIX "sk_"
17 
18 class GrGLSLProgramBuilder;
19 class GrGLSLShaderBuilder;
20 class GrSamplerState;
21 class GrSurfaceProxy;
22 
23 // Handles for program uniforms (other than per-effect uniforms)
24 struct GrGLSLBuiltinUniformHandles {
25     GrGLSLProgramDataManager::UniformHandle fRTAdjustmentUni;
26     // Render target height, used to implement u_skRTHeight and to calculate sk_FragCoord when
27     // origin_upper_left is not supported.
28     GrGLSLProgramDataManager::UniformHandle fRTHeightUni;
29 };
30 
31 class GrGLSLUniformHandler {
32 public:
33     struct UniformInfo {
34         GrShaderVar                fVariable;
35         uint32_t                   fVisibility;
36         const GrFragmentProcessor* fOwner;
37         SkString                   fRawName;
38     };
39 
~GrGLSLUniformHandler()40     virtual ~GrGLSLUniformHandler() {}
41 
42     using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
43 
44     GR_DEFINE_RESOURCE_HANDLE_CLASS(SamplerHandle);
45 
46     /** Add a uniform variable to the current program, that has visibility in one or more shaders.
47         visibility is a bitfield of GrShaderFlag values indicating from which shaders the uniform
48         should be accessible. At least one bit must be set. Geometry shader uniforms are not
49         supported at this time. The actual uniform name will be mangled. If outName is not nullptr
50         then it will refer to the final uniform name after return. Use the addUniformArray variant
51         to add an array of uniforms. */
52     UniformHandle addUniform(const GrFragmentProcessor* owner,
53                              uint32_t visibility,
54                              GrSLType type,
55                              const char* name,
56                              const char** outName = nullptr) {
57         SkASSERT(!GrSLTypeIsCombinedSamplerType(type));
58         return this->addUniformArray(owner, visibility, type, name, 0, outName);
59     }
60 
61     UniformHandle addUniformArray(const GrFragmentProcessor* owner,
62                                   uint32_t visibility,
63                                   GrSLType type,
64                                   const char* name,
65                                   int arrayCount,
66                                   const char** outName = nullptr) {
67         SkASSERT(!GrSLTypeIsCombinedSamplerType(type));
68         bool mangle = strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX));
69         return this->internalAddUniformArray(owner, visibility, type, name, mangle, arrayCount,
70                                              outName);
71     }
72 
73     virtual const GrShaderVar& getUniformVariable(UniformHandle u) const = 0;
74 
75     /**
76      * Shortcut for getUniformVariable(u).c_str()
77      */
78     virtual const char* getUniformCStr(UniformHandle u) const = 0;
79 
80     virtual int numUniforms() const = 0;
81 
82     virtual UniformInfo& uniform(int idx) = 0;
83     virtual const UniformInfo& uniform(int idx) const = 0;
84 
85     // Looks up a uniform that was added by 'owner' with the given 'rawName' (pre-mangling).
86     // If there is no such uniform, a variable with type kVoid is returned.
87     GrShaderVar getUniformMapping(const GrFragmentProcessor& owner, SkString rawName) const;
88 
89     // Like getUniformMapping(), but if the uniform is found it also marks it as accessible in
90     // the vertex shader.
91     GrShaderVar liftUniformToVertexShader(const GrFragmentProcessor& owner, SkString rawName);
92 
93 protected:
94     struct UniformMapping {
95         const GrFragmentProcessor* fOwner;
96         int fInfoIndex;
97         SkString fRawName;
98         const char* fFinalName;
99         GrSLType fType;
100     };
101 
GrGLSLUniformHandler(GrGLSLProgramBuilder * program)102     explicit GrGLSLUniformHandler(GrGLSLProgramBuilder* program) : fProgramBuilder(program) {}
103 
104     // This is not owned by the class
105     GrGLSLProgramBuilder* fProgramBuilder;
106 
107 private:
108     virtual const char * samplerVariable(SamplerHandle) const = 0;
109     virtual GrSwizzle samplerSwizzle(SamplerHandle) const = 0;
110 
inputSamplerVariable(SamplerHandle)111     virtual const char* inputSamplerVariable(SamplerHandle) const {
112         SkDEBUGFAIL("Trying to get input sampler from unsupported backend");
113         return nullptr;
114     }
inputSamplerSwizzle(SamplerHandle)115     virtual GrSwizzle inputSamplerSwizzle(SamplerHandle) const {
116         SkDEBUGFAIL("Trying to get input sampler swizzle from unsupported backend");
117         return {};
118     }
119 
120     virtual SamplerHandle addSampler(const GrBackendFormat&, GrSamplerState, const GrSwizzle&,
121                                      const char* name, const GrShaderCaps*) = 0;
122 
addInputSampler(const GrSwizzle & swizzle,const char * name)123     virtual SamplerHandle addInputSampler(const GrSwizzle& swizzle, const char* name) {
124         SkDEBUGFAIL("Trying to add input sampler to unsupported backend");
125         return {};
126     }
127 
128     virtual UniformHandle internalAddUniformArray(const GrFragmentProcessor* owner,
129                                                   uint32_t visibility,
130                                                   GrSLType type,
131                                                   const char* name,
132                                                   bool mangleName,
133                                                   int arrayCount,
134                                                   const char** outName) = 0;
135 
136     virtual void appendUniformDecls(GrShaderFlags visibility, SkString*) const = 0;
137 
138     friend class GrGLSLProgramBuilder;
139 };
140 
141 #endif
142