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