1 /* 2 * Copyright 2011 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 9 #ifndef GrGLProgram_DEFINED 10 #define GrGLProgram_DEFINED 11 12 #include "GrDrawState.h" 13 #include "GrGLContext.h" 14 #include "GrGLProgramDesc.h" 15 #include "GrGLSL.h" 16 #include "GrGLTexture.h" 17 #include "GrGLUniformManager.h" 18 19 #include "SkString.h" 20 #include "SkXfermode.h" 21 22 class GrBinHashKeyBuilder; 23 class GrGLEffect; 24 class GrGLShaderBuilder; 25 26 /** 27 * This class manages a GPU program and records per-program information. 28 * We can specify the attribute locations so that they are constant 29 * across our shaders. But the driver determines the uniform locations 30 * at link time. We don't need to remember the sampler uniform location 31 * because we will bind a texture slot to it and never change it 32 * Uniforms are program-local so we can't rely on fHWState to hold the 33 * previous uniform state after a program change. 34 */ 35 class GrGLProgram : public GrRefCnt { 36 public: 37 SK_DECLARE_INST_COUNT(GrGLProgram) 38 39 static GrGLProgram* Create(const GrGLContext& gl, 40 const GrGLProgramDesc& desc, 41 const GrEffectStage* colorStages[], 42 const GrEffectStage* coverageStages[]); 43 44 virtual ~GrGLProgram(); 45 46 /** 47 * Call to abandon GL objects owned by this program. 48 */ 49 void abandon(); 50 51 /** 52 * The shader may modify the blend coefficients. Params are in/out. 53 */ 54 void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const; 55 56 const GrGLProgramDesc& getDesc() { return fDesc; } 57 58 /** 59 * Gets the GL program ID for this program. 60 */ 61 GrGLuint programID() const { return fProgramID; } 62 63 /** 64 * Some GL state that is relevant to programs is not stored per-program. In particular color 65 * and coverage attributes can be global state. This struct is read and updated by 66 * GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state 67 * redundantly. 68 */ 69 struct SharedGLState { 70 GrColor fConstAttribColor; 71 int fConstAttribColorIndex; 72 GrColor fConstAttribCoverage; 73 int fConstAttribCoverageIndex; 74 75 SharedGLState() { this->invalidate(); } 76 void invalidate() { 77 fConstAttribColor = GrColor_ILLEGAL; 78 fConstAttribColorIndex = -1; 79 fConstAttribCoverage = GrColor_ILLEGAL; 80 fConstAttribCoverageIndex = -1; 81 } 82 }; 83 84 /** 85 * The GrDrawState's view matrix along with the aspects of the render target determine the 86 * matrix sent to GL. The size of the render target affects the GL matrix because we must 87 * convert from Skia device coords to GL's normalized coords. Also the origin of the render 88 * target may require us to perform a mirror-flip. 89 */ 90 struct MatrixState { 91 SkMatrix fViewMatrix; 92 SkISize fRenderTargetSize; 93 GrSurfaceOrigin fRenderTargetOrigin; 94 95 MatrixState() { this->invalidate(); } 96 void invalidate() { 97 fViewMatrix = SkMatrix::InvalidMatrix(); 98 fRenderTargetSize.fWidth = -1; 99 fRenderTargetSize.fHeight = -1; 100 fRenderTargetOrigin = (GrSurfaceOrigin) -1; 101 } 102 }; 103 104 /** 105 * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a 106 * draw occurs using the program after the program has already been bound. It also uses the 107 * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage 108 * stages come from GrGLProgramDesc::Build(). 109 */ 110 void setData(GrGpuGL*, 111 GrDrawState::BlendOptFlags, 112 const GrEffectStage* colorStages[], 113 const GrEffectStage* coverageStages[], 114 const GrDeviceCoordTexture* dstCopy, // can be NULL 115 SharedGLState*); 116 117 private: 118 typedef GrGLUniformManager::UniformHandle UniformHandle; 119 120 // handles for uniforms (aside from per-effect samplers) 121 struct UniformHandles { 122 UniformHandle fViewMatrixUni; 123 UniformHandle fColorUni; 124 UniformHandle fCoverageUni; 125 UniformHandle fColorFilterUni; 126 127 // We use the render target height to provide a y-down frag coord when specifying 128 // origin_upper_left is not supported. 129 UniformHandle fRTHeightUni; 130 131 // Uniforms for computing texture coords to do the dst-copy lookup 132 UniformHandle fDstCopyTopLeftUni; 133 UniformHandle fDstCopyScaleUni; 134 UniformHandle fDstCopySamplerUni; 135 136 UniformHandles() { 137 fViewMatrixUni = GrGLUniformManager::kInvalidUniformHandle; 138 fColorUni = GrGLUniformManager::kInvalidUniformHandle; 139 fCoverageUni = GrGLUniformManager::kInvalidUniformHandle; 140 fColorFilterUni = GrGLUniformManager::kInvalidUniformHandle; 141 fRTHeightUni = GrGLUniformManager::kInvalidUniformHandle; 142 fDstCopyTopLeftUni = GrGLUniformManager::kInvalidUniformHandle; 143 fDstCopyScaleUni = GrGLUniformManager::kInvalidUniformHandle; 144 fDstCopySamplerUni = GrGLUniformManager::kInvalidUniformHandle; 145 } 146 }; 147 148 typedef SkSTArray<4, UniformHandle, true> SamplerUniSArray; 149 typedef SkSTArray<4, int, true> TextureUnitSArray; 150 151 struct EffectAndSamplers { 152 EffectAndSamplers() : fGLEffect(NULL) {} 153 ~EffectAndSamplers() { delete fGLEffect; } 154 GrGLEffect* fGLEffect; 155 SamplerUniSArray fSamplerUnis; // sampler uni handles for effect's GrTextureAccess 156 TextureUnitSArray fTextureUnits; // texture unit used for each entry of fSamplerUnis 157 }; 158 159 GrGLProgram(const GrGLContext& gl, 160 const GrGLProgramDesc& desc, 161 const GrEffectStage* colorStages[], 162 const GrEffectStage* coverageStages[]); 163 164 bool succeeded() const { return 0 != fProgramID; } 165 166 /** 167 * This is the heavy initialization routine for building a GLProgram. colorStages and 168 * coverageStages correspond to the output of GrGLProgramDesc::Build(). 169 */ 170 bool genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]); 171 172 GrSLConstantVec genInputColor(GrGLShaderBuilder* builder, SkString* inColor); 173 174 GrSLConstantVec genInputCoverage(GrGLShaderBuilder* builder, SkString* inCoverage); 175 176 void genGeometryShader(GrGLShaderBuilder* segments) const; 177 178 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program 179 bool bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder, 180 bool bindColorOut, 181 bool bindDualSrcOut); 182 183 // Sets the texture units for samplers 184 void initSamplerUniforms(); 185 void initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx); 186 187 bool compileShaders(const GrGLShaderBuilder& builder); 188 189 const char* adjustInColor(const SkString& inColor) const; 190 191 // Helper for setData(). 192 void setEffectData(GrGpuGL* gpu, const GrEffectStage& stage, const EffectAndSamplers& effect); 193 194 // Helper for setData(). Makes GL calls to specify the initial color when there is not 195 // per-vertex colors. 196 void setColor(const GrDrawState&, GrColor color, SharedGLState*); 197 198 // Helper for setData(). Makes GL calls to specify the initial coverage when there is not 199 // per-vertex coverages. 200 void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*); 201 202 // Helper for setData() that sets the view matrix and loads the render target height uniform 203 void setMatrixAndRenderTargetHeight(const GrDrawState&); 204 205 // GL IDs 206 GrGLuint fVShaderID; 207 GrGLuint fGShaderID; 208 GrGLuint fFShaderID; 209 GrGLuint fProgramID; 210 211 // these reflect the current values of uniforms (GL uniform values travel with program) 212 MatrixState fMatrixState; 213 GrColor fColor; 214 GrColor fCoverage; 215 GrColor fColorFilterColor; 216 int fDstCopyTexUnit; 217 218 SkTArray<EffectAndSamplers> fColorEffects; 219 SkTArray<EffectAndSamplers> fCoverageEffects; 220 221 GrGLProgramDesc fDesc; 222 const GrGLContext& fContext; 223 224 GrGLUniformManager fUniformManager; 225 UniformHandles fUniformHandles; 226 227 typedef GrRefCnt INHERITED; 228 }; 229 230 #endif 231