1 /* 2 * Copyright 2014 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 "GrGLFullProgramBuilder.h" 9 #include "../GrGLGeometryProcessor.h" 10 #include "../GrGpuGL.h" 11 12 GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu, 13 const GrGLProgramDesc& desc) 14 : INHERITED(gpu, desc) 15 , fGLGeometryProcessorEmitter(this) 16 , fGS(this) 17 , fVS(this) { 18 } 19 20 void 21 GrGLFullProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor, 22 const GrFragmentStage* colorStages[], 23 const GrFragmentStage* coverageStages[], 24 GrGLSLExpr4* inputColor, 25 GrGLSLExpr4* inputCoverage) { 26 fVS.emitCodeBeforeEffects(inputColor, inputCoverage); 27 28 /////////////////////////////////////////////////////////////////////////// 29 // emit the per-effect code for both color and coverage effects 30 31 EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType); 32 fColorEffects.reset(this->onCreateAndEmitEffects(colorStages, 33 this->desc().numColorEffects(), 34 colorKeyProvider, 35 inputColor)); 36 37 if (geometryProcessor) { 38 const GrGeometryProcessor& gp = *geometryProcessor->getGeometryProcessor(); 39 fGLGeometryProcessorEmitter.set(&gp); 40 fEffectEmitter = &fGLGeometryProcessorEmitter; 41 fVS.emitAttributes(gp); 42 GrGLSLExpr4 gpInputCoverage = *inputCoverage; 43 GrGLSLExpr4 gpOutputCoverage; 44 EffectKeyProvider gpKeyProvider(&this->desc(), 45 EffectKeyProvider::kGeometryProcessor_EffectType); 46 bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCoords(); 47 fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, (1, useLocalCoords))); 48 this->INHERITED::emitEffect(*geometryProcessor, 0, gpKeyProvider, &gpInputCoverage, 49 &gpOutputCoverage); 50 fGeometryProcessor.reset(fProgramEffects.detach()); 51 *inputCoverage = gpOutputCoverage; 52 } 53 54 EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType); 55 fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages, 56 this->desc().numCoverageEffects(), 57 coverageKeyProvider, 58 inputCoverage)); 59 60 fVS.emitCodeAfterEffects(); 61 } 62 63 void GrGLFullProgramBuilder::addVarying(GrSLType type, 64 const char* name, 65 const char** vsOutName, 66 const char** fsInName, 67 GrGLShaderVar::Precision fsPrecision) { 68 fVS.addVarying(type, name, vsOutName); 69 70 SkString* fsInputName = fVS.fOutputs.back().accessName(); 71 72 #if GR_GL_EXPERIMENTAL_GS 73 if (desc().getHeader().fExperimentalGS) { 74 // TODO let the caller use these names 75 fGS.addVarying(type, fsInputName->c_str(), NULL); 76 fsInputName = fGS.fOutputs.back().accessName(); 77 } 78 #endif 79 fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision); 80 } 81 82 GrGLFullProgramBuilder::VaryingHandle 83 GrGLFullProgramBuilder::addSeparableVarying(GrSLType type, 84 const char* name, 85 const char** vsOutName, 86 const char** fsInName) { 87 addVarying(type, name, vsOutName, fsInName); 88 SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back(); 89 varying.fVariable = fFS.fInputs.back(); 90 return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos.count() - 1); 91 } 92 93 GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects( 94 const GrFragmentStage* effectStages[], 95 int effectCnt, 96 const GrGLProgramDesc::EffectKeyProvider& keyProvider, 97 GrGLSLExpr4* inOutFSColor) { 98 fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, 99 (effectCnt, 100 this->getVertexShaderBuilder()->hasExplicitLocalCoords()))); 101 this->INHERITED::createAndEmitEffects(effectStages, 102 effectCnt, 103 keyProvider, 104 inOutFSColor); 105 return fProgramEffects.detach(); 106 } 107 108 void GrGLFullProgramBuilder::emitEffect(const GrProcessorStage& stage, 109 const GrProcessorKey& key, 110 const char* outColor, 111 const char* inColor, 112 int stageIndex) { 113 SkASSERT(fProgramEffects.get()); 114 const GrProcessor& effect = *stage.getProcessor(); 115 SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms()); 116 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures()); 117 118 this->emitTransforms(stage, &coords); 119 this->emitSamplers(effect, &samplers); 120 121 SkASSERT(fEffectEmitter); 122 GrGLProcessor* glEffect = fEffectEmitter->createGLInstance(); 123 fProgramEffects->addEffect(glEffect); 124 125 // Enclose custom code in a block to avoid namespace conflicts 126 SkString openBrace; 127 openBrace.printf("{ // Stage %d: %s\n", stageIndex, glEffect->name()); 128 fFS.codeAppend(openBrace.c_str()); 129 fVS.codeAppend(openBrace.c_str()); 130 131 fEffectEmitter->emit(key, outColor, inColor, coords, samplers); 132 133 fVS.codeAppend("\t}\n"); 134 fFS.codeAppend("\t}\n"); 135 } 136 137 void GrGLFullProgramBuilder::emitTransforms(const GrProcessorStage& effectStage, 138 GrGLProcessor::TransformedCoordsArray* outCoords) { 139 SkTArray<GrGLVertexProgramEffects::Transform, true>& transforms = 140 fProgramEffects->addTransforms(); 141 const GrProcessor* effect = effectStage.getProcessor(); 142 int numTransforms = effect->numTransforms(); 143 transforms.push_back_n(numTransforms); 144 145 SkTArray<GrGLVertexProgramEffects::PathTransform, true>* pathTransforms = NULL; 146 const GrGLCaps* glCaps = this->ctxInfo().caps(); 147 if (glCaps->pathRenderingSupport() && 148 this->gpu()->glPathRendering()->texturingMode() == 149 GrGLPathRendering::SeparableShaders_TexturingMode) { 150 pathTransforms = &fProgramEffects->addPathTransforms(); 151 pathTransforms->push_back_n(numTransforms); 152 } 153 154 for (int t = 0; t < numTransforms; t++) { 155 const char* uniName = "StageMatrix"; 156 GrSLType varyingType = 157 effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ? 158 kVec3f_GrSLType : 159 kVec2f_GrSLType; 160 161 SkString suffixedUniName; 162 if (0 != t) { 163 suffixedUniName.append(uniName); 164 suffixedUniName.appendf("_%i", t); 165 uniName = suffixedUniName.c_str(); 166 } 167 transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility, 168 kMat33f_GrSLType, 169 uniName, 170 &uniName); 171 172 const char* varyingName = "MatrixCoord"; 173 SkString suffixedVaryingName; 174 if (0 != t) { 175 suffixedVaryingName.append(varyingName); 176 suffixedVaryingName.appendf("_%i", t); 177 varyingName = suffixedVaryingName.c_str(); 178 } 179 const char* vsVaryingName; 180 const char* fsVaryingName; 181 if (pathTransforms) { 182 (*pathTransforms)[t].fHandle = 183 this->addSeparableVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName); 184 (*pathTransforms)[t].fType = varyingType; 185 } else { 186 this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName); 187 } 188 189 const GrGLShaderVar& coords = 190 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ? 191 fVS.positionAttribute() : 192 fVS.localCoordsAttribute(); 193 // varying = matrix * coords (logically) 194 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); 195 if (kVec2f_GrSLType == varyingType) { 196 fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;", 197 vsVaryingName, uniName, coords.c_str()); 198 } else { 199 fVS.codeAppendf("%s = %s * vec3(%s, 1);", 200 vsVaryingName, uniName, coords.c_str()); 201 } 202 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, 203 (SkString(fsVaryingName), varyingType)); 204 } 205 } 206 207 bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId, 208 SkTDArray<GrGLuint>* shaderIds) const { 209 return INHERITED::compileAndAttachShaders(programId, shaderIds) 210 && fVS.compileAndAttachShaders(programId, shaderIds) 211 #if GR_GL_EXPERIMENTAL_GS 212 && (!desc().getHeader().fExperimentalGS 213 || fGS.compileAndAttachShaders(programId, shaderIds)) 214 #endif 215 ; 216 } 217 218 void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) { 219 fVS.bindProgramLocations(programId); 220 INHERITED::bindProgramLocations(programId); 221 } 222