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
18class GrGLSLProgramBuilder;
19class GrGLSLShaderBuilder;
20class GrSamplerState;
21class GrSurfaceProxy;
22
23// Handles for program uniforms (other than per-effect uniforms)
24struct 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
33class GrGLSLUniformHandler {
34public:
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
95protected:
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
109private:
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