Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: src/gpu/gl/builders/GrGLProgramBuilder.cpp

Issue 611653002: Cleanup of shader building system (Closed) Base URL: https://skia.googlesource.com/skia.git@solo_gp
Patch Set: more cleanup Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrGLProgramBuilder.h"
9 #include "gl/GrGLGeometryProcessor.h"
8 #include "gl/GrGLProgram.h" 10 #include "gl/GrGLProgram.h"
9 #include "gl/GrGLSLPrettyPrint.h" 11 #include "gl/GrGLSLPrettyPrint.h"
10 #include "gl/GrGLUniformHandle.h" 12 #include "gl/GrGLUniformHandle.h"
13 #include "../GrGpuGL.h"
11 #include "GrCoordTransform.h" 14 #include "GrCoordTransform.h"
12 #include "../GrGpuGL.h" 15 #include "GrGLESNvprProgramBuilder.h"
13 #include "GrGLFragmentShaderBuilder.h" 16 #include "GrGLNvprProgramBuilder.h"
14 #include "GrGLProgramBuilder.h" 17 #include "GrGLSkiaProgramBuilder.h"
15 #include "GrTexture.h" 18 #include "GrTexture.h"
16 #include "GrGLVertexShaderBuilder.h"
17 #include "SkRTConf.h" 19 #include "SkRTConf.h"
18 #include "SkTraceEvent.h" 20 #include "SkTraceEvent.h"
19 21
20 namespace {
21 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) 22 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
22 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) 23 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
23 24
24 // number of each input/output type in a single allocation block
25 static const int kVarsPerBlock = 8;
26
27 // ES2 FS only guarantees mediump and lowp support 25 // ES2 FS only guarantees mediump and lowp support
28 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar: :kMedium_Precision; 26 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar: :kMedium_Precision;
29 }
30
31 //////////////////////////////////////////////////////////////////////////////// ///////////////////
32
33 bool GrGLProgramBuilder::genProgram(const GrGeometryStage* geometryProcessor,
34 const GrFragmentStage* colorStages[],
35 const GrFragmentStage* coverageStages[]) {
36 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
37
38 fFS.emitCodeBeforeEffects();
39
40 ///////////////////////////////////////////////////////////////////////////
41 // get the initial color and coverage to feed into the first effect in each effect chain
42
43 GrGLSLExpr4 inputColor;
44 GrGLSLExpr4 inputCoverage;
45
46 if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
47 const char* name;
48 fUniformHandles.fColorUni =
49 this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
50 kVec4f_GrSLType,
51 "Color",
52 &name);
53 inputColor = GrGLSLExpr4(name);
54 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
55 inputColor = GrGLSLExpr4(1);
56 }
57
58 if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
59 const char* name;
60 fUniformHandles.fCoverageUni =
61 this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
62 kVec4f_GrSLType,
63 "Coverage",
64 &name);
65 inputCoverage = GrGLSLExpr4(name);
66 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
67 inputCoverage = GrGLSLExpr4(1);
68 }
69
70 // Subclasses drive effect emitting
71 this->createAndEmitEffects(geometryProcessor, colorStages, coverageStages, & inputColor,
72 &inputCoverage);
73
74 fFS.emitCodeAfterEffects(inputColor, inputCoverage);
75
76 if (!this->finish()) {
77 return false;
78 }
79
80 return true;
81 }
82 27
83 ////////////////////////////////////////////////////////////////////////////// 28 //////////////////////////////////////////////////////////////////////////////
84 29
30 const int GrGLProgramBuilder::kVarsPerBlock = 8;
31
32 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrGLProgramDesc& desc,
33 GrGpu::DrawType drawType,
34 const GrGeometryStage* geometryPr ocessor,
35 const GrFragmentStage* colorStage s[],
36 const GrFragmentStage* coverageSt ages[],
37 GrGpuGL* gpu) {
38 // create a builder. This will be handed off to effects so they can use it to add
39 // uniforms, varyings, textures, etc
40 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc,
41 drawType,
42 SkToBool(geom etryProcessor),
43 gpu));
44
45 GrGLProgramBuilder* pb = builder.get();
46 const GrGLProgramDesc::KeyHeader& header = pb->header();
47
48 // emit code to read the dst copy texture, if necessary
49 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey
50 && !gpu->glCaps().fbFetchSupport()) {
51 pb->fFS.emitCodeToReadDstTexture();
52 }
53
54 // On any post 1.10 GLSL supporting GPU, we declare custom output
55 if (k110_GrGLSLGeneration != gpu->glslGeneration()) {
56 pb->fFS.enableCustomOutput();
57 }
58
59 // get the initial color and coverage to feed into the first effect in each effect chain
60 GrGLSLExpr4 inputColor, inputCoverage;
61 pb->setupUniformColorIfNeeded(header.fColorInput, "Color", &inputColor);
62 pb->setupUniformColorIfNeeded(header.fCoverageInput, "Coverage", &inputCover age);
63
64 // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES) , then we may have
65 // to setup a few more things like builtin vertex attributes
66 bool hasVertexShader = !header.fUseFragShaderOnly;
67 if (hasVertexShader) {
68 pb->fVS.setupLocalCoords();
69 pb->transformGLToSkiaCoords();
70 if (header.fEmitsPointSize) {
71 pb->fVS.codeAppend("gl_PointSize = 1.0;");
72 }
73 if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
74 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor);
75 }
76 if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
77 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage);
78 }
79 }
80
81 pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages, &inputColor,
82 &inputCoverage);
83
84 if (hasVertexShader) {
85 pb->transformSkiaToGLCoords();
86 }
87
88 // write the secondary color output if necessary
89 bool hasSecondaryOutput =
90 (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutpu tType);
91 if (hasSecondaryOutput) {
92 pb->enableSecondaryOutput(inputColor, inputCoverage);
93 }
94
95 pb->combineColorAndCoverage(inputColor, inputCoverage);
96
97 return pb->compileBindLinkCreate();
98 }
99
100 GrGLProgramBuilder*
101 GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
102 GrGpu::DrawType drawType,
103 bool hasGeometryProcessor,
104 GrGpuGL* gpu) {
105 if (desc.getHeader().fUseFragShaderOnly) {
106 SkASSERT(gpu->glCaps().pathRenderingSupport());
107 SkASSERT(gpu->glPathRendering()->texturingMode() ==
108 GrGLPathRendering::FixedFunction_TexturingMode);
109 SkASSERT(!hasGeometryProcessor);
110 return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, desc));
111 } else if (GrGpu::IsPathRenderingDrawType(drawType)) {
112 SkASSERT(gpu->glCaps().pathRenderingSupport());
113 SkASSERT(gpu->glPathRendering()->texturingMode() ==
114 GrGLPathRendering::SeparableShaders_TexturingMode);
115 SkASSERT(!hasGeometryProcessor);
116 return SkNEW_ARGS(GrGLESNvprProgramBuilder, (gpu, desc));
117 } else {
118 return SkNEW_ARGS(GrGLSkiaProgramBuilder, (gpu, desc));
119 }
120 }
121
122 /////////////////////////////////////////////////////////////////////////////
123
85 GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, 124 GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
86 const GrGLProgramDesc& desc) 125 const GrGLProgramDesc& desc)
87 : fEffectEmitter(NULL) 126 : fVS(this)
88 , fFragOnly(SkToBool(desc.getHeader().fUseFragShaderOnly)) 127 , fGS(this)
89 , fTexCoordSetCnt(0)
90 , fProgramID(0)
91 , fFS(this, desc) 128 , fFS(this, desc)
92 , fSeparableVaryingInfos(kVarsPerBlock) 129 , fOutOfStage(true)
93 , fGrProcessorEmitter(this) 130 , fStageIndex(-1)
94 , fDesc(desc) 131 , fDesc(desc)
95 , fGpu(gpu) 132 , fGpu(gpu)
96 , fUniforms(kVarsPerBlock) { 133 , fUniforms(kVarsPerBlock) {
97 } 134 }
98 135
136 void GrGLProgramBuilder::addVarying(GrSLType type,
137 const char* name,
138 const char** vsOutName,
139 const char** fsInName,
140 GrGLShaderVar::Precision fsPrecision) {
141 SkString* fsInputName = fVS.addVarying(type, name, vsOutName);
142 fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision);
143 }
144
99 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na me) { 145 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na me) {
100 if ('\0' == prefix) { 146 if ('\0' == prefix) {
101 *out = name; 147 *out = name;
102 } else { 148 } else {
103 out->printf("%c%s", prefix, name); 149 out->printf("%c%s", prefix, name);
104 } 150 }
105 if (fCodeStage.inStageCode()) { 151 if (!fOutOfStage) {
106 if (out->endsWith('_')) { 152 if (out->endsWith('_')) {
107 // Names containing "__" are reserved. 153 // Names containing "__" are reserved.
108 out->append("x"); 154 out->append("x");
109 } 155 }
110 out->appendf("_Stage%d", fCodeStage.stageIndex()); 156 out->appendf("_Stage%d", fStageIndex);
111 } 157 }
112 } 158 }
113 159
114 GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32 _t visibility, 160 GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32 _t visibility,
115 GrSLTy pe type, 161 GrSLTy pe type,
116 const char* name, 162 const char* name,
117 int co unt, 163 int co unt,
118 const char** outName) { 164 const char** outName) {
119 SkASSERT(name && strlen(name)); 165 SkASSERT(name && strlen(name));
120 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr agment_Visibility); 166 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr agment_Visibility);
(...skipping 14 matching lines...) Expand all
135 // the fragment and vertex precisions must match 181 // the fragment and vertex precisions must match
136 uni.fVariable.setPrecision(kDefaultFragmentPrecision); 182 uni.fVariable.setPrecision(kDefaultFragmentPrecision);
137 } 183 }
138 184
139 if (outName) { 185 if (outName) {
140 *outName = uni.fVariable.c_str(); 186 *outName = uni.fVariable.c_str();
141 } 187 }
142 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUnifor ms.count() - 1); 188 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUnifor ms.count() - 1);
143 } 189 }
144 190
145 void GrGLProgramBuilder::appendDecls(const VarArray& vars, SkString* out) const {
146 for (int i = 0; i < vars.count(); ++i) {
147 vars[i].appendDecl(this->ctxInfo(), out);
148 out->append(";\n");
149 }
150 }
151
152 void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility, 191 void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
153 SkString* out) const { 192 SkString* out) const {
154 for (int i = 0; i < fUniforms.count(); ++i) { 193 for (int i = 0; i < fUniforms.count(); ++i) {
155 if (fUniforms[i].fVisibility & visibility) { 194 if (fUniforms[i].fVisibility & visibility) {
156 fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out); 195 fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
157 out->append(";\n"); 196 out->append(";\n");
158 } 197 }
159 } 198 }
160 } 199 }
161 200
162 void GrGLProgramBuilder::createAndEmitEffects(const GrFragmentStage* effectStage s[], 201 const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
163 int effectCnt, 202 return fGpu->ctxInfo();
164 const GrGLProgramDesc::EffectKeyPr ovider& keyProvider, 203 }
165 GrGLSLExpr4* fsInOutColor) { 204
205 void GrGLProgramBuilder::setupUniformColorIfNeeded(const GrGLProgramDesc::ColorI nput& colorInput,
206 const char* name,
207 GrGLSLExpr4* input) {
208 if (GrGLProgramDesc::kUniform_ColorInput == colorInput) {
209 const char* uniformName;
210 this->fUniformHandles.fColorUni =
211 this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
212 kVec4f_GrSLType,
213 name,
214 &uniformName);
215 *input = GrGLSLExpr4(uniformName);
216 } else if (GrGLProgramDesc::kAllOnes_ColorInput == colorInput) {
217 *input = GrGLSLExpr4(1);
218 }
219 }
220
221 void GrGLProgramBuilder::transformGLToSkiaCoords() {
222 const char* viewMName;
223 fUniformHandles.fViewMatrixUni = this->addUniform(GrGLProgramBuilder::kVerte x_Visibility,
224 kMat33f_GrSLType,
225 "ViewM",
226 &viewMName);
227
228 // Transform the position into Skia's device coords.
229 fVS.codeAppendf("vec3 pos3 = %s * vec3(%s, 1);", viewMName, fVS.positionAttr ibute().c_str());
230 }
231
232 void GrGLProgramBuilder::createAndEmitProcessors(const GrGeometryStage* geometry Processor,
233 const GrFragmentStage* colorSta ges[],
234 const GrFragmentStage* coverage Stages[],
235 GrGLSLExpr4* inputColor,
236 GrGLSLExpr4* inputCoverage) {
237 bool useLocalCoords = fVS.hasExplicitLocalCoords();
238
239 EffectKeyProvider colorKeyProvider(&fDesc, EffectKeyProvider::kColor_EffectT ype);
240 int numColorEffects = fDesc.numColorEffects();
241 GrGLInstalledProcessors* ip = SkNEW_ARGS(GrGLInstalledProcessors, (numColorE ffects,
242 useLocalC oords));
243 this->createAndEmitProcessors<GrFragmentStage>(colorStages, numColorEffects, colorKeyProvider,
244 inputColor, ip);
245 fColorEffects.reset(ip);
246
247 if (geometryProcessor) {
248 fVS.emitAttributes(*geometryProcessor->getProcessor());
249 EffectKeyProvider gpKeyProvider(&fDesc, EffectKeyProvider::kGeometryProc essor_EffectType);
250 ip = SkNEW_ARGS(GrGLInstalledProcessors, (1, useLocalCoords));
251 this->createAndEmitProcessors<GrGeometryStage>(&geometryProcessor, 1, gp KeyProvider,
252 inputCoverage, ip);
253 fGeometryProcessor.reset(ip);
254 }
255
256 EffectKeyProvider coverageKeyProvider(&fDesc, EffectKeyProvider::kCoverage_E ffectType);
257 int numCoverageEffects = fDesc.numCoverageEffects();
258 ip = SkNEW_ARGS(GrGLInstalledProcessors, (numCoverageEffects, useLocalCoords ));
259 this->createAndEmitProcessors<GrFragmentStage>(coverageStages, numCoverageEf fects,
260 coverageKeyProvider, inputCov erage, ip);
261 fCoverageEffects.reset(ip);
262 }
263
264 template <class ProcessorStage>
265 void GrGLProgramBuilder::createAndEmitProcessors(const ProcessorStage* processSt ages[],
266 int effectCnt,
267 const EffectKeyProvider& keyPro vider,
268 GrGLSLExpr4* fsInOutColor,
269 GrGLInstalledProcessors* instal ledProcessors) {
166 bool effectEmitted = false; 270 bool effectEmitted = false;
167 271
168 GrGLSLExpr4 inColor = *fsInOutColor; 272 GrGLSLExpr4 inColor = *fsInOutColor;
169 GrGLSLExpr4 outColor; 273 GrGLSLExpr4 outColor;
170 274
171 for (int e = 0; e < effectCnt; ++e) { 275 for (int e = 0; e < effectCnt; ++e) {
172 fGrProcessorEmitter.set(effectStages[e]->getFragmentProcessor()); 276 // Program builders have a bit of state we need to clear with each effec t
173 fEffectEmitter = &fGrProcessorEmitter; 277 this->reset();
174 // calls into the subclass to emit the actual effect into the program ef fect object 278 const ProcessorStage& stage = *processStages[e];
175 this->emitEffect(*effectStages[e], e, keyProvider, &inColor, &outColor); 279 SkASSERT(stage.getProcessor());
280
281 if (inColor.isZeros()) {
282 SkString inColorName;
283
284 // Effects have no way to communicate zeros, they treat an empty str ing as ones.
285 this->nameVariable(&inColorName, '\0', "input");
286 fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str( ));
287 inColor = inColorName;
288 }
289
290 // create var to hold stage result
291 SkString outColorName;
292 this->nameVariable(&outColorName, '\0', "output");
293 fFS.codeAppendf("vec4 %s;", outColorName.c_str());
294 outColor = outColorName;
295
296 SkASSERT(installedProcessors);
297 const typename ProcessorStage::Processor& processor = *stage.getProcesso r();
298 SkSTArray<2, GrGLProcessor::TransformedCoords> coords(processor.numTrans forms());
299 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(processor.numTextur es());
300
301 this->emitTransforms(stage, &coords, installedProcessors);
302 this->emitSamplers(processor, &samplers, installedProcessors);
303
304 typename ProcessorStage::GLProcessor* glEffect =
305 processor.getFactory().createGLInstance(processor);
306 installedProcessors->addEffect(glEffect);
307
308 // Enclose custom code in a block to avoid namespace conflicts
309 SkString openBrace;
310 openBrace.printf("{ // Stage %d: %s\n", fStageIndex, glEffect->name());
311 fFS.codeAppend(openBrace.c_str());
312
313 glEffect->emitCode(this, processor, keyProvider.get(e), outColor.c_str() , inColor.c_str(),
314 coords, samplers);
315
316 // We have to check that effects and the code they emit are consistent, ie if an effect
317 // asks for dst color, then the emit code needs to follow suit
318 verify(processor);
319 fFS.codeAppend("}");
320
321 inColor = outColor;
176 effectEmitted = true; 322 effectEmitted = true;
177 } 323 }
178 324
179 if (effectEmitted) { 325 if (effectEmitted) {
180 *fsInOutColor = outColor; 326 *fsInOutColor = outColor;
181 } 327 }
182 } 328 }
183 329
184 void GrGLProgramBuilder::emitEffect(const GrProcessorStage& effectStage, 330 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
185 int effectIndex, 331 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
186 const GrGLProgramDesc::EffectKeyProvider& ke yProvider,
187 GrGLSLExpr4* inColor,
188 GrGLSLExpr4* outColor) {
189 SkASSERT(effectStage.getProcessor());
190 CodeStage::AutoStageRestore csar(&fCodeStage, &effectStage);
191
192 if (inColor->isZeros()) {
193 SkString inColorName;
194
195 // Effects have no way to communicate zeros, they treat an empty string as ones.
196 this->nameVariable(&inColorName, '\0', "input");
197 fFS.codeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor->c_str ());
198 *inColor = inColorName;
199 }
200
201 // create var to hold stage result
202 SkString outColorName;
203 this->nameVariable(&outColorName, '\0', "output");
204 fFS.codeAppendf("\tvec4 %s;\n", outColorName.c_str());
205 *outColor = outColorName;
206
207 this->emitEffect(effectStage, keyProvider.get(effectIndex), outColor->c_str( ),
208 inColor->isOnes() ? NULL : inColor->c_str(), fCodeStage.sta geIndex());
209
210 *inColor = *outColor;
211 } 332 }
212 333
213 void GrGLProgramBuilder::emitSamplers(const GrProcessor& effect, 334 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
214 GrGLProcessor::TextureSamplerArray* outSam plers) { 335 SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition());
215 SkTArray<GrGLProgramEffects::Sampler, true>& samplers = 336 SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
216 this->getProgramEffects()->addSamplers(); 337 }
217 int numTextures = effect.numTextures(); 338
339 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
340 GrGLProcessor::TextureSamplerArray* outSam plers,
341 GrGLInstalledProcessors* installedProcesso rs) {
342 SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = installedProces sors->addSamplers();
343 int numTextures = processor.numTextures();
218 samplers.push_back_n(numTextures); 344 samplers.push_back_n(numTextures);
219 SkString name; 345 SkString name;
220 for (int t = 0; t < numTextures; ++t) { 346 for (int t = 0; t < numTextures; ++t) {
221 name.printf("Sampler%d", t); 347 name.printf("Sampler%d", t);
222 samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Vi sibility, 348 samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Vi sibility,
223 kSampler2D_GrSLType, 349 kSampler2D_GrSLType,
224 name.c_str()); 350 name.c_str());
225 SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler, 351 SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
226 (samplers[t].fUniform, effect.textureAccess(t))); 352 (samplers[t].fUniform, processor.textureAccess(t) ));
227 } 353 }
228 } 354 }
229 355
230 bool GrGLProgramBuilder::finish() { 356 void GrGLProgramBuilder::transformSkiaToGLCoords() {
231 SkASSERT(0 == fProgramID); 357 const char* rtAdjustName;
232 GL_CALL_RET(fProgramID, CreateProgram()); 358 fUniformHandles.fRTAdjustmentUni = this->addUniform(GrGLProgramBuilder::kVer tex_Visibility,
233 if (!fProgramID) { 359 kVec4f_GrSLType,
234 return false; 360 "rtAdjustment",
361 &rtAdjustName);
362
363 // Transform from Skia's device coords to GL's normalized device coords.
364 fVS.codeAppendf("gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw) , 0, pos3.z);",
365 rtAdjustName, rtAdjustName);
366 }
367
368 void GrGLProgramBuilder::enableSecondaryOutput(const GrGLSLExpr4& inputColor,
369 const GrGLSLExpr4& inputCoverage) {
370 fFS.enableSecondaryOutput();
371 const char* secondaryOutputName = fFS.getSecondaryColorOutputName();
372 GrGLSLExpr4 coeff(1);
373 switch (this->header().fSecondaryOutputType) {
374 case GrOptDrawState::kCoverage_SecondaryOutputType:
375 break;
376 case GrOptDrawState::kCoverageISA_SecondaryOutputType:
377 // Get (1-A) into coeff
378 coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
379 break;
380 case GrOptDrawState::kCoverageISC_SecondaryOutputType:
381 // Get (1-RGBA) into coeff
382 coeff = GrGLSLExpr4(1) - inputColor;
383 break;
384 default:
385 SkFAIL("Unexpected Secondary Output");
386 }
387 // Get coeff * coverage into modulate and then write that to the dual source output.
388 fFS.codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage) .c_str());
389 }
390
391 void GrGLProgramBuilder::combineColorAndCoverage(const GrGLSLExpr4& inputColor,
392 const GrGLSLExpr4& inputCoverag e) {
393 GrGLSLExpr4 fragColor = inputColor * inputCoverage;
394 switch (this->header().fPrimaryOutputType) {
395 case GrOptDrawState::kModulate_PrimaryOutputType:
396 break;
397 case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
398 {
399 // Tack on "+(1-coverage)dst onto the frag color.
400 GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
401 GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(fFS.dstColo r());
402 fragColor = fragColor + dstContribution;
403 }
404 break;
405 default:
406 SkFAIL("Unknown Primary Output");
407 }
408 fFS.codeAppendf("\t%s = %s;\n", fFS.getPrimaryColorOutputName(), fragColor.c _str());
409 }
410
411
412 GrGLProgram* GrGLProgramBuilder::compileBindLinkCreate() {
413 // verify we can get a program id
414 GrGLuint programID;
415 GL_CALL_RET(programID, CreateProgram());
416 if (0 == programID) {
417 return NULL;
235 } 418 }
236 419
420 // compile shaders and bind attributes / uniforms
237 SkTDArray<GrGLuint> shadersToDelete; 421 SkTDArray<GrGLuint> shadersToDelete;
238 422 if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) {
239 if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) { 423 this->cleanupProgram(programID, shadersToDelete);
240 GL_CALL(DeleteProgram(fProgramID)); 424 return NULL;
241 return false;
242 } 425 }
243 426 if (!this->header().fUseFragShaderOnly) {
244 this->bindProgramLocations(fProgramID); 427 if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) {
245 428 this->cleanupProgram(programID, shadersToDelete);
246 GL_CALL(LinkProgram(fProgramID)); 429 return NULL;
430 }
431 fVS.bindVertexAttributes(programID);
432 }
433 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
434 if (usingBindUniform) {
435 this->bindUniformLocations(programID);
436 }
437 fFS.bindFragmentShaderLocations(programID);
438 GL_CALL(LinkProgram(programID));
247 439
248 // Calling GetProgramiv is expensive in Chromium. Assume success in release builds. 440 // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
249 bool checkLinked = !fGpu->ctxInfo().isChromium(); 441 bool checkLinked = !fGpu->ctxInfo().isChromium();
250 #ifdef SK_DEBUG 442 #ifdef SK_DEBUG
251 checkLinked = true; 443 checkLinked = true;
252 #endif 444 #endif
253 if (checkLinked) { 445 if (checkLinked) {
254 GrGLint linked = GR_GL_INIT_ZERO; 446 checkLinkStatus(programID);
255 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); 447 }
256 if (!linked) { 448 if (!usingBindUniform) {
257 GrGLint infoLen = GR_GL_INIT_ZERO; 449 this->resolveUniformLocations(programID);
258 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
259 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debug ger
260 if (infoLen > 0) {
261 // retrieve length even though we don't need it to workaround
262 // bug in chrome cmd buffer param validation.
263 GrGLsizei length = GR_GL_INIT_ZERO;
264 GL_CALL(GetProgramInfoLog(fProgramID,
265 infoLen+1,
266 &length,
267 (char*)log.get()));
268 GrPrintf((char*)log.get());
269 }
270 SkDEBUGFAIL("Error linking program");
271 GL_CALL(DeleteProgram(fProgramID));
272 fProgramID = 0;
273 return false;
274 }
275 } 450 }
276 451
277 this->resolveProgramLocations(fProgramID); 452 // Finally, this is just for nvpr es, which has separable varyings that are plugged in after
453 // building
454 this->resolveSeparableVaryings(programID);
278 455
279 for (int i = 0; i < shadersToDelete.count(); ++i) { 456 this->cleanupShaders(shadersToDelete);
280 GL_CALL(DeleteShader(shadersToDelete[i]));
281 }
282 457
283 return true; 458 return this->createProgram(programID);
284 } 459 }
285 460
286 bool GrGLProgramBuilder::compileAndAttachShaders(GrGLuint programId, 461 void GrGLProgramBuilder::bindUniformLocations(GrGLuint programID) {
287 SkTDArray<GrGLuint>* shaderIds) const { 462 int count = fUniforms.count();
288 return fFS.compileAndAttachShaders(programId, shaderIds); 463 for (int i = 0; i < count; ++i) {
289 } 464 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str() ));
290 465 fUniforms[i].fLocation = i;
291 void GrGLProgramBuilder::bindProgramLocations(GrGLuint programId) {
292 fFS.bindProgramLocations(programId);
293
294 // skbug.com/2056
295 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
296 if (usingBindUniform) {
297 int count = fUniforms.count();
298 for (int i = 0; i < count; ++i) {
299 GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_s tr()));
300 fUniforms[i].fLocation = i;
301 }
302 } 466 }
303 } 467 }
304 468
305 void GrGLProgramBuilder::resolveProgramLocations(GrGLuint programId) { 469 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
306 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL; 470 GrGLint linked = GR_GL_INIT_ZERO;
307 if (!usingBindUniform) { 471 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
308 int count = fUniforms.count(); 472 if (!linked) {
309 for (int i = 0; i < count; ++i) { 473 GrGLint infoLen = GR_GL_INIT_ZERO;
310 GrGLint location; 474 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
311 GL_CALL_RET(location, 475 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
312 GetUniformLocation(programId, fUniforms[i].fVariable.c_s tr())); 476 if (infoLen > 0) {
313 fUniforms[i].fLocation = location; 477 // retrieve length even though we don't need it to workaround
478 // bug in chrome cmd buffer param validation.
479 GrGLsizei length = GR_GL_INIT_ZERO;
480 GL_CALL(GetProgramInfoLog(programID,
481 infoLen+1,
482 &length,
483 (char*)log.get()));
484 GrPrintf((char*)log.get());
314 } 485 }
486 SkDEBUGFAIL("Error linking program");
487 GL_CALL(DeleteProgram(programID));
488 programID = 0;
315 } 489 }
490 return SkToBool(linked);
491 }
316 492
317 int count = fSeparableVaryingInfos.count(); 493 void GrGLProgramBuilder::resolveUniformLocations(GrGLuint programID) {
494 int count = fUniforms.count();
318 for (int i = 0; i < count; ++i) { 495 for (int i = 0; i < count; ++i) {
319 GrGLint location; 496 GrGLint location;
320 GL_CALL_RET(location, 497 GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariab le.c_str()));
321 GetProgramResourceLocation(programId, 498 fUniforms[i].fLocation = location;
322 GR_GL_FRAGMENT_INPUT,
323 fSeparableVaryingInfos[i].fVariab le.c_str()));
324 fSeparableVaryingInfos[i].fLocation = location;
325 } 499 }
326 } 500 }
327 501
328 const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const { 502 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGL uint>& shaderIDs) {
329 return fGpu->ctxInfo(); 503 GL_CALL(DeleteProgram(programID));
504 cleanupShaders(shaderIDs);
330 } 505 }
506 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
507 for (int i = 0; i < shaderIDs.count(); ++i) {
508 GL_CALL(DeleteShader(shaderIDs[i]));
509 }
510 }
511
512 ////////////////////////////////////////////////////////////////////////////////
513
514 GrGLInstalledProcessors::~GrGLInstalledProcessors() {
515 int numEffects = fGLProcessors.count();
516 for (int e = 0; e < numEffects; ++e) {
517 SkDELETE(fGLProcessors[e]);
518 }
519 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698