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 23 class GrBinHashKeyBuilder; 24 class GrGLEffect; 25 class GrGLProgramEffects; 26 class GrGLShaderBuilder; 27 28 /** 29 * This class manages a GPU program and records per-program information. 30 * We can specify the attribute locations so that they are constant 31 * across our shaders. But the driver determines the uniform locations 32 * at link time. We don't need to remember the sampler uniform location 33 * because we will bind a texture slot to it and never change it 34 * Uniforms are program-local so we can't rely on fHWState to hold the 35 * previous uniform state after a program change. 36 */ 37 class GrGLProgram : public SkRefCnt { 38 public: 39 SK_DECLARE_INST_COUNT(GrGLProgram) 40 41 static GrGLProgram* Create(GrGpuGL* gpu, 42 const GrGLProgramDesc& desc, 43 const GrEffectStage* colorStages[], 44 const GrEffectStage* coverageStages[]); 45 46 virtual ~GrGLProgram(); 47 48 /** 49 * Call to abandon GL objects owned by this program. 50 */ 51 void abandon(); 52 53 /** 54 * The shader may modify the blend coefficients. Params are in/out. 55 */ 56 void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const; 57 58 const GrGLProgramDesc& getDesc() { return fDesc; } 59 60 /** 61 * Gets the GL program ID for this program. 62 */ 63 GrGLuint programID() const { return fBuilderOutput.fProgramID; } 64 65 bool hasVertexShader() const { return fBuilderOutput.fHasVertexShader; } 66 67 /** 68 * Some GL state that is relevant to programs is not stored per-program. In particular color 69 * and coverage attributes can be global state. This struct is read and updated by 70 * GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state 71 * redundantly. 72 */ 73 struct SharedGLState { 74 GrColor fConstAttribColor; 75 int fConstAttribColorIndex; 76 GrColor fConstAttribCoverage; 77 int fConstAttribCoverageIndex; 78 79 SharedGLState() { this->invalidate(); } 80 void invalidate() { 81 fConstAttribColor = GrColor_ILLEGAL; 82 fConstAttribColorIndex = -1; 83 fConstAttribCoverage = GrColor_ILLEGAL; 84 fConstAttribCoverageIndex = -1; 85 } 86 }; 87 88 /** 89 * The GrDrawState's view matrix along with the aspects of the render target determine the 90 * matrix sent to GL. The size of the render target affects the GL matrix because we must 91 * convert from Skia device coords to GL's normalized coords. Also the origin of the render 92 * target may require us to perform a mirror-flip. 93 */ 94 struct MatrixState { 95 SkMatrix fViewMatrix; 96 SkISize fRenderTargetSize; 97 GrSurfaceOrigin fRenderTargetOrigin; 98 99 MatrixState() { this->invalidate(); } 100 void invalidate() { 101 fViewMatrix = SkMatrix::InvalidMatrix(); 102 fRenderTargetSize.fWidth = -1; 103 fRenderTargetSize.fHeight = -1; 104 fRenderTargetOrigin = (GrSurfaceOrigin) -1; 105 } 106 107 /** 108 * Gets a matrix that goes from local coords to Skia's device coordinates. 109 */ 110 template<int Size> void getGLMatrix(GrGLfloat* destMatrix) { 111 GrGLGetMatrix<Size>(destMatrix, fViewMatrix); 112 } 113 114 /** 115 * Gets a matrix that goes from local coordinates to GL normalized device coords. 116 */ 117 template<int Size> void getRTAdjustedGLMatrix(GrGLfloat* destMatrix) { 118 SkMatrix combined; 119 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 120 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 121 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1, 122 0, 0, 1); 123 } else { 124 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 125 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1, 126 0, 0, 1); 127 } 128 combined.preConcat(fViewMatrix); 129 GrGLGetMatrix<Size>(destMatrix, combined); 130 } 131 132 /** 133 * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device 134 * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is 135 * applied as such: 136 * pos.x = dot(v.xy, pos.xz) 137 * pos.y = dot(v.zq, pos.yz) 138 */ 139 void getRTAdjustmentVec(GrGLfloat* destVec) { 140 destVec[0] = 2.f / fRenderTargetSize.fWidth; 141 destVec[1] = -1.f; 142 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 143 destVec[2] = -2.f / fRenderTargetSize.fHeight; 144 destVec[3] = 1.f; 145 } else { 146 destVec[2] = 2.f / fRenderTargetSize.fHeight; 147 destVec[3] = -1.f; 148 } 149 } 150 }; 151 152 /** 153 * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a 154 * draw occurs using the program after the program has already been bound. It also uses the 155 * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage 156 * stages come from GrGLProgramDesc::Build(). 157 */ 158 void setData(GrDrawState::BlendOptFlags, 159 const GrEffectStage* colorStages[], 160 const GrEffectStage* coverageStages[], 161 const GrDeviceCoordTexture* dstCopy, // can be NULL 162 SharedGLState*); 163 164 private: 165 typedef GrGLUniformManager::UniformHandle UniformHandle; 166 167 GrGLProgram(GrGpuGL*, 168 const GrGLProgramDesc&, 169 GrGLUniformManager*, 170 const GrGLShaderBuilder::GenProgramOutput&); 171 172 // Sets the texture units for samplers. 173 void initSamplerUniforms(); 174 175 // Helper for setData(). Makes GL calls to specify the initial color when there is not 176 // per-vertex colors. 177 void setColor(const GrDrawState&, GrColor color, SharedGLState*); 178 179 // Helper for setData(). Makes GL calls to specify the initial coverage when there is not 180 // per-vertex coverages. 181 void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*); 182 183 // Helper for setData() that sets the view matrix and loads the render target height uniform 184 void setMatrixAndRenderTargetHeight(const GrDrawState&); 185 186 // these reflect the current values of uniforms (GL uniform values travel with program) 187 MatrixState fMatrixState; 188 GrColor fColor; 189 GrColor fCoverage; 190 int fDstCopyTexUnit; 191 192 GrGLShaderBuilder::GenProgramOutput fBuilderOutput; 193 194 GrGLProgramDesc fDesc; 195 GrGpuGL* fGpu; 196 197 SkAutoTUnref<GrGLUniformManager> fUniformManager; 198 199 typedef SkRefCnt INHERITED; 200 }; 201 202 #endif 203