• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GrGLFullProgramBuilder(GrGpuGL * gpu,const GrGLProgramDesc & desc)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
createAndEmitEffects(const GrGeometryStage * geometryProcessor,const GrFragmentStage * colorStages[],const GrFragmentStage * coverageStages[],GrGLSLExpr4 * inputColor,GrGLSLExpr4 * inputCoverage)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 
addVarying(GrSLType type,const char * name,const char ** vsOutName,const char ** fsInName,GrGLShaderVar::Precision fsPrecision)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
addSeparableVarying(GrSLType type,const char * name,const char ** vsOutName,const char ** fsInName)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 
onCreateAndEmitEffects(const GrFragmentStage * effectStages[],int effectCnt,const GrGLProgramDesc::EffectKeyProvider & keyProvider,GrGLSLExpr4 * inOutFSColor)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 
emitEffect(const GrProcessorStage & stage,const GrProcessorKey & key,const char * outColor,const char * inColor,int stageIndex)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 
emitTransforms(const GrProcessorStage & effectStage,GrGLProcessor::TransformedCoordsArray * outCoords)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 
compileAndAttachShaders(GrGLuint programId,SkTDArray<GrGLuint> * shaderIds) const207 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 
bindProgramLocations(GrGLuint programId)218 void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) {
219     fVS.bindProgramLocations(programId);
220     INHERITED::bindProgramLocations(programId);
221 }
222