Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLShaderBuilder.cpp
1 /*
2  * Copyright 2012 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 "gl/GrGLShaderBuilder.h"
9 #include "gl/GrGLProgram.h"
10 #include "gl/GrGLUniformHandle.h"
11 #include "GrCoordTransform.h"
12 #include "GrDrawEffect.h"
13 #include "GrGpuGL.h"
14 #include "GrTexture.h"
15 #include "SkRTConf.h"
16 #include "SkTraceEvent.h"
17
18 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
19 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
20
21 // number of each input/output type in a single allocation block
22 static const int kVarsPerBlock = 8;
23
24 // except FS outputs where we expect 2 at most.
25 static const int kMaxFSOutputs = 2;
26
27 // ES2 FS only guarantees mediump and lowp support
28 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
29
30 typedef GrGLUniformManager::UniformHandle UniformHandle;
31
32 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
33                 "Print the source code for all shaders generated.");
34
35 ///////////////////////////////////////////////////////////////////////////////
36
37 namespace {
38
39 inline const char* color_attribute_name() { return "aColor"; }
40 inline const char* coverage_attribute_name() { return "aCoverage"; }
41 inline const char* declared_color_output_name() { return "fsColorOut"; }
42 inline const char* dual_source_output_name() { return "dualSourceOut"; }
43 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
44     if (kVec2f_GrSLType == type) {
45         return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
46     } else {
47         SkASSERT(kVec3f_GrSLType == type);
48         return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
49     }
50 }
51
52 void append_texture_lookup(SkString* out,
53                            GrGpuGL* gpu,
54                            const char* samplerName,
55                            const char* coordName,
56                            uint32_t configComponentMask,
57                            const char* swizzle,
58                            GrSLType varyingType = kVec2f_GrSLType) {
59     SkASSERT(NULL != coordName);
60
61     out->appendf("%s(%s, %s)",
62                  sample_function_name(varyingType, gpu->glslGeneration()),
63                  samplerName,
64                  coordName);
65
66     char mangledSwizzle[5];
67
68     // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
69     // is available.
70     if (!gpu->glCaps().textureSwizzleSupport() &&
71         (kA_GrColorComponentFlag == configComponentMask)) {
72         char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
73         int i;
74         for (i = 0; '\0' != swizzle[i]; ++i) {
75             mangledSwizzle[i] = alphaChar;
76         }
77         mangledSwizzle[i] ='\0';
78         swizzle = mangledSwizzle;
79     }
80     // For shader prettiness we omit the swizzle rather than appending ".rgba".
81     if (memcmp(swizzle, "rgba", 4)) {
82         out->appendf(".%s", swizzle);
83     }
84 }
85
86 }
87
88 static const char kDstCopyColorName[] = "_dstColor";
89
90 ///////////////////////////////////////////////////////////////////////////////
91
92 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu,
93                                      GrGLUniformManager& uniformManager,
94                                      const GrGLProgramDesc& desc)
95     : fGpu(gpu)
96     , fUniformManager(uniformManager)
97     , fFSFeaturesAddedMask(0)
98     , fFSInputs(kVarsPerBlock)
99     , fFSOutputs(kMaxFSOutputs)
100     , fUniforms(kVarsPerBlock)
101     , fSetupFragPosition(false)
102     , fHasCustomColorOutput(false)
103     , fHasSecondaryOutput(false)
104     , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) {
105
106     const GrGLProgramDesc::KeyHeader& header = desc.getHeader();
107
108     // Emit code to read the dst copy textue if necessary.
109     if (kNoDstRead_DstReadKey != header.fDstReadKey &&
110         GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) {
111         bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
112         const char* dstCopyTopLeftName;
113         const char* dstCopyCoordScaleName;
114         uint32_t configMask;
115         if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) {
116             configMask = kA_GrColorComponentFlag;
117         } else {
118             configMask = kRGBA_GrColorComponentFlags;
119         }
120         fDstCopySamplerUniform = this->addUniform(kFragment_Visibility,
121                                                   kSampler2D_GrSLType,
122                                                   "DstCopySampler");
123         fDstCopyTopLeftUniform = this->addUniform(kFragment_Visibility,
124                                                   kVec2f_GrSLType,
125                                                   "DstCopyUpperLeft",
126                                                   &dstCopyTopLeftName);
127         fDstCopyScaleUniform     = this->addUniform(kFragment_Visibility,
128                                                     kVec2f_GrSLType,
129                                                     "DstCopyCoordScale",
130                                                     &dstCopyCoordScaleName);
131         const char* fragPos = this->fragmentPosition();
132         this->fsCodeAppend("\t// Read color from copy of the destination.\n");
133         this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n",
134                             fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
135         if (!topDown) {
136             this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n");
137         }
138         this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName);
139         append_texture_lookup(&fFSCode,
140                               fGpu,
141                               this->getUniformCStr(fDstCopySamplerUniform),
142                               "_dstTexCoord",
143                               configMask,
144                               "rgba");
145         this->fsCodeAppend(";\n\n");
146     }
147
148     if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
149         const char* name;
150         fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
151                                          kVec4f_GrSLType, "Color", &name);
152         fInputColor = GrGLSLExpr4(name);
153     } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) {
154         fInputColor = GrGLSLExpr4(1);
155     } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) {
156         fInputColor = GrGLSLExpr4(0);
157     }
158
159     if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
160         const char* name;
161         fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility,
162                                             kVec4f_GrSLType, "Coverage", &name);
163         fInputCoverage = GrGLSLExpr4(name);
164     } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) {
165         fInputCoverage = GrGLSLExpr4(1);
166     } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fCoverageInput) {
167         fInputCoverage = GrGLSLExpr4(0);
168     }
169
170     if (k110_GrGLSLGeneration != fGpu->glslGeneration()) {
171         fFSOutputs.push_back().set(kVec4f_GrSLType,
172                                    GrGLShaderVar::kOut_TypeModifier,
173                                    declared_color_output_name());
174         fHasCustomColorOutput = true;
175     }
176 }
177
178 bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
179     switch (feature) {
180         case kStandardDerivatives_GLSLFeature:
181             if (!fGpu->glCaps().shaderDerivativeSupport()) {
182                 return false;
183             }
184             if (kGLES_GrGLStandard == fGpu->glStandard()) {
185                 this->addFSFeature(1 << kStandardDerivatives_GLSLFeature,
186                                    "GL_OES_standard_derivatives");
187             }
188             return true;
189         default:
190             SkFAIL("Unexpected GLSLFeature requested.");
191             return false;
192     }
193 }
194
195 bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) {
196     switch (feature) {
197         case kFragCoordConventions_GLSLPrivateFeature:
198             if (!fGpu->glCaps().fragCoordConventionsSupport()) {
199                 return false;
200             }
201             if (fGpu->glslGeneration() < k150_GrGLSLGeneration) {
202                 this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
203                                    "GL_ARB_fragment_coord_conventions");
204             }
205             return true;
206         case kEXTShaderFramebufferFetch_GLSLPrivateFeature:
207             if (GrGLCaps::kEXT_FBFetchType != fGpu->glCaps().fbFetchType()) {
208                 return false;
209             }
210             this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeature,
211                                "GL_EXT_shader_framebuffer_fetch");
212             return true;
213         case kNVShaderFramebufferFetch_GLSLPrivateFeature:
214             if (GrGLCaps::kNV_FBFetchType != fGpu->glCaps().fbFetchType()) {
215                 return false;
216             }
217             this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature,
218                                "GL_NV_shader_framebuffer_fetch");
219             return true;
220         default:
221             SkFAIL("Unexpected GLSLPrivateFeature requested.");
222             return false;
223     }
224 }
225
226 void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionName) {
227     if (!(featureBit & fFSFeaturesAddedMask)) {
228         fFSExtensions.appendf("#extension %s: require\n", extensionName);
229         fFSFeaturesAddedMask |= featureBit;
230     }
231 }
232
233 void GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* name) {
234     if ('\0' == prefix) {
235         *out = name;
236     } else {
237         out->printf("%c%s", prefix, name);
238     }
239     if (fCodeStage.inStageCode()) {
240         if (out->endsWith('_')) {
241             // Names containing "__" are reserved.
242             out->append("x");
243         }
244         out->appendf("_Stage%d", fCodeStage.stageIndex());
245     }
246 }
247
248 const char* GrGLShaderBuilder::dstColor() {
249     if (fCodeStage.inStageCode()) {
250         const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
251         if (!effect->willReadDstColor()) {
252             SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEffect "
253                          "did not request access.");
254             return "";
255         }
256     }
257     static const char kFBFetchColorName[] = "gl_LastFragData[0]";
258     GrGLCaps::FBFetchType fetchType = fGpu->glCaps().fbFetchType();
259     if (GrGLCaps::kEXT_FBFetchType == fetchType) {
260         SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLSLPrivateFeature));
261         return kFBFetchColorName;
262     } else if (GrGLCaps::kNV_FBFetchType == fetchType) {
263         SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSLPrivateFeature));
264         return kFBFetchColorName;
265     } else if (fDstCopySamplerUniform.isValid()) {
266         return kDstCopyColorName;
267     } else {
268         return "";
269     }
270 }
271
272 void GrGLShaderBuilder::appendTextureLookup(SkString* out,
273                                             const GrGLShaderBuilder::TextureSampler& sampler,
274                                             const char* coordName,
275                                             GrSLType varyingType) const {
276     append_texture_lookup(out,
277                           fGpu,
278                           this->getUniformCStr(sampler.samplerUniform()),
279                           coordName,
280                           sampler.configComponentMask(),
281                           sampler.swizzle(),
282                           varyingType);
283 }
284
285 void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSampler& sampler,
286                                               const char* coordName,
287                                               GrSLType varyingType) {
288     this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType);
289 }
290
291 void GrGLShaderBuilder::fsAppendTextureLookupAndModulate(
292                                             const char* modulation,
293                                             const GrGLShaderBuilder::TextureSampler& sampler,
294                                             const char* coordName,
295                                             GrSLType varyingType) {
296     SkString lookup;
297     this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
298     fFSCode.append((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
299 }
300
301 GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
302                                                                const GrGLCaps& caps) {
303     uint32_t key = kYesDstRead_DstReadKeyBit;
304     if (GrGLCaps::kNone_FBFetchType != caps.fbFetchType()) {
305         return key;
306     }
307     SkASSERT(NULL != dstCopy);
308     if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) {
309         // The fact that the config is alpha-only must be considered when generating code.
310         key |= kUseAlphaConfig_DstReadKeyBit;
311     }
312     if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) {
313         key |= kTopLeftOrigin_DstReadKeyBit;
314     }
315     SkASSERT(static_cast<DstReadKey>(key) == key);
316     return static_cast<DstReadKey>(key);
317 }
318
319 GrGLShaderBuilder::FragPosKey GrGLShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst,
320                                                                         const GrGLCaps&) {
321     if (kTopLeft_GrSurfaceOrigin == dst->origin()) {
322         return kTopLeftFragPosRead_FragPosKey;
323     } else {
324         return kBottomLeftFragPosRead_FragPosKey;
325     }
326 }
327
328
329 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
330     if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
331         if (caps.textureRedSupport()) {
332             static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
333             return gRedSmear;
334         } else {
335             static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
336                                                     GR_GL_ALPHA, GR_GL_ALPHA };
337             return gAlphaSmear;
338         }
339     } else {
340         static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
341         return gStraight;
342     }
343 }
344
345 GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t visibility,
346                                                                      GrSLType type,
347                                                                      const char* name,
348                                                                      int count,
349                                                                      const char** outName) {
350     SkASSERT(name && strlen(name));
351     SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
352     SkASSERT(0 == (~kVisibilityMask & visibility));
353     SkASSERT(0 != visibility);
354
355     BuilderUniform& uni = fUniforms.push_back();
356     UniformHandle h = GrGLUniformManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
357     SkDEBUGCODE(UniformHandle h2 =)
358     fUniformManager.appendUniform(type, count);
359     // We expect the uniform manager to initially have no uniforms and that all uniforms are added
360     // by this function. Therefore, the handles should match.
361     SkASSERT(h2 == h);
362     uni.fVariable.setType(type);
363     uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
364     this->nameVariable(uni.fVariable.accessName(), 'u', name);
365     uni.fVariable.setArrayCount(count);
366     uni.fVisibility = visibility;
367
368     // If it is visible in both the VS and FS, the precision must match.
369     // We declare a default FS precision, but not a default VS. So set the var
370     // to use the default FS precision.
371     if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
372         // the fragment and vertex precisions must match
373         uni.fVariable.setPrecision(kDefaultFragmentPrecision);
374     }
375
376     if (NULL != outName) {
377         *outName = uni.fVariable.c_str();
378     }
379
380     return h;
381 }
382
383 SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coords, int index) {
384     if (kVec3f_GrSLType != coords[index].type()) {
385         SkASSERT(kVec2f_GrSLType == coords[index].type());
386         return coords[index].getName();
387     }
388
389     SkString coords2D("coords2D");
390     if (0 != index) {
391         coords2D.appendf("_%i", index);
392     }
393     this->fsCodeAppendf("\tvec2 %s = %s.xy / %s.z;",
394                         coords2D.c_str(), coords[index].c_str(), coords[index].c_str());
395     return coords2D;
396 }
397
398 const char* GrGLShaderBuilder::fragmentPosition() {
399     if (fCodeStage.inStageCode()) {
400         const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect();
401         if (!effect->willReadFragmentPosition()) {
402             SkDEBUGFAIL("GrGLEffect asked for frag position but its generating GrEffect "
403                          "did not request access.");
404             return "";
405         }
406     }
407     // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers
408     // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the
409     // declaration varies in earlier GLSL specs. So it is simpler to omit it.
410     if (fTopLeftFragPosRead) {
411         fSetupFragPosition = true;
412         return "gl_FragCoord";
413     } else if (fGpu->glCaps().fragCoordConventionsSupport()) {
414         if (!fSetupFragPosition) {
415             SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
416             fFSInputs.push_back().set(kVec4f_GrSLType,
417                                       GrGLShaderVar::kIn_TypeModifier,
418                                       "gl_FragCoord",
419                                       GrGLShaderVar::kDefault_Precision,
420                                       GrGLShaderVar::kUpperLeft_Origin);
421             fSetupFragPosition = true;
422         }
423         return "gl_FragCoord";
424     } else {
425         static const char* kCoordName = "fragCoordYDown";
426         if (!fSetupFragPosition) {
427             // temporarily change the stage index because we're inserting non-stage code.
428             CodeStage::AutoStageRestore csar(&fCodeStage, NULL);
429
430             SkASSERT(!fRTHeightUniform.isValid());
431             const char* rtHeightName;
432
433             fRTHeightUniform = this->addUniform(kFragment_Visibility,
434                                                 kFloat_GrSLType,
435                                                 "RTHeight",
436                                                 &rtHeightName);
437
438             this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n",
439                                    kCoordName, rtHeightName);
440             fSetupFragPosition = true;
441         }
442         SkASSERT(fRTHeightUniform.isValid());
443         return kCoordName;
444     }
445 }
446
447 void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType,
448                                        const char* name,
449                                        int argCnt,
450                                        const GrGLShaderVar* args,
451                                        const char* body,
452                                        SkString* outName) {
453     fFSFunctions.append(GrGLSLTypeString(returnType));
454     this->nameVariable(outName, '\0', name);
455     fFSFunctions.appendf(" %s", outName->c_str());
456     fFSFunctions.append("(");
457     for (int i = 0; i < argCnt; ++i) {
458         args[i].appendDecl(this->ctxInfo(), &fFSFunctions);
459         if (i < argCnt - 1) {
460             fFSFunctions.append(", ");
461         }
462     }
463     fFSFunctions.append(") {\n");
464     fFSFunctions.append(body);
465     fFSFunctions.append("}\n\n");
466 }
467
468 namespace {
469
470 inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
471                                                GrGLStandard standard,
472                                                SkString* str) {
473     // Desktop GLSL has added precision qualifiers but they don't do anything.
474     if (kGLES_GrGLStandard == standard) {
475         switch (p) {
476             case GrGLShaderVar::kHigh_Precision:
477                 str->append("precision highp float;\n");
478                 break;
479             case GrGLShaderVar::kMedium_Precision:
480                 str->append("precision mediump float;\n");
481                 break;
482             case GrGLShaderVar::kLow_Precision:
483                 str->append("precision lowp float;\n");
484                 break;
485             case GrGLShaderVar::kDefault_Precision:
486                 SkFAIL("Default precision now allowed.");
487             default:
488                 SkFAIL("Unknown precision value.");
489         }
490     }
491 }
492 }
493
494 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const {
495     for (int i = 0; i < vars.count(); ++i) {
496         vars[i].appendDecl(this->ctxInfo(), out);
497         out->append(";\n");
498     }
499 }
500
501 void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility,
502                                            SkString* out) const {
503     for (int i = 0; i < fUniforms.count(); ++i) {
504         if (fUniforms[i].fVisibility & visibility) {
505             fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
506             out->append(";\n");
507         }
508     }
509 }
510
511 void GrGLShaderBuilder::createAndEmitEffects(GrGLProgramEffectsBuilder* programEffectsBuilder,
512                                              const GrEffectStage* effectStages[],
513                                              const EffectKey effectKeys[],
514                                              int effectCnt,
515                                              GrGLSLExpr4* fsInOutColor) {
516     bool effectEmitted = false;
517
518     GrGLSLExpr4 inColor = *fsInOutColor;
519     GrGLSLExpr4 outColor;
520
521     for (int e = 0; e < effectCnt; ++e) {
522         SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect());
523         const GrEffectStage& stage = *effectStages[e];
524
525         CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
526
527         if (inColor.isZeros()) {
528             SkString inColorName;
529
530             // Effects have no way to communicate zeros, they treat an empty string as ones.
531             this->nameVariable(&inColorName, '\0', "input");
532             this->fsCodeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor.c_str());
533             inColor = inColorName;
534         }
535
536         // create var to hold stage result
537         SkString outColorName;
538         this->nameVariable(&outColorName, '\0', "output");
539         this->fsCodeAppendf("\tvec4 %s;\n", outColorName.c_str());
540         outColor = outColorName;
541
542
543         programEffectsBuilder->emitEffect(stage,
544                                           effectKeys[e],
545                                           outColor.c_str(),
546                                           inColor.isOnes() ? NULL : inColor.c_str(),
547                                           fCodeStage.stageIndex());
548
549         inColor = outColor;
550         effectEmitted = true;
551     }
552
553     if (effectEmitted) {
554         *fsInOutColor = outColor;
555     }
556 }
557
558 const char* GrGLShaderBuilder::getColorOutputName() const {
559     return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
560 }
561
562 const char* GrGLShaderBuilder::enableSecondaryOutput() {
563     if (!fHasSecondaryOutput) {
564         fFSOutputs.push_back().set(kVec4f_GrSLType,
565                                    GrGLShaderVar::kOut_TypeModifier,
566                                    dual_source_output_name());
567         fHasSecondaryOutput = true;
568     }
569     return dual_source_output_name();
570 }
571
572 bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) {
573     GrGLuint programId = 0;
574     GL_CALL_RET(programId, CreateProgram());
575     if (!programId) {
576         return false;
577     }
578
579     SkTDArray<GrGLuint> shadersToDelete;
580
581     if (!this->compileAndAttachShaders(programId, &shadersToDelete)) {
582         GL_CALL(DeleteProgram(programId));
583         return false;
584     }
585
586     this->bindProgramLocations(programId);
587     if (fUniformManager.isUsingBindUniform()) {
588       fUniformManager.getUniformLocations(programId, fUniforms);
589     }
590
591     GL_CALL(LinkProgram(programId));
592
593     // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
594     bool checkLinked = !fGpu->ctxInfo().isChromium();
595 #ifdef SK_DEBUG
596     checkLinked = true;
597 #endif
598     if (checkLinked) {
599         GrGLint linked = GR_GL_INIT_ZERO;
600         GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked));
601         if (!linked) {
602             GrGLint infoLen = GR_GL_INIT_ZERO;
603             GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen));
604             SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
605             if (infoLen > 0) {
606                 // retrieve length even though we don't need it to workaround
607                 // bug in chrome cmd buffer param validation.
608                 GrGLsizei length = GR_GL_INIT_ZERO;
609                 GL_CALL(GetProgramInfoLog(programId,
610                                           infoLen+1,
611                                           &length,
612                                           (char*)log.get()));
613                 GrPrintf((char*)log.get());
614             }
615             SkDEBUGFAIL("Error linking program");
616             GL_CALL(DeleteProgram(programId));
617             return false;
618         }
619     }
620
621     if (!fUniformManager.isUsingBindUniform()) {
622       fUniformManager.getUniformLocations(programId, fUniforms);
623     }
624
625     for (int i = 0; i < shadersToDelete.count(); ++i) {
626       GL_CALL(DeleteShader(shadersToDelete[i]));
627     }
628
629     *outProgramId = programId;
630     return true;
631 }
632
633 // Compiles a GL shader and attaches it to a program. Returns the shader ID if
634 // successful, or 0 if not.
635 static GrGLuint attach_shader(const GrGLContext& glCtx,
636                               GrGLuint programId,
637                               GrGLenum type,
638                               const SkString& shaderSrc) {
639     const GrGLInterface* gli = glCtx.interface();
640
641     GrGLuint shaderId;
642     GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
643     if (0 == shaderId) {
644         return 0;
645     }
646
647     const GrGLchar* sourceStr = shaderSrc.c_str();
648     GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
649     GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
650     GR_GL_CALL(gli, CompileShader(shaderId));
651
652     // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
653     bool checkCompiled = !glCtx.isChromium();
654 #ifdef SK_DEBUG
655     checkCompiled = true;
656 #endif
657     if (checkCompiled) {
658         GrGLint compiled = GR_GL_INIT_ZERO;
659         GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
660
661         if (!compiled) {
662             GrGLint infoLen = GR_GL_INIT_ZERO;
663             GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
664             SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
665             if (infoLen > 0) {
666                 // retrieve length even though we don't need it to workaround bug in Chromium cmd
667                 // buffer param validation.
668                 GrGLsizei length = GR_GL_INIT_ZERO;
669                 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
670                                                  &length, (char*)log.get()));
671                 GrPrintf(shaderSrc.c_str());
672                 GrPrintf("\n%s", log.get());
673             }
674             SkDEBUGFAIL("Shader compilation failed!");
675             GR_GL_CALL(gli, DeleteShader(shaderId));
676             return 0;
677         }
678     }
679     if (c_PrintShaders) {
680         GrPrintf(shaderSrc.c_str());
681         GrPrintf("\n");
682     }
683
684     // Attach the shader, but defer deletion until after we have linked the program.
685     // This works around a bug in the Android emulator's GLES2 wrapper which
686     // will immediately delete the shader object and free its memory even though it's
687     // attached to a program, which then causes glLinkProgram to fail.
688     GR_GL_CALL(gli, AttachShader(programId, shaderId));
689
690     return shaderId;
691 }
692
693 bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const {
694     SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
695     fragShaderSrc.append(fFSExtensions);
696     append_default_precision_qualifier(kDefaultFragmentPrecision,
697                                        fGpu->glStandard(),
698                                        &fragShaderSrc);
699     this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc);
700     this->appendDecls(fFSInputs, &fragShaderSrc);
701     // We shouldn't have declared outputs on 1.10
702     SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty());
703     this->appendDecls(fFSOutputs, &fragShaderSrc);
704     fragShaderSrc.append(fFSFunctions);
705     fragShaderSrc.append("void main() {\n");
706     fragShaderSrc.append(fFSCode);
707     fragShaderSrc.append("}\n");
708
709     GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc);
710     if (!fragShaderId) {
711         return false;
712     }
713
714     *shaderIds->append() = fragShaderId;
715
716     return true;
717 }
718
719 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const {
720     if (fHasCustomColorOutput) {
721         GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name()));
722     }
723     if (fHasSecondaryOutput) {
724         GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_name()));
725     }
726 }
727
728 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const {
729     return fGpu->ctxInfo();
730 }
731
732 ////////////////////////////////////////////////////////////////////////////////
733
734 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu,
735                                              GrGLUniformManager& uniformManager,
736                                              const GrGLProgramDesc& desc)
737     : INHERITED(gpu, uniformManager, desc)
738     , fDesc(desc)
739     , fVSAttrs(kVarsPerBlock)
740     , fVSOutputs(kVarsPerBlock)
741     , fGSInputs(kVarsPerBlock)
742     , fGSOutputs(kVarsPerBlock) {
743
744     const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
745
746     fPositionVar = &fVSAttrs.push_back();
747     fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition");
748     if (-1 != header.fLocalCoordAttributeIndex) {
749         fLocalCoordsVar = &fVSAttrs.push_back();
750         fLocalCoordsVar->set(kVec2f_GrSLType,
751                              GrGLShaderVar::kAttribute_TypeModifier,
752                              "aLocalCoords");
753     } else {
754         fLocalCoordsVar = fPositionVar;
755     }
756
757     const char* viewMName;
758     fViewMatrixUniform = this->addUniform(GrGLShaderBuilder::kVertex_Visibility,
759                                           kMat33f_GrSLType, "ViewM", &viewMName);
760
761     this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n"
762                         "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n",
763                         viewMName, fPositionVar->c_str());
764
765     // we output point size in the GS if present
766     if (header.fEmitsPointSize
767 #if GR_GL_EXPERIMENTAL_GS
768         && !header.fExperimentalGS
769 #endif
770         ) {
771         this->vsCodeAppend("\tgl_PointSize = 1.0;\n");
772     }
773
774     if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
775         this->addAttribute(kVec4f_GrSLType, color_attribute_name());
776         const char *vsName, *fsName;
777         this->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
778         this->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name());
779         this->setInputColor(fsName);
780     }
781
782     if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
783         this->addAttribute(kVec4f_GrSLType, coverage_attribute_name());
784         const char *vsName, *fsName;
785         this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
786         this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name());
787         this->setInputCoverage(fsName);
788     }
789 }
790
791 bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) {
792     for (int i = 0; i < fVSAttrs.count(); ++i) {
793         const GrGLShaderVar& attr = fVSAttrs[i];
794         // if attribute already added, don't add it again
795         if (attr.getName().equals(name)) {
796             SkASSERT(attr.getType() == type);
797             return false;
798         }
799     }
800     fVSAttrs.push_back().set(type,
801                              GrGLShaderVar::kAttribute_TypeModifier,
802                              name);
803     return true;
804 }
805
806 bool GrGLFullShaderBuilder::addEffectAttribute(int attributeIndex,
807                                                GrSLType type,
808                                                const SkString& name) {
809     if (!this->addAttribute(type, name.c_str())) {
810         return false;
811     }
812
813     fEffectAttributes.push_back().set(attributeIndex, name);
814     return true;
815 }
816
817 void GrGLFullShaderBuilder::addVarying(GrSLType type,
818                                        const char* name,
819                                        const char** vsOutName,
820                                        const char** fsInName) {
821     fVSOutputs.push_back();
822     fVSOutputs.back().setType(type);
823     fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
824     this->nameVariable(fVSOutputs.back().accessName(), 'v', name);
825
826     if (vsOutName) {
827         *vsOutName = fVSOutputs.back().getName().c_str();
828     }
829     // input to FS comes either from VS or GS
830     const SkString* fsName;
831 #if GR_GL_EXPERIMENTAL_GS
832     if (fDesc.getHeader().fExperimentalGS) {
833         // if we have a GS take each varying in as an array
834         // and output as non-array.
835         fGSInputs.push_back();
836         fGSInputs.back().setType(type);
837         fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
838         fGSInputs.back().setUnsizedArray();
839         *fGSInputs.back().accessName() = fVSOutputs.back().getName();
840         fGSOutputs.push_back();
841         fGSOutputs.back().setType(type);
842         fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
843         this->nameVariable(fGSOutputs.back().accessName(), 'g', name);
844         fsName = fGSOutputs.back().accessName();
845     } else
846 #endif
847     {
848         fsName = fVSOutputs.back().accessName();
849     }
850     this->fsInputAppend().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, *fsName);
851     if (fsInName) {
852         *fsInName = fsName->c_str();
853     }
854 }
855
856 const SkString* GrGLFullShaderBuilder::getEffectAttributeName(int attributeIndex) const {
857     const AttributePair* attribEnd = fEffectAttributes.end();
858     for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
859         if (attrib->fIndex == attributeIndex) {
860             return &attrib->fName;
861         }
862     }
863
864     return NULL;
865 }
866
867 GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects(
868         const GrEffectStage* effectStages[],
869         const EffectKey effectKeys[],
870         int effectCnt,
871         GrGLSLExpr4* inOutFSColor) {
872
873     GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt);
874     this->INHERITED::createAndEmitEffects(&programEffectsBuilder,
875                                           effectStages,
876                                           effectKeys,
877                                           effectCnt,
878                                           inOutFSColor);
879     return programEffectsBuilder.finish();
880 }
881
882 bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const {
883     const GrGLContext& glCtx = this->gpu()->glContext();
884     SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
885     this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc);
886     this->appendDecls(fVSAttrs, &vertShaderSrc);
887     this->appendDecls(fVSOutputs, &vertShaderSrc);
888     vertShaderSrc.append("void main() {\n");
889     vertShaderSrc.append(fVSCode);
890     vertShaderSrc.append("}\n");
891     GrGLuint vertShaderId = attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc);
892     if (!vertShaderId) {
893         return false;
894     }
895     *shaderIds->append() = vertShaderId;
896
897 #if GR_GL_EXPERIMENTAL_GS
898     if (fDesc.getHeader().fExperimentalGS) {
899         SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration);
900         SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo()));
901         geomShaderSrc.append("layout(triangles) in;\n"
902                              "layout(triangle_strip, max_vertices = 6) out;\n");
903         this->appendDecls(fGSInputs, &geomShaderSrc);
904         this->appendDecls(fGSOutputs, &geomShaderSrc);
905         geomShaderSrc.append("void main() {\n");
906         geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n"
907                              "\t\tgl_Position = gl_in[i].gl_Position;\n");
908         if (fDesc.getHeader().fEmitsPointSize) {
909             geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
910         }
911         SkASSERT(fGSInputs.count() == fGSOutputs.count());
912         for (int i = 0; i < fGSInputs.count(); ++i) {
913             geomShaderSrc.appendf("\t\t%s = %s[i];\n",
914                                   fGSOutputs[i].getName().c_str(),
915                                   fGSInputs[i].getName().c_str());
916         }
917         geomShaderSrc.append("\t\tEmitVertex();\n"
918                              "\t}\n"
919                              "\tEndPrimitive();\n");
920         geomShaderSrc.append("}\n");
921         GrGLuint geomShaderId = attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc);
922         if (!geomShaderId) {
923             return false;
924         }
925         *shaderIds->append() = geomShaderId;
926     }
927 #endif
928
929     return this->INHERITED::compileAndAttachShaders(programId, shaderIds);
930 }
931
932 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const {
933     this->INHERITED::bindProgramLocations(programId);
934
935     const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
936
937     // Bind the attrib locations to same values for all shaders
938     SkASSERT(-1 != header.fPositionAttributeIndex);
939     GL_CALL(BindAttribLocation(programId,
940                                header.fPositionAttributeIndex,
941                                fPositionVar->c_str()));
942     if (-1 != header.fLocalCoordAttributeIndex) {
943         GL_CALL(BindAttribLocation(programId,
944                                    header.fLocalCoordAttributeIndex,
945                                    fLocalCoordsVar->c_str()));
946     }
947     if (-1 != header.fColorAttributeIndex) {
948         GL_CALL(BindAttribLocation(programId,
949                                    header.fColorAttributeIndex,
950                                    color_attribute_name()));
951     }
952     if (-1 != header.fCoverageAttributeIndex) {
953         GL_CALL(BindAttribLocation(programId,
954                                    header.fCoverageAttributeIndex,
955                                    coverage_attribute_name()));
956     }
957
958     const AttributePair* attribEnd = fEffectAttributes.end();
959     for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attribEnd; ++attrib) {
960          GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_str()));
961     }
962 }
963
964 ////////////////////////////////////////////////////////////////////////////////
965
966 GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu,
967                                                              GrGLUniformManager& uniformManager,
968                                                              const GrGLProgramDesc& desc)
969     : INHERITED(gpu, uniformManager, desc)
970     , fNumTexCoordSets(0) {
971
972     SkASSERT(!desc.getHeader().fHasVertexCode);
973     SkASSERT(gpu->glCaps().pathRenderingSupport());
974     SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
975     SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
976 }
977
978 int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) {
979     int firstFreeCoordSet = fNumTexCoordSets;
980     fNumTexCoordSets += count;
981     SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fNumTexCoordSets);
982     return firstFreeCoordSet;
983 }
984
985 GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects(
986         const GrEffectStage* effectStages[],
987         const EffectKey effectKeys[],
988         int effectCnt,
989         GrGLSLExpr4* inOutFSColor) {
990
991     GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this,
992                                                                  effectCnt);
993     this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder,
994                                           effectStages,
995                                           effectKeys,
996                                           effectCnt,
997                                           inOutFSColor);
998     return pathTexGenEffectsBuilder.finish();
999 }