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 "builders/GrGLProgramBuilder.h" 13 #include "GrDrawState.h" 14 #include "GrGLContext.h" 15 #include "GrGLProgramDesc.h" 16 #include "GrGLSL.h" 17 #include "GrGLTexture.h" 18 #include "GrGLProgramDataManager.h" 19 20 #include "SkString.h" 21 #include "SkXfermode.h" 22 23 class GrGLProcessor; 24 class GrGLProgramEffects; 25 class GrGLProgramBuilder; 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 */ 36 class GrGLProgram : public SkRefCnt { 37 public: 38 SK_DECLARE_INST_COUNT(GrGLProgram) 39 40 typedef GrGLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles; 41 42 static GrGLProgram* Create(GrGpuGL* gpu, 43 const GrGLProgramDesc& desc, 44 const GrGeometryStage* geometryProcessor, 45 const GrFragmentStage* colorStages[], 46 const GrFragmentStage* coverageStages[]); 47 48 virtual ~GrGLProgram(); 49 50 /** 51 * Call to abandon GL objects owned by this program. 52 */ 53 void abandon(); 54 55 const GrGLProgramDesc& getDesc() { return fDesc; } 56 57 /** 58 * Gets the GL program ID for this program. 59 */ 60 GrGLuint programID() const { return fProgramID; } 61 62 bool hasVertexShader() const { return fHasVertexShader; } 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 104 /** 105 * Gets a matrix that goes from local coords to Skia's device coordinates. 106 */ 107 template<int Size> void getGLMatrix(GrGLfloat* destMatrix) { 108 GrGLGetMatrix<Size>(destMatrix, fViewMatrix); 109 } 110 111 /** 112 * Gets a matrix that goes from local coordinates to GL normalized device coords. 113 */ 114 template<int Size> void getRTAdjustedGLMatrix(GrGLfloat* destMatrix) { 115 SkMatrix combined; 116 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 117 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 118 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1, 119 0, 0, 1); 120 } else { 121 combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 122 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1, 123 0, 0, 1); 124 } 125 combined.preConcat(fViewMatrix); 126 GrGLGetMatrix<Size>(destMatrix, combined); 127 } 128 129 /** 130 * Gets a vec4 that adjusts the position from Skia device coords to GL's normalized device 131 * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is 132 * applied as such: 133 * pos.x = dot(v.xy, pos.xz) 134 * pos.y = dot(v.zq, pos.yz) 135 */ 136 void getRTAdjustmentVec(GrGLfloat* destVec) { 137 destVec[0] = 2.f / fRenderTargetSize.fWidth; 138 destVec[1] = -1.f; 139 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 140 destVec[2] = -2.f / fRenderTargetSize.fHeight; 141 destVec[3] = 1.f; 142 } else { 143 destVec[2] = 2.f / fRenderTargetSize.fHeight; 144 destVec[3] = -1.f; 145 } 146 } 147 }; 148 149 /** 150 * This function uploads uniforms and calls each GrGLProcessor's setData. It is called before a 151 * draw occurs using the program after the program has already been bound. It also uses the 152 * GrGpuGL object to bind the textures required by the GrGLProcessors. The color and coverage 153 * stages come from GrGLProgramDesc::Build(). 154 */ 155 void setData(const GrOptDrawState&, 156 GrGpu::DrawType, 157 const GrGeometryStage* geometryProcessor, 158 const GrFragmentStage* colorStages[], 159 const GrFragmentStage* coverageStages[], 160 const GrDeviceCoordTexture* dstCopy, // can be NULL 161 SharedGLState*); 162 163 private: 164 typedef GrGLProgramDataManager::UniformHandle UniformHandle; 165 166 GrGLProgram(GrGpuGL*, 167 const GrGLProgramDesc&, 168 const GrGLProgramBuilder&); 169 170 // Sets the texture units for samplers. 171 void initSamplerUniforms(); 172 173 // Helper for setData(). Makes GL calls to specify the initial color when there is not 174 // per-vertex colors. 175 void setColor(const GrOptDrawState&, GrColor color, SharedGLState*); 176 177 // Helper for setData(). Makes GL calls to specify the initial coverage when there is not 178 // per-vertex coverages. 179 void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*); 180 181 // Helper for setData() that sets the view matrix and loads the render target height uniform 182 void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState&); 183 184 // these reflect the current values of uniforms (GL uniform values travel with program) 185 MatrixState fMatrixState; 186 GrColor fColor; 187 GrColor fCoverage; 188 int fDstCopyTexUnit; 189 190 BuiltinUniformHandles fBuiltinUniformHandles; 191 SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor; 192 SkAutoTUnref<GrGLProgramEffects> fColorEffects; 193 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; 194 GrGLuint fProgramID; 195 bool fHasVertexShader; 196 int fTexCoordSetCnt; 197 198 GrGLProgramDesc fDesc; 199 GrGpuGL* fGpu; 200 201 GrGLProgramDataManager fProgramDataManager; 202 203 typedef SkRefCnt INHERITED; 204 }; 205 206 #endif 207