GrGLProgram.cpp revision ae81d5c4aa1716756b2cfb4c44f27f4dce2716ef
1/*
2 * Copyright 2011 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 "GrGLProgram.h"
9
10#include "GrAllocator.h"
11#include "GrEffect.h"
12#include "GrDrawEffect.h"
13#include "GrGLEffect.h"
14#include "GrGpuGL.h"
15#include "GrGLShaderVar.h"
16#include "GrBackendEffectFactory.h"
17#include "SkTrace.h"
18#include "SkXfermode.h"
19
20#include "SkRTConf.h"
21
22SK_DEFINE_INST_COUNT(GrGLProgram)
23
24#define GL_CALL(X) GR_GL_CALL(fContext.interface(), X)
25#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X)
26
27SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false,
28                "Print the source code for all shaders generated.");
29
30#define COL_ATTR_NAME "aColor"
31#define COV_ATTR_NAME "aCoverage"
32#define EDGE_ATTR_NAME "aEdge"
33
34namespace {
35inline const char* declared_color_output_name() { return "fsColorOut"; }
36inline const char* dual_source_output_name() { return "dualSourceOut"; }
37}
38
39const GrGLProgram::AttribLayout GrGLProgram::kAttribLayouts[kGrVertexAttribTypeCount] = {
40    {1, GR_GL_FLOAT, false},         // kFloat_GrVertexAttribType
41    {2, GR_GL_FLOAT, false},         // kVec2f_GrVertexAttribType
42    {3, GR_GL_FLOAT, false},         // kVec3f_GrVertexAttribType
43    {4, GR_GL_FLOAT, false},         // kVec4f_GrVertexAttribType
44    {4, GR_GL_UNSIGNED_BYTE, true},  // kVec4ub_GrVertexAttribType
45};
46
47void GrGLProgram::BuildDesc(const GrDrawState& drawState,
48                            bool isPoints,
49                            GrDrawState::BlendOptFlags blendOpts,
50                            GrBlendCoeff srcCoeff,
51                            GrBlendCoeff dstCoeff,
52                            const GrGpuGL* gpu,
53                            Desc* desc) {
54
55    // This should already have been caught
56    GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts));
57
58    bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
59
60    bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag |
61                                           GrDrawState::kEmitCoverage_BlendOptFlag));
62
63    // The descriptor is used as a cache key. Thus when a field of the
64    // descriptor will not affect program generation (because of the attribute
65    // bindings in use or other descriptor field settings) it should be set
66    // to a canonical value to avoid duplicate programs with different keys.
67
68    // Must initialize all fields or cache will have false negatives!
69    desc->fAttribBindings = drawState.getAttribBindings();
70
71    desc->fEmitsPointSize = isPoints;
72
73    bool requiresAttributeColors =
74        !skipColor && SkToBool(desc->fAttribBindings & GrDrawState::kColor_AttribBindingsBit);
75    bool requiresAttributeCoverage =
76        !skipCoverage && SkToBool(desc->fAttribBindings & GrDrawState::kCoverage_AttribBindingsBit);
77
78    // fColorInput/fCoverageInput records how colors are specified for the program So we strip the
79    // bits from the bindings to avoid false negatives when searching for an existing program in the
80    // cache.
81    desc->fAttribBindings &=
82        ~(GrDrawState::kColor_AttribBindingsBit | GrDrawState::kCoverage_AttribBindingsBit);
83
84    desc->fColorFilterXfermode = skipColor ?
85                                SkXfermode::kDst_Mode :
86                                drawState.getColorFilterMode();
87
88    // no reason to do edge aa or look at per-vertex coverage if coverage is ignored
89    if (skipCoverage) {
90        desc->fAttribBindings &= ~(GrDrawState::kEdge_AttribBindingsBit |
91                                   GrDrawState::kCoverage_AttribBindingsBit);
92    }
93
94    bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
95    bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) ||
96                             (!requiresAttributeColors && 0xffffffff == drawState.getColor());
97    if (colorIsTransBlack) {
98        desc->fColorInput = Desc::kTransBlack_ColorInput;
99    } else if (colorIsSolidWhite) {
100        desc->fColorInput = Desc::kSolidWhite_ColorInput;
101    } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) {
102        desc->fColorInput = Desc::kUniform_ColorInput;
103    } else {
104        desc->fColorInput = Desc::kAttribute_ColorInput;
105    }
106
107    bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState.getCoverage();
108
109    if (skipCoverage) {
110        desc->fCoverageInput = Desc::kTransBlack_ColorInput;
111    } else if (covIsSolidWhite) {
112        desc->fCoverageInput = Desc::kSolidWhite_ColorInput;
113    } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) {
114        desc->fCoverageInput = Desc::kUniform_ColorInput;
115    } else {
116        desc->fCoverageInput = Desc::kAttribute_ColorInput;
117    }
118
119    int lastEnabledStage = -1;
120
121    if (!skipCoverage && (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit)) {
122        desc->fVertexEdgeType = drawState.getVertexEdgeType();
123        desc->fDiscardIfOutsideEdge = drawState.getStencil().doesWrite();
124    } else {
125        // Use canonical values when edge-aa is not enabled to avoid program cache misses.
126        desc->fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
127        desc->fDiscardIfOutsideEdge = false;
128    }
129
130    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
131
132        bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCoverage;
133        if (!skip && drawState.isStageEnabled(s)) {
134            lastEnabledStage = s;
135            const GrEffectRef& effect = *drawState.getStage(s).getEffect();
136            const GrBackendEffectFactory& factory = effect->getFactory();
137            bool explicitLocalCoords = (drawState.getAttribBindings() &
138                                        GrDrawState::kLocalCoords_AttribBindingsBit);
139            GrDrawEffect drawEffect(drawState.getStage(s), explicitLocalCoords);
140            desc->fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps());
141        } else {
142            desc->fEffectKeys[s] = 0;
143        }
144    }
145
146    desc->fDualSrcOutput = Desc::kNone_DualSrcOutput;
147
148    // Currently the experimental GS will only work with triangle prims (and it doesn't do anything
149    // other than pass through values from the VS to the FS anyway).
150#if GR_GL_EXPERIMENTAL_GS
151#if 0
152    desc->fExperimentalGS = gpu->getCaps().geometryShaderSupport();
153#else
154    desc->fExperimentalGS = false;
155#endif
156#endif
157
158    // We want to avoid generating programs with different "first cov stage" values when they would
159    // compute the same result. We set field in the desc to kNumStages when either there are no
160    // coverage stages or the distinction between coverage and color is immaterial.
161    int firstCoverageStage = GrDrawState::kNumStages;
162    desc->fFirstCoverageStage = GrDrawState::kNumStages;
163    bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage;
164    if (hasCoverage) {
165        firstCoverageStage = drawState.getFirstCoverageStage();
166    }
167
168    // other coverage inputs
169    if (!hasCoverage) {
170        hasCoverage = requiresAttributeCoverage ||
171                      (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit);
172    }
173
174    if (hasCoverage) {
175        // color filter is applied between color/coverage computation
176        if (SkXfermode::kDst_Mode != desc->fColorFilterXfermode) {
177            desc->fFirstCoverageStage = firstCoverageStage;
178        }
179
180        if (gpu->getCaps().dualSourceBlendingSupport() &&
181            !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag |
182                           GrDrawState::kCoverageAsAlpha_BlendOptFlag))) {
183            if (kZero_GrBlendCoeff == dstCoeff) {
184                // write the coverage value to second color
185                desc->fDualSrcOutput =  Desc::kCoverage_DualSrcOutput;
186                desc->fFirstCoverageStage = firstCoverageStage;
187            } else if (kSA_GrBlendCoeff == dstCoeff) {
188                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
189                desc->fDualSrcOutput = Desc::kCoverageISA_DualSrcOutput;
190                desc->fFirstCoverageStage = firstCoverageStage;
191            } else if (kSC_GrBlendCoeff == dstCoeff) {
192                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
193                desc->fDualSrcOutput = Desc::kCoverageISC_DualSrcOutput;
194                desc->fFirstCoverageStage = firstCoverageStage;
195            }
196        }
197    }
198
199    desc->fPositionAttributeIndex = drawState.getAttribIndex(GrDrawState::kPosition_AttribIndex);
200    if (requiresAttributeColors) {
201        desc->fColorAttributeIndex = drawState.getAttribIndex(GrDrawState::kColor_AttribIndex);
202    } else {
203        desc->fColorAttributeIndex = GrDrawState::kColorOverrideAttribIndexValue;
204    }
205    if (requiresAttributeCoverage) {
206        desc->fCoverageAttributeIndex = drawState.getAttribIndex(GrDrawState::kCoverage_AttribIndex);
207    } else {
208        desc->fCoverageAttributeIndex = GrDrawState::kCoverageOverrideAttribIndexValue;
209    }
210    if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
211        desc->fEdgeAttributeIndex = drawState.getAttribIndex(GrDrawState::kEdge_AttribIndex);
212    }
213    if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
214        desc->fLocalCoordsAttributeIndex = drawState.getAttribIndex(GrDrawState::kLocalCoords_AttribIndex);
215    }
216
217#if GR_DEBUG
218    // verify valid vertex attribute state
219    const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs();
220    GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt);
221    GrAssert(kAttribLayouts[vertexAttribs[desc->fPositionAttributeIndex].fType].fCount == 2);
222    if (requiresAttributeColors) {
223        GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt);
224        GrAssert(kAttribLayouts[vertexAttribs[desc->fColorAttributeIndex].fType].fCount == 4);
225    }
226    if (requiresAttributeCoverage) {
227        GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt);
228        GrAssert(kAttribLayouts[vertexAttribs[desc->fCoverageAttributeIndex].fType].fCount == 4);
229    }
230    if (desc->fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
231        GrAssert(desc->fEdgeAttributeIndex < GrDrawState::kVertexAttribCnt);
232        GrAssert(kAttribLayouts[vertexAttribs[desc->fEdgeAttributeIndex].fType].fCount == 4);
233    }
234    if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
235        GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt);
236        GrAssert(kAttribLayouts[vertexAttribs[desc->fLocalCoordsAttributeIndex].fType].fCount == 2);
237    }
238#endif
239}
240
241GrGLProgram* GrGLProgram::Create(const GrGLContext& gl,
242                                 const Desc& desc,
243                                 const GrEffectStage* stages[]) {
244    GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages));
245    if (!program->succeeded()) {
246        delete program;
247        program = NULL;
248    }
249    return program;
250}
251
252GrGLProgram::GrGLProgram(const GrGLContext& gl,
253                         const Desc& desc,
254                         const GrEffectStage* stages[])
255: fContext(gl)
256, fUniformManager(gl) {
257    fDesc = desc;
258    fVShaderID = 0;
259    fGShaderID = 0;
260    fFShaderID = 0;
261    fProgramID = 0;
262
263    fColor = GrColor_ILLEGAL;
264    fColorFilterColor = GrColor_ILLEGAL;
265
266    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
267        fEffects[s] = NULL;
268    }
269
270    this->genProgram(stages);
271}
272
273GrGLProgram::~GrGLProgram() {
274    if (fVShaderID) {
275        GL_CALL(DeleteShader(fVShaderID));
276    }
277    if (fGShaderID) {
278        GL_CALL(DeleteShader(fGShaderID));
279    }
280    if (fFShaderID) {
281        GL_CALL(DeleteShader(fFShaderID));
282    }
283    if (fProgramID) {
284        GL_CALL(DeleteProgram(fProgramID));
285    }
286
287    for (int i = 0; i < GrDrawState::kNumStages; ++i) {
288        delete fEffects[i];
289    }
290}
291
292void GrGLProgram::abandon() {
293    fVShaderID = 0;
294    fGShaderID = 0;
295    fFShaderID = 0;
296    fProgramID = 0;
297}
298
299void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
300                                GrBlendCoeff* dstCoeff) const {
301    switch (fDesc.fDualSrcOutput) {
302        case Desc::kNone_DualSrcOutput:
303            break;
304        // the prog will write a coverage value to the secondary
305        // output and the dst is blended by one minus that value.
306        case Desc::kCoverage_DualSrcOutput:
307        case Desc::kCoverageISA_DualSrcOutput:
308        case Desc::kCoverageISC_DualSrcOutput:
309        *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
310        break;
311        default:
312            GrCrash("Unexpected dual source blend output");
313            break;
314    }
315}
316
317namespace {
318
319// given two blend coeffecients determine whether the src
320// and/or dst computation can be omitted.
321inline void need_blend_inputs(SkXfermode::Coeff srcCoeff,
322                              SkXfermode::Coeff dstCoeff,
323                              bool* needSrcValue,
324                              bool* needDstValue) {
325    if (SkXfermode::kZero_Coeff == srcCoeff) {
326        switch (dstCoeff) {
327            // these all read the src
328            case SkXfermode::kSC_Coeff:
329            case SkXfermode::kISC_Coeff:
330            case SkXfermode::kSA_Coeff:
331            case SkXfermode::kISA_Coeff:
332                *needSrcValue = true;
333                break;
334            default:
335                *needSrcValue = false;
336                break;
337        }
338    } else {
339        *needSrcValue = true;
340    }
341    if (SkXfermode::kZero_Coeff == dstCoeff) {
342        switch (srcCoeff) {
343            // these all read the dst
344            case SkXfermode::kDC_Coeff:
345            case SkXfermode::kIDC_Coeff:
346            case SkXfermode::kDA_Coeff:
347            case SkXfermode::kIDA_Coeff:
348                *needDstValue = true;
349                break;
350            default:
351                *needDstValue = false;
352                break;
353        }
354    } else {
355        *needDstValue = true;
356    }
357}
358
359/**
360 * Create a blend_coeff * value string to be used in shader code. Sets empty
361 * string if result is trivially zero.
362 */
363inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff,
364                       const char* src, const char* dst,
365                       const char* value) {
366    switch (coeff) {
367    case SkXfermode::kZero_Coeff:    /** 0 */
368        *str = "";
369        break;
370    case SkXfermode::kOne_Coeff:     /** 1 */
371        *str = value;
372        break;
373    case SkXfermode::kSC_Coeff:
374        str->printf("(%s * %s)", src, value);
375        break;
376    case SkXfermode::kISC_Coeff:
377        str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value);
378        break;
379    case SkXfermode::kDC_Coeff:
380        str->printf("(%s * %s)", dst, value);
381        break;
382    case SkXfermode::kIDC_Coeff:
383        str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value);
384        break;
385    case SkXfermode::kSA_Coeff:      /** src alpha */
386        str->printf("(%s.a * %s)", src, value);
387        break;
388    case SkXfermode::kISA_Coeff:     /** inverse src alpha (i.e. 1 - sa) */
389        str->printf("((1.0 - %s.a) * %s)", src, value);
390        break;
391    case SkXfermode::kDA_Coeff:      /** dst alpha */
392        str->printf("(%s.a * %s)", dst, value);
393        break;
394    case SkXfermode::kIDA_Coeff:     /** inverse dst alpha (i.e. 1 - da) */
395        str->printf("((1.0 - %s.a) * %s)", dst, value);
396        break;
397    default:
398        GrCrash("Unexpected xfer coeff.");
399        break;
400    }
401}
402/**
403 * Adds a line to the fragment shader code which modifies the color by
404 * the specified color filter.
405 */
406void add_color_filter(GrGLShaderBuilder* builder,
407                      const char * outputVar,
408                      SkXfermode::Coeff uniformCoeff,
409                      SkXfermode::Coeff colorCoeff,
410                      const char* filterColor,
411                      const char* inColor) {
412    SkString colorStr, constStr;
413    blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor);
414    blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor);
415
416    SkString sum;
417    GrGLSLAdd4f(&sum, colorStr.c_str(), constStr.c_str());
418    builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str());
419}
420}
421
422bool GrGLProgram::genEdgeCoverage(SkString* coverageVar,
423                                  GrGLShaderBuilder* builder) const {
424    if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
425        const char *vsName, *fsName;
426        builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName);
427        builder->addAttribute(kVec4f_GrSLType, EDGE_ATTR_NAME);
428        builder->vsCodeAppendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
429        switch (fDesc.fVertexEdgeType) {
430        case GrDrawState::kHairLine_EdgeType:
431            builder->fsCodeAppendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n",
432                                   builder->fragmentPosition(), fsName);
433            builder->fsCodeAppendf("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
434            break;
435        case GrDrawState::kQuad_EdgeType:
436            builder->fsCodeAppendf("\tfloat edgeAlpha;\n");
437            // keep the derivative instructions outside the conditional
438            builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
439            builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
440            builder->fsCodeAppendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
441            // today we know z and w are in device space. We could use derivatives
442            builder->fsCodeAppendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName,
443                                   fsName);
444            builder->fsCodeAppendf ("\t} else {\n");
445            builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
446                                   "\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
447                                    fsName, fsName);
448            builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName);
449            builder->fsCodeAppendf("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n"
450                                   "\t}\n");
451            if (kES2_GrGLBinding == fContext.info().binding()) {
452                builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n");
453            }
454            break;
455        case GrDrawState::kHairQuad_EdgeType:
456            builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
457            builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
458            builder->fsCodeAppendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
459                                   "\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
460                                   fsName, fsName);
461            builder->fsCodeAppendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
462                                   fsName);
463            builder->fsCodeAppend("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
464            builder->fsCodeAppend("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
465            if (kES2_GrGLBinding == fContext.info().binding()) {
466                builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n");
467            }
468            break;
469        default:
470            GrCrash("Unknown Edge Type!");
471            break;
472        }
473        if (fDesc.fDiscardIfOutsideEdge) {
474            builder->fsCodeAppend("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\t}\n");
475        }
476        *coverageVar = "edgeAlpha";
477        return true;
478    } else {
479        coverageVar->reset();
480        return false;
481    }
482}
483
484void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) {
485    switch (fDesc.fColorInput) {
486        case GrGLProgram::Desc::kAttribute_ColorInput: {
487            builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME);
488            const char *vsName, *fsName;
489            builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
490            builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
491            *inColor = fsName;
492            } break;
493        case GrGLProgram::Desc::kUniform_ColorInput: {
494            const char* name;
495            fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
496                                                            kVec4f_GrSLType, "Color", &name);
497            *inColor = name;
498            break;
499        }
500        case GrGLProgram::Desc::kTransBlack_ColorInput:
501            GrAssert(!"needComputedColor should be false.");
502            break;
503        case GrGLProgram::Desc::kSolidWhite_ColorInput:
504            break;
505        default:
506            GrCrash("Unknown color type.");
507            break;
508    }
509}
510
511void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) {
512    const char* covUniName;
513    fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
514                                                       kVec4f_GrSLType, "Coverage", &covUniName);
515    if (inOutCoverage->size()) {
516        builder->fsCodeAppendf("\tvec4 uniCoverage = %s * %s;\n",
517                               covUniName, inOutCoverage->c_str());
518        *inOutCoverage = "uniCoverage";
519    } else {
520        *inOutCoverage = covUniName;
521    }
522}
523
524namespace {
525void gen_attribute_coverage(GrGLShaderBuilder* builder,
526                            SkString* inOutCoverage) {
527    builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME);
528    const char *vsName, *fsName;
529    builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
530    builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
531    if (inOutCoverage->size()) {
532        builder->fsCodeAppendf("\tvec4 attrCoverage = %s * %s;\n", fsName, inOutCoverage->c_str());
533        *inOutCoverage = "attrCoverage";
534    } else {
535        *inOutCoverage = fsName;
536    }
537}
538}
539
540void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const {
541#if GR_GL_EXPERIMENTAL_GS
542    // TODO: The builder should add all this glue code.
543    if (fDesc.fExperimentalGS) {
544        GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration);
545        builder->fGSHeader.append("layout(triangles) in;\n"
546                                   "layout(triangle_strip, max_vertices = 6) out;\n");
547        builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n"
548                              "\t\tgl_Position = gl_in[i].gl_Position;\n");
549        if (fDesc.fEmitsPointSize) {
550            builder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n");
551        }
552        GrAssert(builder->fGSInputs.count() == builder->fGSOutputs.count());
553        int count = builder->fGSInputs.count();
554        for (int i = 0; i < count; ++i) {
555            builder->gsCodeAppendf("\t\t%s = %s[i];\n",
556                                   builder->fGSOutputs[i].getName().c_str(),
557                                   builder->fGSInputs[i].getName().c_str());
558        }
559        builder->gsCodeAppend("\t\tEmitVertex();\n"
560                              "\t}\n"
561                              "\tEndPrimitive();\n");
562    }
563#endif
564}
565
566const char* GrGLProgram::adjustInColor(const SkString& inColor) const {
567    if (inColor.size()) {
568          return inColor.c_str();
569    } else {
570        if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) {
571            return GrGLSLOnesVecf(4);
572        } else {
573            return GrGLSLZerosVecf(4);
574        }
575    }
576}
577
578namespace {
579// prints a shader using params similar to glShaderSource
580void print_shader(GrGLint stringCnt,
581                  const GrGLchar** strings,
582                  GrGLint* stringLengths) {
583    for (int i = 0; i < stringCnt; ++i) {
584        if (NULL == stringLengths || stringLengths[i] < 0) {
585            GrPrintf(strings[i]);
586        } else {
587            GrPrintf("%.*s", stringLengths[i], strings[i]);
588        }
589    }
590}
591
592// Compiles a GL shader, returns shader ID or 0 if failed params have same meaning as glShaderSource
593GrGLuint compile_shader(const GrGLContext& gl,
594                        GrGLenum type,
595                        int stringCnt,
596                        const char** strings,
597                        int* stringLengths) {
598    SK_TRACE_EVENT1("GrGLProgram::CompileShader",
599                    "stringCount", SkStringPrintf("%i", stringCnt).c_str());
600
601    GrGLuint shader;
602    GR_GL_CALL_RET(gl.interface(), shader, CreateShader(type));
603    if (0 == shader) {
604        return 0;
605    }
606
607    const GrGLInterface* gli = gl.interface();
608    GrGLint compiled = GR_GL_INIT_ZERO;
609    GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths));
610    GR_GL_CALL(gli, CompileShader(shader));
611    GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled));
612
613    if (!compiled) {
614        GrGLint infoLen = GR_GL_INIT_ZERO;
615        GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen));
616        SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
617        if (infoLen > 0) {
618            // retrieve length even though we don't need it to workaround bug in chrome cmd buffer
619            // param validation.
620            GrGLsizei length = GR_GL_INIT_ZERO;
621            GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1,
622                                             &length, (char*)log.get()));
623            print_shader(stringCnt, strings, stringLengths);
624            GrPrintf("\n%s", log.get());
625        }
626        GrAssert(!"Shader compilation failed!");
627        GR_GL_CALL(gli, DeleteShader(shader));
628        return 0;
629    }
630    return shader;
631}
632
633// helper version of above for when shader is already flattened into a single SkString
634GrGLuint compile_shader(const GrGLContext& gl, GrGLenum type, const SkString& shader) {
635    const GrGLchar* str = shader.c_str();
636    int length = shader.size();
637    return compile_shader(gl, type, 1, &str, &length);
638}
639
640}
641
642// compiles all the shaders from builder and stores the shader IDs
643bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) {
644
645    SkString shader;
646
647    builder.getShader(GrGLShaderBuilder::kVertex_ShaderType, &shader);
648    if (c_PrintShaders) {
649        GrPrintf(shader.c_str());
650        GrPrintf("\n");
651    }
652
653    if (!(fVShaderID = compile_shader(fContext, GR_GL_VERTEX_SHADER, shader))) {
654        return false;
655    }
656
657    if (builder.fUsesGS) {
658        builder.getShader(GrGLShaderBuilder::kGeometry_ShaderType, &shader);
659        if (c_PrintShaders) {
660            GrPrintf(shader.c_str());
661            GrPrintf("\n");
662        }
663        if (!(fGShaderID = compile_shader(fContext, GR_GL_GEOMETRY_SHADER, shader))) {
664            return false;
665        }
666    } else {
667        fGShaderID = 0;
668    }
669
670    builder.getShader(GrGLShaderBuilder::kFragment_ShaderType, &shader);
671    if (c_PrintShaders) {
672        GrPrintf(shader.c_str());
673        GrPrintf("\n");
674    }
675    if (!(fFShaderID = compile_shader(fContext, GR_GL_FRAGMENT_SHADER, shader))) {
676        return false;
677    }
678
679    return true;
680}
681
682bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
683    GrAssert(0 == fProgramID);
684
685    const GrAttribBindings& attribBindings = fDesc.fAttribBindings;
686    bool hasExplicitLocalCoords =
687        SkToBool(attribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
688    GrGLShaderBuilder builder(fContext.info(), fUniformManager, hasExplicitLocalCoords);
689
690#if GR_GL_EXPERIMENTAL_GS
691    builder.fUsesGS = fDesc.fExperimentalGS;
692#endif
693
694    SkXfermode::Coeff colorCoeff, uniformCoeff;
695    // The rest of transfer mode color filters have not been implemented
696    if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) {
697        GR_DEBUGCODE(bool success =)
698            SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>
699                                    (fDesc.fColorFilterXfermode),
700                                    &uniformCoeff, &colorCoeff);
701        GR_DEBUGASSERT(success);
702    } else {
703        colorCoeff = SkXfermode::kOne_Coeff;
704        uniformCoeff = SkXfermode::kZero_Coeff;
705    }
706
707    // no need to do the color filter if coverage is 0. The output color is scaled by the coverage.
708    // All the dual source outputs are scaled by the coverage as well.
709    if (Desc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
710        colorCoeff = SkXfermode::kZero_Coeff;
711        uniformCoeff = SkXfermode::kZero_Coeff;
712    }
713
714    // If we know the final color is going to be all zeros then we can
715    // simplify the color filter coefficients. needComputedColor will then
716    // come out false below.
717    if (Desc::kTransBlack_ColorInput == fDesc.fColorInput) {
718        colorCoeff = SkXfermode::kZero_Coeff;
719        if (SkXfermode::kDC_Coeff == uniformCoeff ||
720            SkXfermode::kDA_Coeff == uniformCoeff) {
721            uniformCoeff = SkXfermode::kZero_Coeff;
722        } else if (SkXfermode::kIDC_Coeff == uniformCoeff ||
723                   SkXfermode::kIDA_Coeff == uniformCoeff) {
724            uniformCoeff = SkXfermode::kOne_Coeff;
725        }
726    }
727
728    bool needColorFilterUniform;
729    bool needComputedColor;
730    need_blend_inputs(uniformCoeff, colorCoeff,
731                      &needColorFilterUniform, &needComputedColor);
732
733    // the dual source output has no canonical var name, have to
734    // declare an output, which is incompatible with gl_FragColor/gl_FragData.
735    bool dualSourceOutputWritten = false;
736    builder.fHeader.append(GrGetGLSLVersionDecl(fContext.info().binding(),
737                                                fContext.info().glslGeneration()));
738
739    GrGLShaderVar colorOutput;
740    bool isColorDeclared = GrGLSLSetupFSColorOuput(fContext.info().glslGeneration(),
741                                                   declared_color_output_name(),
742                                                   &colorOutput);
743    if (isColorDeclared) {
744        builder.fFSOutputs.push_back(colorOutput);
745    }
746
747    const char* viewMName;
748    fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType,
749                                                        kMat33f_GrSLType, "ViewM", &viewMName);
750
751
752    builder.vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n"
753                          "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n",
754                          viewMName, builder.positionAttribute().getName().c_str());
755
756    // incoming color to current stage being processed.
757    SkString inColor;
758
759    if (needComputedColor) {
760        this->genInputColor(&builder, &inColor);
761    }
762
763    // we output point size in the GS if present
764    if (fDesc.fEmitsPointSize && !builder.fUsesGS){
765        builder.vsCodeAppend("\tgl_PointSize = 1.0;\n");
766    }
767
768    ///////////////////////////////////////////////////////////////////////////
769    // compute the final color
770
771    // if we have color stages string them together, feeding the output color
772    // of each to the next and generating code for each stage.
773    if (needComputedColor) {
774        SkString outColor;
775        for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) {
776            if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) {
777                // create var to hold stage result
778                outColor = "color";
779                outColor.appendS32(s);
780                builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
781
782                builder.setCurrentStage(s);
783                fEffects[s] = builder.createAndEmitGLEffect(*stages[s],
784                                                            fDesc.fEffectKeys[s],
785                                                            inColor.size() ? inColor.c_str() : NULL,
786                                                            outColor.c_str(),
787                                                            &fUniformHandles.fSamplerUnis[s]);
788                builder.setNonStage();
789                inColor = outColor;
790            }
791        }
792    }
793
794    // if have all ones or zeros for the "dst" input to the color filter then we
795    // may be able to make additional optimizations.
796    if (needColorFilterUniform && needComputedColor && !inColor.size()) {
797        GrAssert(Desc::kSolidWhite_ColorInput == fDesc.fColorInput);
798        bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff ||
799                                  SkXfermode::kIDA_Coeff == uniformCoeff;
800        if (uniformCoeffIsZero) {
801            uniformCoeff = SkXfermode::kZero_Coeff;
802            bool bogus;
803            need_blend_inputs(SkXfermode::kZero_Coeff, colorCoeff,
804                              &needColorFilterUniform, &bogus);
805        }
806    }
807    const char* colorFilterColorUniName = NULL;
808    if (needColorFilterUniform) {
809        fUniformHandles.fColorFilterUni = builder.addUniform(
810                                                        GrGLShaderBuilder::kFragment_ShaderType,
811                                                        kVec4f_GrSLType, "FilterColor",
812                                                        &colorFilterColorUniName);
813    }
814    bool wroteFragColorZero = false;
815    if (SkXfermode::kZero_Coeff == uniformCoeff &&
816        SkXfermode::kZero_Coeff == colorCoeff) {
817        builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4));
818        wroteFragColorZero = true;
819    } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) {
820        builder.fsCodeAppend("\tvec4 filteredColor;\n");
821        const char* color = adjustInColor(inColor);
822        add_color_filter(&builder, "filteredColor", uniformCoeff,
823                         colorCoeff, colorFilterColorUniName, color);
824        inColor = "filteredColor";
825    }
826
827    ///////////////////////////////////////////////////////////////////////////
828    // compute the partial coverage (coverage stages and edge aa)
829
830    SkString inCoverage;
831    bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput;
832    // we don't need to compute coverage at all if we know the final shader
833    // output will be zero and we don't have a dual src blend output.
834    if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
835
836        if (!coverageIsZero) {
837            bool inCoverageIsScalar  = this->genEdgeCoverage(&inCoverage, &builder);
838
839            switch (fDesc.fCoverageInput) {
840                case Desc::kSolidWhite_ColorInput:
841                    // empty string implies solid white
842                    break;
843                case Desc::kAttribute_ColorInput:
844                    gen_attribute_coverage(&builder, &inCoverage);
845                    inCoverageIsScalar = false;
846                    break;
847                case Desc::kUniform_ColorInput:
848                    this->genUniformCoverage(&builder, &inCoverage);
849                    inCoverageIsScalar = false;
850                    break;
851                default:
852                    GrCrash("Unexpected input coverage.");
853            }
854
855            SkString outCoverage;
856            const int& startStage = fDesc.fFirstCoverageStage;
857            for (int s = startStage; s < GrDrawState::kNumStages; ++s) {
858                if (fDesc.fEffectKeys[s]) {
859                    // create var to hold stage output
860                    outCoverage = "coverage";
861                    outCoverage.appendS32(s);
862                    builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str());
863
864                    // stages don't know how to deal with a scalar input. (Maybe they should. We
865                    // could pass a GrGLShaderVar)
866                    if (inCoverageIsScalar) {
867                        builder.fsCodeAppendf("\tvec4 %s4 = vec4(%s);\n",
868                                              inCoverage.c_str(), inCoverage.c_str());
869                        inCoverage.append("4");
870                    }
871                    builder.setCurrentStage(s);
872                    fEffects[s] = builder.createAndEmitGLEffect(
873                                                    *stages[s],
874                                                    fDesc.fEffectKeys[s],
875                                                    inCoverage.size() ? inCoverage.c_str() : NULL,
876                                                    outCoverage.c_str(),
877                                                    &fUniformHandles.fSamplerUnis[s]);
878                    builder.setNonStage();
879                    inCoverage = outCoverage;
880                }
881            }
882
883            // discard if coverage is zero
884            if (fDesc.fDiscardIfOutsideEdge && !outCoverage.isEmpty()) {
885                builder.fsCodeAppendf(
886                    "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n",
887                    outCoverage.c_str());
888            }
889        }
890
891        if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
892            builder.fFSOutputs.push_back().set(kVec4f_GrSLType,
893                                               GrGLShaderVar::kOut_TypeModifier,
894                                               dual_source_output_name());
895            bool outputIsZero = coverageIsZero;
896            SkString coeff;
897            if (!outputIsZero &&
898                Desc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) {
899                if (!inColor.size()) {
900                    outputIsZero = true;
901                } else {
902                    if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
903                        coeff.printf("(1 - %s.a)", inColor.c_str());
904                    } else {
905                        coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str());
906                    }
907                }
908            }
909            if (outputIsZero) {
910                builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), GrGLSLZerosVecf(4));
911            } else {
912                SkString modulate;
913                GrGLSLModulate4f(&modulate, coeff.c_str(), inCoverage.c_str());
914                builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str());
915            }
916            dualSourceOutputWritten = true;
917        }
918    }
919
920    ///////////////////////////////////////////////////////////////////////////
921    // combine color and coverage as frag color
922
923    if (!wroteFragColorZero) {
924        if (coverageIsZero) {
925            builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4));
926        } else {
927            SkString modulate;
928            GrGLSLModulate4f(&modulate, inColor.c_str(), inCoverage.c_str());
929            builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulate.c_str());
930        }
931    }
932
933    ///////////////////////////////////////////////////////////////////////////
934    // insert GS
935#if GR_DEBUG
936    this->genGeometryShader(&builder);
937#endif
938
939    ///////////////////////////////////////////////////////////////////////////
940    // compile and setup attribs and unis
941
942    if (!this->compileShaders(builder)) {
943        return false;
944    }
945
946    if (!this->bindOutputsAttribsAndLinkProgram(builder,
947                                                isColorDeclared,
948                                                dualSourceOutputWritten)) {
949        return false;
950    }
951
952    builder.finished(fProgramID);
953    this->initSamplerUniforms();
954    fUniformHandles.fRTHeightUni = builder.getRTHeightUniform();
955
956    return true;
957}
958
959bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
960                                                   bool bindColorOut,
961                                                   bool bindDualSrcOut) {
962    GL_CALL_RET(fProgramID, CreateProgram());
963    if (!fProgramID) {
964        return false;
965    }
966
967    GL_CALL(AttachShader(fProgramID, fVShaderID));
968    if (fGShaderID) {
969        GL_CALL(AttachShader(fProgramID, fGShaderID));
970    }
971    GL_CALL(AttachShader(fProgramID, fFShaderID));
972
973    if (bindColorOut) {
974        GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()));
975    }
976    if (bindDualSrcOut) {
977        GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name()));
978    }
979
980    // Bind the attrib locations to same values for all shaders
981    GL_CALL(BindAttribLocation(fProgramID,
982                               fDesc.fPositionAttributeIndex,
983                               builder.positionAttribute().c_str()));
984    GL_CALL(BindAttribLocation(fProgramID, fDesc.fColorAttributeIndex, COL_ATTR_NAME));
985    GL_CALL(BindAttribLocation(fProgramID, fDesc.fCoverageAttributeIndex, COV_ATTR_NAME));
986
987    if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) {
988        GL_CALL(BindAttribLocation(fProgramID, fDesc.fEdgeAttributeIndex, EDGE_ATTR_NAME));
989    }
990    if (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
991        GL_CALL(BindAttribLocation(fProgramID,
992                                   fDesc.fLocalCoordsAttributeIndex,
993                                   builder.localCoordsAttribute().c_str()));
994    }
995
996    const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end();
997    for (const GrGLShaderBuilder::AttributePair* attrib = builder.getEffectAttributes().begin();
998         attrib != attribEnd;
999         ++attrib) {
1000         GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fName.c_str()));
1001    }
1002
1003    GL_CALL(LinkProgram(fProgramID));
1004
1005    GrGLint linked = GR_GL_INIT_ZERO;
1006    GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
1007    if (!linked) {
1008        GrGLint infoLen = GR_GL_INIT_ZERO;
1009        GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
1010        SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
1011        if (infoLen > 0) {
1012            // retrieve length even though we don't need it to workaround
1013            // bug in chrome cmd buffer param validation.
1014            GrGLsizei length = GR_GL_INIT_ZERO;
1015            GL_CALL(GetProgramInfoLog(fProgramID,
1016                                      infoLen+1,
1017                                      &length,
1018                                      (char*)log.get()));
1019            GrPrintf((char*)log.get());
1020        }
1021        GrAssert(!"Error linking program");
1022        GL_CALL(DeleteProgram(fProgramID));
1023        fProgramID = 0;
1024        return false;
1025    }
1026    return true;
1027}
1028
1029void GrGLProgram::initSamplerUniforms() {
1030    GL_CALL(UseProgram(fProgramID));
1031    // We simply bind the uniforms to successive texture units beginning at 0. setData() assumes this
1032    // behavior.
1033    GrGLint texUnitIdx = 0;
1034    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
1035        int numSamplers = fUniformHandles.fSamplerUnis[s].count();
1036        for (int u = 0; u < numSamplers; ++u) {
1037            UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
1038            if (GrGLUniformManager::kInvalidUniformHandle != handle) {
1039                fUniformManager.setSampler(handle, texUnitIdx);
1040                ++texUnitIdx;
1041            }
1042        }
1043    }
1044}
1045
1046///////////////////////////////////////////////////////////////////////////////
1047
1048void GrGLProgram::setData(GrGpuGL* gpu,
1049                          GrColor color,
1050                          GrColor coverage,
1051                          SharedGLState* sharedState) {
1052    const GrDrawState& drawState = gpu->getDrawState();
1053
1054    this->setColor(drawState, color, sharedState);
1055    this->setCoverage(drawState, coverage, sharedState);
1056    this->setMatrixAndRenderTargetHeight(drawState);
1057
1058    // Setup the SkXfermode::Mode-based colorfilter uniform if necessary
1059    if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fColorFilterUni &&
1060        fColorFilterColor != drawState.getColorFilterColor()) {
1061        GrGLfloat c[4];
1062        GrColorToRGBAFloat(drawState.getColorFilterColor(), c);
1063        fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c);
1064        fColorFilterColor = drawState.getColorFilterColor();
1065    }
1066
1067    GrGLint texUnitIdx = 0;
1068    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
1069        if (NULL != fEffects[s]) {
1070            const GrEffectStage& stage = drawState.getStage(s);
1071            GrAssert(NULL != stage.getEffect());
1072
1073            bool explicitLocalCoords =
1074                (fDesc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit);
1075            GrDrawEffect drawEffect(stage, explicitLocalCoords);
1076            fEffects[s]->setData(fUniformManager, drawEffect);
1077            int numSamplers = fUniformHandles.fSamplerUnis[s].count();
1078            for (int u = 0; u < numSamplers; ++u) {
1079                UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
1080                if (GrGLUniformManager::kInvalidUniformHandle != handle) {
1081                    const GrTextureAccess& access = (*stage.getEffect())->textureAccess(u);
1082                    GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture());
1083                    gpu->bindTexture(texUnitIdx, access.getParams(), texture);
1084                    ++texUnitIdx;
1085                }
1086            }
1087        }
1088    }
1089}
1090
1091void GrGLProgram::setColor(const GrDrawState& drawState,
1092                           GrColor color,
1093                           SharedGLState* sharedState) {
1094    if (!(drawState.getAttribBindings() & GrDrawState::kColor_AttribBindingsBit)) {
1095        switch (fDesc.fColorInput) {
1096            case GrGLProgram::Desc::kAttribute_ColorInput:
1097                if (sharedState->fConstAttribColor != color) {
1098                    // OpenGL ES only supports the float varieties of glVertexAttrib
1099                    GrGLfloat c[4];
1100                    GrColorToRGBAFloat(color, c);
1101                    GL_CALL(VertexAttrib4fv(fDesc.fColorAttributeIndex, c));
1102                    sharedState->fConstAttribColor = color;
1103                }
1104                break;
1105            case GrGLProgram::Desc::kUniform_ColorInput:
1106                if (fColor != color) {
1107                    // OpenGL ES doesn't support unsigned byte varieties of glUniform
1108                    GrGLfloat c[4];
1109                    GrColorToRGBAFloat(color, c);
1110                    GrAssert(GrGLUniformManager::kInvalidUniformHandle !=
1111                             fUniformHandles.fColorUni);
1112                    fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c);
1113                    fColor = color;
1114                }
1115                break;
1116            case GrGLProgram::Desc::kSolidWhite_ColorInput:
1117            case GrGLProgram::Desc::kTransBlack_ColorInput:
1118                break;
1119            default:
1120                GrCrash("Unknown color type.");
1121        }
1122    }
1123}
1124
1125void GrGLProgram::setCoverage(const GrDrawState& drawState,
1126                              GrColor coverage,
1127                              SharedGLState* sharedState) {
1128    if (!(drawState.getAttribBindings() & GrDrawState::kCoverage_AttribBindingsBit)) {
1129        switch (fDesc.fCoverageInput) {
1130            case Desc::kAttribute_ColorInput:
1131                if (sharedState->fConstAttribCoverage != coverage) {
1132                    // OpenGL ES only supports the float varieties of  glVertexAttrib
1133                    GrGLfloat c[4];
1134                    GrColorToRGBAFloat(coverage, c);
1135                    GL_CALL(VertexAttrib4fv(fDesc.fCoverageAttributeIndex, c));
1136                    sharedState->fConstAttribCoverage = coverage;
1137                }
1138                break;
1139            case Desc::kUniform_ColorInput:
1140                if (fCoverage != coverage) {
1141                    // OpenGL ES doesn't support unsigned byte varieties of glUniform
1142                    GrGLfloat c[4];
1143                    GrColorToRGBAFloat(coverage, c);
1144                    GrAssert(GrGLUniformManager::kInvalidUniformHandle !=
1145                             fUniformHandles.fCoverageUni);
1146                    fUniformManager.set4fv(fUniformHandles.fCoverageUni, 0, 1, c);
1147                    fCoverage = coverage;
1148                }
1149                break;
1150            case Desc::kSolidWhite_ColorInput:
1151            case Desc::kTransBlack_ColorInput:
1152                break;
1153            default:
1154                GrCrash("Unknown coverage type.");
1155        }
1156    }
1157}
1158
1159void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
1160    const GrRenderTarget* rt = drawState.getRenderTarget();
1161    SkISize size;
1162    size.set(rt->width(), rt->height());
1163
1164    // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
1165    if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni &&
1166        fMatrixState.fRenderTargetSize.fHeight != size.fHeight) {
1167        fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight));
1168    }
1169
1170    if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
1171        !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) ||
1172        fMatrixState.fRenderTargetSize != size) {
1173        SkMatrix m;
1174        if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
1175            m.setAll(
1176                SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1,
1177                0,-SkIntToScalar(2) / size.fHeight, SK_Scalar1,
1178            0, 0, SkMatrix::I()[8]);
1179        } else {
1180            m.setAll(
1181                SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1,
1182                0, SkIntToScalar(2) / size.fHeight,-SK_Scalar1,
1183            0, 0, SkMatrix::I()[8]);
1184        }
1185        m.setConcat(m, drawState.getViewMatrix());
1186
1187        // ES doesn't allow you to pass true to the transpose param so we do our own transpose.
1188        GrGLfloat mt[]  = {
1189            SkScalarToFloat(m[SkMatrix::kMScaleX]),
1190            SkScalarToFloat(m[SkMatrix::kMSkewY]),
1191            SkScalarToFloat(m[SkMatrix::kMPersp0]),
1192            SkScalarToFloat(m[SkMatrix::kMSkewX]),
1193            SkScalarToFloat(m[SkMatrix::kMScaleY]),
1194            SkScalarToFloat(m[SkMatrix::kMPersp1]),
1195            SkScalarToFloat(m[SkMatrix::kMTransX]),
1196            SkScalarToFloat(m[SkMatrix::kMTransY]),
1197            SkScalarToFloat(m[SkMatrix::kMPersp2])
1198        };
1199        fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt);
1200        fMatrixState.fViewMatrix = drawState.getViewMatrix();
1201        fMatrixState.fRenderTargetSize = size;
1202        fMatrixState.fRenderTargetOrigin = rt->origin();
1203    }
1204}
1205