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