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 width, used to implement sk_Width |
27 | GrGLSLProgramDataManager::UniformHandle fRTWidthUni; |
28 | // Render target height, used to implement sk_Height and to calculate sk_FragCoord when |
29 | // origin_upper_left is not supported. |
30 | GrGLSLProgramDataManager::UniformHandle fRTHeightUni; |
31 | }; |
32 | |
33 | class GrGLSLUniformHandler { |
34 | public: |
35 | struct UniformInfo { |
36 | GrShaderVar fVariable; |
37 | uint32_t fVisibility; |
38 | const GrFragmentProcessor* fOwner; |
39 | SkString fRawName; |
40 | }; |
41 | |
42 | virtual ~GrGLSLUniformHandler() {} |
43 | |
44 | using UniformHandle = GrGLSLProgramDataManager::UniformHandle; |
45 | |
46 | GR_DEFINE_RESOURCE_HANDLE_CLASS(SamplerHandle); |
47 | |
48 | /** Add a uniform variable to the current program, that has visibility in one or more shaders. |
49 | visibility is a bitfield of GrShaderFlag values indicating from which shaders the uniform |
50 | should be accessible. At least one bit must be set. Geometry shader uniforms are not |
51 | supported at this time. The actual uniform name will be mangled. If outName is not nullptr |
52 | then it will refer to the final uniform name after return. Use the addUniformArray variant |
53 | to add an array of uniforms. */ |
54 | UniformHandle addUniform(const GrFragmentProcessor* owner, |
55 | uint32_t visibility, |
56 | GrSLType type, |
57 | const char* name, |
58 | const char** outName = nullptr) { |
59 | SkASSERT(!GrSLTypeIsCombinedSamplerType(type)); |
60 | return this->addUniformArray(owner, visibility, type, name, 0, outName); |
61 | } |
62 | |
63 | UniformHandle addUniformArray(const GrFragmentProcessor* owner, |
64 | uint32_t visibility, |
65 | GrSLType type, |
66 | const char* name, |
67 | int arrayCount, |
68 | const char** outName = nullptr) { |
69 | SkASSERT(!GrSLTypeIsCombinedSamplerType(type)); |
70 | bool mangle = strncmp(name, GR_NO_MANGLE_PREFIX, strlen(GR_NO_MANGLE_PREFIX)); |
71 | return this->internalAddUniformArray(owner, visibility, type, name, mangle, arrayCount, |
72 | outName); |
73 | } |
74 | |
75 | virtual const GrShaderVar& getUniformVariable(UniformHandle u) const = 0; |
76 | |
77 | /** |
78 | * Shortcut for getUniformVariable(u).c_str() |
79 | */ |
80 | virtual const char* getUniformCStr(UniformHandle u) const = 0; |
81 | |
82 | virtual int numUniforms() const = 0; |
83 | |
84 | virtual UniformInfo& uniform(int idx) = 0; |
85 | virtual const UniformInfo& uniform(int idx) const = 0; |
86 | |
87 | // Looks up a uniform that was added by 'owner' with the given 'rawName' (pre-mangling). |
88 | // If there is no such uniform, a variable with type kVoid is returned. |
89 | GrShaderVar getUniformMapping(const GrFragmentProcessor& owner, SkString rawName) const; |
90 | |
91 | // Like getUniformMapping(), but if the uniform is found it also marks it as accessible in |
92 | // the vertex shader. |
93 | GrShaderVar liftUniformToVertexShader(const GrFragmentProcessor& owner, SkString rawName); |
94 | |
95 | protected: |
96 | struct UniformMapping { |
97 | const GrFragmentProcessor* fOwner; |
98 | int fInfoIndex; |
99 | SkString fRawName; |
100 | const char* fFinalName; |
101 | GrSLType fType; |
102 | }; |
103 | |
104 | explicit GrGLSLUniformHandler(GrGLSLProgramBuilder* program) : fProgramBuilder(program) {} |
105 | |
106 | // This is not owned by the class |
107 | GrGLSLProgramBuilder* fProgramBuilder; |
108 | |
109 | private: |
110 | virtual const char * samplerVariable(SamplerHandle) const = 0; |
111 | // Only called if GrShaderCaps(:textureSwizzleAppliedInShader() == true. |
112 | virtual GrSwizzle samplerSwizzle(SamplerHandle) const = 0; |
113 | |
114 | virtual SamplerHandle addSampler(const GrBackendFormat&, GrSamplerState, const GrSwizzle&, |
115 | const char* name, const GrShaderCaps*) = 0; |
116 | |
117 | virtual UniformHandle internalAddUniformArray(const GrFragmentProcessor* owner, |
118 | uint32_t visibility, |
119 | GrSLType type, |
120 | const char* name, |
121 | bool mangleName, |
122 | int arrayCount, |
123 | const char** outName) = 0; |
124 | |
125 | virtual void appendUniformDecls(GrShaderFlags visibility, SkString*) const = 0; |
126 | |
127 | friend class GrGLSLProgramBuilder; |
128 | }; |
129 | |
130 | #endif |
131 | |