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 #include "GrGLProgram.h" 9 10 #include "builders/GrGLFullProgramBuilder.h" 11 #include "builders/GrGLFragmentOnlyProgramBuilder.h" 12 #include "GrAllocator.h" 13 #include "GrProcessor.h" 14 #include "GrCoordTransform.h" 15 #include "GrGLProcessor.h" 16 #include "GrGpuGL.h" 17 #include "GrGLPathRendering.h" 18 #include "GrGLShaderVar.h" 19 #include "GrGLSL.h" 20 #include "GrOptDrawState.h" 21 #include "SkXfermode.h" 22 23 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) 24 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) 25 26 GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu, 27 const GrGLProgramDesc& desc, 28 const GrGeometryStage* geometryProcessor, 29 const GrFragmentStage* colorStages[], 30 const GrFragmentStage* coverageStages[]) { 31 SkAutoTDelete<GrGLProgramBuilder> builder; 32 if (desc.getHeader().fUseFragShaderOnly) { 33 SkASSERT(gpu->glCaps().pathRenderingSupport()); 34 SkASSERT(gpu->glPathRendering()->texturingMode() == 35 GrGLPathRendering::FixedFunction_TexturingMode); 36 SkASSERT(NULL == geometryProcessor); 37 builder.reset(SkNEW_ARGS(GrGLFragmentOnlyProgramBuilder, (gpu, desc))); 38 } else { 39 builder.reset(SkNEW_ARGS(GrGLFullProgramBuilder, (gpu, desc))); 40 } 41 if (builder->genProgram(geometryProcessor, colorStages, coverageStages)) { 42 SkASSERT(0 != builder->getProgramID()); 43 return SkNEW_ARGS(GrGLProgram, (gpu, desc, *builder)); 44 } 45 return NULL; 46 } 47 48 GrGLProgram::GrGLProgram(GrGpuGL* gpu, 49 const GrGLProgramDesc& desc, 50 const GrGLProgramBuilder& builder) 51 : fColor(GrColor_ILLEGAL) 52 , fCoverage(GrColor_ILLEGAL) 53 , fDstCopyTexUnit(-1) 54 , fBuiltinUniformHandles(builder.getBuiltinUniformHandles()) 55 , fGeometryProcessor(SkSafeRef(builder.getGeometryProcessor())) 56 , fColorEffects(SkRef(builder.getColorEffects())) 57 , fCoverageEffects(SkRef(builder.getCoverageEffects())) 58 , fProgramID(builder.getProgramID()) 59 , fHasVertexShader(builder.hasVertexShader()) 60 , fTexCoordSetCnt(builder.getTexCoordSetCount()) 61 , fDesc(desc) 62 , fGpu(gpu) 63 , fProgramDataManager(gpu, this, builder) { 64 this->initSamplerUniforms(); 65 } 66 67 GrGLProgram::~GrGLProgram() { 68 if (fProgramID) { 69 GL_CALL(DeleteProgram(fProgramID)); 70 } 71 } 72 73 void GrGLProgram::abandon() { 74 fProgramID = 0; 75 } 76 77 void GrGLProgram::initSamplerUniforms() { 78 GL_CALL(UseProgram(fProgramID)); 79 GrGLint texUnitIdx = 0; 80 if (fBuiltinUniformHandles.fDstCopySamplerUni.isValid()) { 81 fProgramDataManager.setSampler(fBuiltinUniformHandles.fDstCopySamplerUni, texUnitIdx); 82 fDstCopyTexUnit = texUnitIdx++; 83 } 84 if (fGeometryProcessor.get()) { 85 fGeometryProcessor->initSamplers(fProgramDataManager, &texUnitIdx); 86 } 87 fColorEffects->initSamplers(fProgramDataManager, &texUnitIdx); 88 fCoverageEffects->initSamplers(fProgramDataManager, &texUnitIdx); 89 } 90 91 /////////////////////////////////////////////////////////////////////////////// 92 93 void GrGLProgram::setData(const GrOptDrawState& optState, 94 GrGpu::DrawType drawType, 95 const GrGeometryStage* geometryProcessor, 96 const GrFragmentStage* colorStages[], 97 const GrFragmentStage* coverageStages[], 98 const GrDeviceCoordTexture* dstCopy, 99 SharedGLState* sharedState) { 100 GrColor color = optState.getColor(); 101 GrColor coverage = optState.getCoverageColor(); 102 103 this->setColor(optState, color, sharedState); 104 this->setCoverage(optState, coverage, sharedState); 105 this->setMatrixAndRenderTargetHeight(drawType, optState); 106 107 if (dstCopy) { 108 if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) { 109 fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyTopLeftUni, 110 static_cast<GrGLfloat>(dstCopy->offset().fX), 111 static_cast<GrGLfloat>(dstCopy->offset().fY)); 112 fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyScaleUni, 113 1.f / dstCopy->texture()->width(), 114 1.f / dstCopy->texture()->height()); 115 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture()); 116 static GrTextureParams kParams; // the default is clamp, nearest filtering. 117 fGpu->bindTexture(fDstCopyTexUnit, kParams, texture); 118 } else { 119 SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid()); 120 SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid()); 121 } 122 } else { 123 SkASSERT(!fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()); 124 SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid()); 125 SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid()); 126 } 127 128 if (fGeometryProcessor.get()) { 129 SkASSERT(geometryProcessor); 130 fGeometryProcessor->setData(fGpu, drawType, fProgramDataManager, geometryProcessor); 131 } 132 fColorEffects->setData(fGpu, drawType, fProgramDataManager, colorStages); 133 fCoverageEffects->setData(fGpu, drawType, fProgramDataManager, coverageStages); 134 135 // PathTexGen state applies to the the fixed function vertex shader. For 136 // custom shaders, it's ignored, so we don't need to change the texgen 137 // settings in that case. 138 if (!fHasVertexShader) { 139 fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt); 140 } 141 } 142 143 void GrGLProgram::setColor(const GrOptDrawState& optState, 144 GrColor color, 145 SharedGLState* sharedState) { 146 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 147 if (!optState.hasColorVertexAttribute()) { 148 switch (header.fColorInput) { 149 case GrGLProgramDesc::kAttribute_ColorInput: 150 SkASSERT(-1 != header.fColorAttributeIndex); 151 if (sharedState->fConstAttribColor != color || 152 sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) { 153 // OpenGL ES only supports the float varieties of glVertexAttrib 154 GrGLfloat c[4]; 155 GrColorToRGBAFloat(color, c); 156 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); 157 sharedState->fConstAttribColor = color; 158 sharedState->fConstAttribColorIndex = header.fColorAttributeIndex; 159 } 160 break; 161 case GrGLProgramDesc::kUniform_ColorInput: 162 if (fColor != color && fBuiltinUniformHandles.fColorUni.isValid()) { 163 // OpenGL ES doesn't support unsigned byte varieties of glUniform 164 GrGLfloat c[4]; 165 GrColorToRGBAFloat(color, c); 166 fProgramDataManager.set4fv(fBuiltinUniformHandles.fColorUni, 1, c); 167 fColor = color; 168 } 169 sharedState->fConstAttribColorIndex = -1; 170 break; 171 case GrGLProgramDesc::kAllOnes_ColorInput: 172 sharedState->fConstAttribColorIndex = -1; 173 break; 174 default: 175 SkFAIL("Unexpected color type."); 176 } 177 } else { 178 sharedState->fConstAttribColorIndex = -1; 179 } 180 } 181 182 void GrGLProgram::setCoverage(const GrOptDrawState& optState, 183 GrColor coverage, 184 SharedGLState* sharedState) { 185 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); 186 if (!optState.hasCoverageVertexAttribute()) { 187 switch (header.fCoverageInput) { 188 case GrGLProgramDesc::kAttribute_ColorInput: 189 if (sharedState->fConstAttribCoverage != coverage || 190 sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) { 191 // OpenGL ES only supports the float varieties of glVertexAttrib 192 GrGLfloat c[4]; 193 GrColorToRGBAFloat(coverage, c); 194 GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c)); 195 sharedState->fConstAttribCoverage = coverage; 196 sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex; 197 } 198 break; 199 case GrGLProgramDesc::kUniform_ColorInput: 200 if (fCoverage != coverage) { 201 // OpenGL ES doesn't support unsigned byte varieties of glUniform 202 GrGLfloat c[4]; 203 GrColorToRGBAFloat(coverage, c); 204 fProgramDataManager.set4fv(fBuiltinUniformHandles.fCoverageUni, 1, c); 205 fCoverage = coverage; 206 } 207 sharedState->fConstAttribCoverageIndex = -1; 208 break; 209 case GrGLProgramDesc::kAllOnes_ColorInput: 210 sharedState->fConstAttribCoverageIndex = -1; 211 break; 212 default: 213 SkFAIL("Unexpected coverage type."); 214 } 215 } else { 216 sharedState->fConstAttribCoverageIndex = -1; 217 } 218 } 219 220 void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, 221 const GrOptDrawState& optState) { 222 const GrRenderTarget* rt = optState.getRenderTarget(); 223 SkISize size; 224 size.set(rt->width(), rt->height()); 225 226 // Load the RT height uniform if it is needed to y-flip gl_FragCoord. 227 if (fBuiltinUniformHandles.fRTHeightUni.isValid() && 228 fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { 229 fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, 230 SkIntToScalar(size.fHeight)); 231 } 232 233 if (GrGpu::IsPathRenderingDrawType(drawType)) { 234 fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin()); 235 } else if (fMatrixState.fRenderTargetOrigin != rt->origin() || 236 fMatrixState.fRenderTargetSize != size || 237 !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) { 238 SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid()); 239 240 fMatrixState.fViewMatrix = optState.getViewMatrix(); 241 fMatrixState.fRenderTargetSize = size; 242 fMatrixState.fRenderTargetOrigin = rt->origin(); 243 244 GrGLfloat viewMatrix[3 * 3]; 245 fMatrixState.getGLMatrix<3>(viewMatrix); 246 fProgramDataManager.setMatrix3f(fBuiltinUniformHandles.fViewMatrixUni, viewMatrix); 247 248 GrGLfloat rtAdjustmentVec[4]; 249 fMatrixState.getRTAdjustmentVec(rtAdjustmentVec); 250 fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); 251 } 252 } 253