Home | History | Annotate | Download | only in gl
      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 bool 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 
    111 bool 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 
    252 GrGLShaderBuilder::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 
    268 bool 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 
    285 bool 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 
    316 void 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 
    323 void 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 
    338 const 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 
    362 void 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 
    375 void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSampler& sampler,
    376                                               const char* coordName,
    377                                               GrSLType varyingType) {
    378     this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType);
    379 }
    380 
    381 void 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 
    391 GrGLShaderBuilder::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 
    409 GrGLShaderBuilder::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 
    419 const 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 
    435 GrGLUniformManager::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 
    473 SkString 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 
    488 const 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 
    535 void 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 
    556 namespace {
    557 
    558 inline 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 
    582 void 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 
    589 void 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 
    599 void 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 
    646 const char* GrGLShaderBuilder::getColorOutputName() const {
    647     return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
    648 }
    649 
    650 const 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 
    660 bool 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.
    723 static 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 
    781 bool 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 
    807 void 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 
    816 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const {
    817     return fGpu->ctxInfo();
    818 }
    819 
    820 ////////////////////////////////////////////////////////////////////////////////
    821 
    822 GrGLFullShaderBuilder::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 
    832 void 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 
    883 void 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 
    895 bool 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 
    910 bool 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 
    921 void 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 
    960 const 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 
    971 GrGLProgramEffects* 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 
    986 bool 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 
   1037 void 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 
   1071 GrGLFragmentOnlyShaderBuilder::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 
   1081 int 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 
   1088 GrGLProgramEffects* 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