130ba436f04e61d4505fb854d5fc56079636e0788joshualitt/*
230ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Copyright 2014 Google Inc.
330ba436f04e61d4505fb854d5fc56079636e0788joshualitt *
430ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Use of this source code is governed by a BSD-style license that can be
530ba436f04e61d4505fb854d5fc56079636e0788joshualitt * found in the LICENSE file.
630ba436f04e61d4505fb854d5fc56079636e0788joshualitt */
730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLProgram.h"
930ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLSLPrettyPrint.h"
1030ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLUniformHandle.h"
1130ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrCoordTransform.h"
1230ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "../GrGpuGL.h"
1330ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrGLFragmentShaderBuilder.h"
1430ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrGLProgramBuilder.h"
1530ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrTexture.h"
1630ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrGLVertexShaderBuilder.h"
1730ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "SkRTConf.h"
1830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "SkTraceEvent.h"
1930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
2030ba436f04e61d4505fb854d5fc56079636e0788joshualittnamespace {
2130ba436f04e61d4505fb854d5fc56079636e0788joshualitt#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
2230ba436f04e61d4505fb854d5fc56079636e0788joshualitt#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
2330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
2430ba436f04e61d4505fb854d5fc56079636e0788joshualitt// number of each input/output type in a single allocation block
2530ba436f04e61d4505fb854d5fc56079636e0788joshualittstatic const int kVarsPerBlock = 8;
2630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
2730ba436f04e61d4505fb854d5fc56079636e0788joshualitt// ES2 FS only guarantees mediump and lowp support
2830ba436f04e61d4505fb854d5fc56079636e0788joshualittstatic const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
2930ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
3030ba436f04e61d4505fb854d5fc56079636e0788joshualitt
3130ba436f04e61d4505fb854d5fc56079636e0788joshualitt///////////////////////////////////////////////////////////////////////////////////////////////////
3230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
33b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrGLProgramBuilder::genProgram(const GrGeometryStage* geometryProcessor,
34b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                    const GrFragmentStage* colorStages[],
35b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                    const GrFragmentStage* coverageStages[]) {
3630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
3730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
3830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fFS.emitCodeBeforeEffects();
3930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
4030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    ///////////////////////////////////////////////////////////////////////////
4130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // get the initial color and coverage to feed into the first effect in each effect chain
4230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
4330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLSLExpr4 inputColor;
4430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLSLExpr4 inputCoverage;
4530ba436f04e61d4505fb854d5fc56079636e0788joshualitt
4630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
4730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        const char* name;
4830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fUniformHandles.fColorUni =
4930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
5030ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             kVec4f_GrSLType,
5130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             "Color",
5230ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             &name);
5330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        inputColor = GrGLSLExpr4(name);
54842b086a3c876061e1279d47e6009629c9818b03egdaniel    } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
55842b086a3c876061e1279d47e6009629c9818b03egdaniel        inputColor = GrGLSLExpr4(1);
5630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
5730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
5830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
5930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        const char* name;
6030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fUniformHandles.fCoverageUni =
6130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
6230ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             kVec4f_GrSLType,
6330ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             "Coverage",
6430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                             &name);
6530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        inputCoverage = GrGLSLExpr4(name);
66842b086a3c876061e1279d47e6009629c9818b03egdaniel    } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
6730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        inputCoverage = GrGLSLExpr4(1);
6830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
6930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
7023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    // Subclasses drive effect emitting
7123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    this->createAndEmitEffects(geometryProcessor, colorStages, coverageStages, &inputColor,
7223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                               &inputCoverage);
7330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
7430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fFS.emitCodeAfterEffects(inputColor, inputCoverage);
7530ba436f04e61d4505fb854d5fc56079636e0788joshualitt
7630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (!this->finish()) {
7730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        return false;
7830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
7930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
8030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    return true;
8130ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
8230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
8330ba436f04e61d4505fb854d5fc56079636e0788joshualitt//////////////////////////////////////////////////////////////////////////////
8430ba436f04e61d4505fb854d5fc56079636e0788joshualitt
8530ba436f04e61d4505fb854d5fc56079636e0788joshualittGrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
8630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                       const GrGLProgramDesc& desc)
87b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    : fEffectEmitter(NULL)
88b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    , fFragOnly(SkToBool(desc.getHeader().fUseFragShaderOnly))
8930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    , fTexCoordSetCnt(0)
9030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    , fProgramID(0)
9130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    , fFS(this, desc)
92ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    , fSeparableVaryingInfos(kVarsPerBlock)
93b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    , fGrProcessorEmitter(this)
9430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    , fDesc(desc)
9530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    , fGpu(gpu)
9630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    , fUniforms(kVarsPerBlock) {
9730ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
9830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
9930ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
10030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if ('\0' == prefix) {
10130ba436f04e61d4505fb854d5fc56079636e0788joshualitt        *out = name;
10230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    } else {
10330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        out->printf("%c%s", prefix, name);
10430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
10530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (fCodeStage.inStageCode()) {
10630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        if (out->endsWith('_')) {
10730ba436f04e61d4505fb854d5fc56079636e0788joshualitt            // Names containing "__" are reserved.
10830ba436f04e61d4505fb854d5fc56079636e0788joshualitt            out->append("x");
10930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        }
11030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        out->appendf("_Stage%d", fCodeStage.stageIndex());
11130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
11230ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
11330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
11430ba436f04e61d4505fb854d5fc56079636e0788joshualittGrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32_t visibility,
11530ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                                                          GrSLType type,
11630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                                                          const char* name,
11730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                                                          int count,
11830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                                                          const char** outName) {
11930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkASSERT(name && strlen(name));
12030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
12130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkASSERT(0 == (~kVisibilityMask & visibility));
12230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkASSERT(0 != visibility);
12330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
12430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    UniformInfo& uni = fUniforms.push_back();
12530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    uni.fVariable.setType(type);
12630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
12730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    this->nameVariable(uni.fVariable.accessName(), 'u', name);
12830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    uni.fVariable.setArrayCount(count);
12930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    uni.fVisibility = visibility;
13030ba436f04e61d4505fb854d5fc56079636e0788joshualitt
13130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // If it is visible in both the VS and FS, the precision must match.
13230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // We declare a default FS precision, but not a default VS. So set the var
13330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // to use the default FS precision.
13430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
13530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        // the fragment and vertex precisions must match
13630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        uni.fVariable.setPrecision(kDefaultFragmentPrecision);
13730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
13830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
13949f085dddff10473b6ebf832a974288300224e60bsalomon    if (outName) {
14030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        *outName = uni.fVariable.c_str();
14130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
14230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
14330ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
14430ba436f04e61d4505fb854d5fc56079636e0788joshualitt
14530ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLProgramBuilder::appendDecls(const VarArray& vars, SkString* out) const {
14630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    for (int i = 0; i < vars.count(); ++i) {
14730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        vars[i].appendDecl(this->ctxInfo(), out);
14830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        out->append(";\n");
14930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
15030ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
15130ba436f04e61d4505fb854d5fc56079636e0788joshualitt
15230ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
15330ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                            SkString* out) const {
15430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    for (int i = 0; i < fUniforms.count(); ++i) {
15530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        if (fUniforms[i].fVisibility & visibility) {
15630ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
15730ba436f04e61d4505fb854d5fc56079636e0788joshualitt            out->append(";\n");
15830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        }
15930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
16030ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
16130ba436f04e61d4505fb854d5fc56079636e0788joshualitt
162b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLProgramBuilder::createAndEmitEffects(const GrFragmentStage* effectStages[],
16330ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                              int effectCnt,
16430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                              const GrGLProgramDesc::EffectKeyProvider& keyProvider,
16530ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                              GrGLSLExpr4* fsInOutColor) {
16630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    bool effectEmitted = false;
16730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
16830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLSLExpr4 inColor = *fsInOutColor;
16930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLSLExpr4 outColor;
17030ba436f04e61d4505fb854d5fc56079636e0788joshualitt
17130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    for (int e = 0; e < effectCnt; ++e) {
172b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        fGrProcessorEmitter.set(effectStages[e]->getFragmentProcessor());
173b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        fEffectEmitter = &fGrProcessorEmitter;
17423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        // calls into the subclass to emit the actual effect into the program effect object
17523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        this->emitEffect(*effectStages[e], e, keyProvider, &inColor, &outColor);
17623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        effectEmitted = true;
17723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    }
17830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
17923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    if (effectEmitted) {
18023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        *fsInOutColor = outColor;
18123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    }
18223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt}
18330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
184b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLProgramBuilder::emitEffect(const GrProcessorStage& effectStage,
18523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                                    int effectIndex,
18623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                                    const GrGLProgramDesc::EffectKeyProvider& keyProvider,
18723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                                    GrGLSLExpr4* inColor,
18823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                                    GrGLSLExpr4* outColor) {
189b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    SkASSERT(effectStage.getProcessor());
19023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    CodeStage::AutoStageRestore csar(&fCodeStage, &effectStage);
19123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
19223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    if (inColor->isZeros()) {
19323e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        SkString inColorName;
19423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt
19523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        // Effects have no way to communicate zeros, they treat an empty string as ones.
19623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        this->nameVariable(&inColorName, '\0', "input");
19723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        fFS.codeAppendf("\tvec4 %s = %s;\n", inColorName.c_str(), inColor->c_str());
19823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        *inColor = inColorName;
19923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    }
20030ba436f04e61d4505fb854d5fc56079636e0788joshualitt
20123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    // create var to hold stage result
20223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    SkString outColorName;
20323e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    this->nameVariable(&outColorName, '\0', "output");
20423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    fFS.codeAppendf("\tvec4 %s;\n", outColorName.c_str());
20523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    *outColor = outColorName;
20630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
20723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    this->emitEffect(effectStage, keyProvider.get(effectIndex), outColor->c_str(),
20823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                     inColor->isOnes() ? NULL : inColor->c_str(), fCodeStage.stageIndex());
20930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
21023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    *inColor = *outColor;
21123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt}
21230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
213b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLProgramBuilder::emitSamplers(const GrProcessor& effect,
214b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                      GrGLProcessor::TextureSamplerArray* outSamplers) {
21523e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    SkTArray<GrGLProgramEffects::Sampler, true>& samplers =
21623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt            this->getProgramEffects()->addSamplers();
21723e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    int numTextures = effect.numTextures();
21823e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    samplers.push_back_n(numTextures);
21923e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    SkString name;
22023e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt    for (int t = 0; t < numTextures; ++t) {
22123e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        name.printf("Sampler%d", t);
22223e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt        samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
22323e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                                                kSampler2D_GrSLType,
22423e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                                                name.c_str());
225b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
22623e280d1f227d94f6b3dfd0b47359cca1569e1b4joshualitt                               (samplers[t].fUniform, effect.textureAccess(t)));
22730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
22830ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
22930ba436f04e61d4505fb854d5fc56079636e0788joshualitt
23030ba436f04e61d4505fb854d5fc56079636e0788joshualittbool GrGLProgramBuilder::finish() {
23130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkASSERT(0 == fProgramID);
23230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GL_CALL_RET(fProgramID, CreateProgram());
23330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (!fProgramID) {
23430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        return false;
23530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
23630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
23730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    SkTDArray<GrGLuint> shadersToDelete;
23830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
23930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) {
24030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        GL_CALL(DeleteProgram(fProgramID));
24130ba436f04e61d4505fb854d5fc56079636e0788joshualitt        return false;
24230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
24330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
24430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    this->bindProgramLocations(fProgramID);
24530ba436f04e61d4505fb854d5fc56079636e0788joshualitt
24630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GL_CALL(LinkProgram(fProgramID));
24730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
24830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
24930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    bool checkLinked = !fGpu->ctxInfo().isChromium();
25030ba436f04e61d4505fb854d5fc56079636e0788joshualitt#ifdef SK_DEBUG
25130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    checkLinked = true;
25230ba436f04e61d4505fb854d5fc56079636e0788joshualitt#endif
25330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (checkLinked) {
25430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        GrGLint linked = GR_GL_INIT_ZERO;
25530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
25630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        if (!linked) {
25730ba436f04e61d4505fb854d5fc56079636e0788joshualitt            GrGLint infoLen = GR_GL_INIT_ZERO;
25830ba436f04e61d4505fb854d5fc56079636e0788joshualitt            GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
25930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
26030ba436f04e61d4505fb854d5fc56079636e0788joshualitt            if (infoLen > 0) {
26130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                // retrieve length even though we don't need it to workaround
26230ba436f04e61d4505fb854d5fc56079636e0788joshualitt                // bug in chrome cmd buffer param validation.
26330ba436f04e61d4505fb854d5fc56079636e0788joshualitt                GrGLsizei length = GR_GL_INIT_ZERO;
26430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                GL_CALL(GetProgramInfoLog(fProgramID,
26530ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                          infoLen+1,
26630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                          &length,
26730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                          (char*)log.get()));
26830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                GrPrintf((char*)log.get());
26930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            }
27030ba436f04e61d4505fb854d5fc56079636e0788joshualitt            SkDEBUGFAIL("Error linking program");
27130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            GL_CALL(DeleteProgram(fProgramID));
27230ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fProgramID = 0;
27330ba436f04e61d4505fb854d5fc56079636e0788joshualitt            return false;
27430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        }
27530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
27630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
27730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    this->resolveProgramLocations(fProgramID);
27830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
27930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    for (int i = 0; i < shadersToDelete.count(); ++i) {
28030ba436f04e61d4505fb854d5fc56079636e0788joshualitt      GL_CALL(DeleteShader(shadersToDelete[i]));
28130ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
28230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
28330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    return true;
28430ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
28530ba436f04e61d4505fb854d5fc56079636e0788joshualitt
28630ba436f04e61d4505fb854d5fc56079636e0788joshualittbool GrGLProgramBuilder::compileAndAttachShaders(GrGLuint programId,
28730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                                                 SkTDArray<GrGLuint>* shaderIds) const {
28830ba436f04e61d4505fb854d5fc56079636e0788joshualitt    return fFS.compileAndAttachShaders(programId, shaderIds);
28930ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
29030ba436f04e61d4505fb854d5fc56079636e0788joshualitt
29130ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLProgramBuilder::bindProgramLocations(GrGLuint programId) {
29230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fFS.bindProgramLocations(programId);
29330ba436f04e61d4505fb854d5fc56079636e0788joshualitt
29430ba436f04e61d4505fb854d5fc56079636e0788joshualitt    // skbug.com/2056
29530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
29630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (usingBindUniform) {
29730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        int count = fUniforms.count();
29830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        for (int i = 0; i < count; ++i) {
29930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_str()));
30030ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fUniforms[i].fLocation = i;
30130ba436f04e61d4505fb854d5fc56079636e0788joshualitt        }
30230ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
30330ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
30430ba436f04e61d4505fb854d5fc56079636e0788joshualitt
30530ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLProgramBuilder::resolveProgramLocations(GrGLuint programId) {
30630ba436f04e61d4505fb854d5fc56079636e0788joshualitt    bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
30730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    if (!usingBindUniform) {
30830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        int count = fUniforms.count();
30930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        for (int i = 0; i < count; ++i) {
31030ba436f04e61d4505fb854d5fc56079636e0788joshualitt            GrGLint location;
31130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            GL_CALL_RET(location,
31230ba436f04e61d4505fb854d5fc56079636e0788joshualitt                        GetUniformLocation(programId, fUniforms[i].fVariable.c_str()));
31330ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fUniforms[i].fLocation = location;
31430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        }
31530ba436f04e61d4505fb854d5fc56079636e0788joshualitt    }
316ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen
317ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    int count = fSeparableVaryingInfos.count();
318ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    for (int i = 0; i < count; ++i) {
319ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        GrGLint location;
320ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        GL_CALL_RET(location,
321ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen                    GetProgramResourceLocation(programId,
322ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen                                               GR_GL_FRAGMENT_INPUT,
323ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen                                               fSeparableVaryingInfos[i].fVariable.c_str()));
324ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        fSeparableVaryingInfos[i].fLocation = location;
325ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    }
32630ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
32730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
32830ba436f04e61d4505fb854d5fc56079636e0788joshualittconst GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
32930ba436f04e61d4505fb854d5fc56079636e0788joshualitt    return fGpu->ctxInfo();
33030ba436f04e61d4505fb854d5fc56079636e0788joshualitt}
331