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