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