GrGLProgram.cpp revision 949eef0af2f5b47000e637347801cf2970092a38
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 "GrGLSL.h"
17#include "SkXfermode.h"
18
19SK_DEFINE_INST_COUNT(GrGLProgram)
20
21#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
22#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X)
23
24GrGLProgram* GrGLProgram::Create(GrGpuGL* gpu,
25                                 const GrGLProgramDesc& desc,
26                                 const GrEffectStage* colorStages[],
27                                 const GrEffectStage* coverageStages[]) {
28    GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gpu, desc, colorStages, coverageStages));
29    if (!program->succeeded()) {
30        delete program;
31        program = NULL;
32    }
33    return program;
34}
35
36GrGLProgram::GrGLProgram(GrGpuGL* gpu,
37                         const GrGLProgramDesc& desc,
38                         const GrEffectStage* colorStages[],
39                         const GrEffectStage* coverageStages[])
40: fGpu(gpu)
41, fUniformManager(gpu) {
42    fDesc = desc;
43    fProgramID = 0;
44
45    fDstCopyTexUnit = -1;
46
47    fColor = GrColor_ILLEGAL;
48    fColorFilterColor = GrColor_ILLEGAL;
49
50    fColorEffects.reset(desc.numColorEffects());
51    fCoverageEffects.reset(desc.numCoverageEffects());
52
53    this->genProgram(colorStages, coverageStages);
54}
55
56GrGLProgram::~GrGLProgram() {
57    if (fProgramID) {
58        GL_CALL(DeleteProgram(fProgramID));
59    }
60}
61
62void GrGLProgram::abandon() {
63    fProgramID = 0;
64}
65
66void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
67                                GrBlendCoeff* dstCoeff) const {
68    switch (fDesc.getHeader().fCoverageOutput) {
69        case GrGLProgramDesc::kModulate_CoverageOutput:
70            break;
71        // The prog will write a coverage value to the secondary
72        // output and the dst is blended by one minus that value.
73        case GrGLProgramDesc::kSecondaryCoverage_CoverageOutput:
74        case GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput:
75        case GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput:
76            *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
77            break;
78        case GrGLProgramDesc::kCombineWithDst_CoverageOutput:
79            // We should only have set this if the blend was specified as (1, 0)
80            SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *dstCoeff);
81            break;
82        default:
83            GrCrash("Unexpected coverage output");
84            break;
85    }
86}
87
88namespace {
89// given two blend coefficients determine whether the src
90// and/or dst computation can be omitted.
91inline void need_blend_inputs(SkXfermode::Coeff srcCoeff,
92                              SkXfermode::Coeff dstCoeff,
93                              bool* needSrcValue,
94                              bool* needDstValue) {
95    if (SkXfermode::kZero_Coeff == srcCoeff) {
96        switch (dstCoeff) {
97            // these all read the src
98            case SkXfermode::kSC_Coeff:
99            case SkXfermode::kISC_Coeff:
100            case SkXfermode::kSA_Coeff:
101            case SkXfermode::kISA_Coeff:
102                *needSrcValue = true;
103                break;
104            default:
105                *needSrcValue = false;
106                break;
107        }
108    } else {
109        *needSrcValue = true;
110    }
111    if (SkXfermode::kZero_Coeff == dstCoeff) {
112        switch (srcCoeff) {
113            // these all read the dst
114            case SkXfermode::kDC_Coeff:
115            case SkXfermode::kIDC_Coeff:
116            case SkXfermode::kDA_Coeff:
117            case SkXfermode::kIDA_Coeff:
118                *needDstValue = true;
119                break;
120            default:
121                *needDstValue = false;
122                break;
123        }
124    } else {
125        *needDstValue = true;
126    }
127}
128
129/**
130 * Create a blend_coeff * value string to be used in shader code. Sets empty
131 * string if result is trivially zero.
132 */
133inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff,
134                       const char* src, const char* dst,
135                       const char* value) {
136    switch (coeff) {
137    case SkXfermode::kZero_Coeff:    /** 0 */
138        *str = "";
139        break;
140    case SkXfermode::kOne_Coeff:     /** 1 */
141        *str = value;
142        break;
143    case SkXfermode::kSC_Coeff:
144        str->printf("(%s * %s)", src, value);
145        break;
146    case SkXfermode::kISC_Coeff:
147        str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value);
148        break;
149    case SkXfermode::kDC_Coeff:
150        str->printf("(%s * %s)", dst, value);
151        break;
152    case SkXfermode::kIDC_Coeff:
153        str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value);
154        break;
155    case SkXfermode::kSA_Coeff:      /** src alpha */
156        str->printf("(%s.a * %s)", src, value);
157        break;
158    case SkXfermode::kISA_Coeff:     /** inverse src alpha (i.e. 1 - sa) */
159        str->printf("((1.0 - %s.a) * %s)", src, value);
160        break;
161    case SkXfermode::kDA_Coeff:      /** dst alpha */
162        str->printf("(%s.a * %s)", dst, value);
163        break;
164    case SkXfermode::kIDA_Coeff:     /** inverse dst alpha (i.e. 1 - da) */
165        str->printf("((1.0 - %s.a) * %s)", dst, value);
166        break;
167    default:
168        GrCrash("Unexpected xfer coeff.");
169        break;
170    }
171}
172/**
173 * Adds a line to the fragment shader code which modifies the color by
174 * the specified color filter.
175 */
176void add_color_filter(GrGLShaderBuilder* builder,
177                      const char * outputVar,
178                      SkXfermode::Coeff uniformCoeff,
179                      SkXfermode::Coeff colorCoeff,
180                      const char* filterColor,
181                      const char* inColor) {
182    SkString colorStr, constStr;
183    blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor);
184    blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor);
185
186    SkString sum;
187    GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str());
188    builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str());
189}
190}
191
192namespace {
193
194void expand_known_value4f(SkString* string, GrSLConstantVec vec) {
195    SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec));
196    switch (vec) {
197        case kNone_GrSLConstantVec:
198            break;
199        case kZeros_GrSLConstantVec:
200            *string = GrGLSLZerosVecf(4);
201            break;
202        case kOnes_GrSLConstantVec:
203            *string = GrGLSLOnesVecf(4);
204            break;
205    }
206}
207
208}
209
210bool GrGLProgram::genProgram(const GrEffectStage* colorStages[],
211                             const GrEffectStage* coverageStages[]) {
212    SkASSERT(0 == fProgramID);
213
214    const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
215
216    bool needsVertexShader = true;
217
218    GrGLShaderBuilder builder(fGpu, fUniformManager, fDesc, needsVertexShader);
219    if (GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder.getVertexBuilder()) {
220        fUniformHandles.fViewMatrixUni = vertexBuilder->getViewMatrixUniform();
221    }
222
223    // incoming color to current stage being processed.
224    SkString inColor = builder.getInputColor();
225    GrSLConstantVec knownColorValue = builder.getKnownColorValue();
226
227    // Get the coeffs for the Mode-based color filter, determine if color is needed.
228    SkXfermode::Coeff colorCoeff;
229    SkXfermode::Coeff filterColorCoeff;
230    SkAssertResult(
231        SkXfermode::ModeAsCoeff(header.fColorFilterXfermode,
232                                &filterColorCoeff,
233                                &colorCoeff));
234    bool needColor, needFilterColor;
235    need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor);
236
237    // used in order for builder to return the per-stage uniform handles.
238    typedef SkTArray<GrGLUniformManager::UniformHandle, true>* UniHandleArrayPtr;
239    int maxColorOrCovEffectCnt = GrMax(fDesc.numColorEffects(), fDesc.numCoverageEffects());
240    SkAutoTArray<UniHandleArrayPtr> effectUniformArrays(maxColorOrCovEffectCnt);
241    SkAutoTArray<GrGLEffect*> glEffects(maxColorOrCovEffectCnt);
242
243    if (needColor) {
244        for (int e = 0; e < fDesc.numColorEffects(); ++e) {
245            effectUniformArrays[e] = &fColorEffects[e].fSamplerUnis;
246        }
247
248        builder.emitEffects(colorStages,
249                            fDesc.effectKeys(),
250                            fDesc.numColorEffects(),
251                            &inColor,
252                            &knownColorValue,
253                            effectUniformArrays.get(),
254                            glEffects.get());
255
256        for (int e = 0; e < fDesc.numColorEffects(); ++e) {
257            fColorEffects[e].fGLEffect = glEffects[e];
258        }
259    }
260
261    // Insert the color filter. This will soon be replaced by a color effect.
262    if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) {
263        const char* colorFilterColorUniName = NULL;
264        fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder::kFragment_Visibility,
265                                                             kVec4f_GrSLType, "FilterColor",
266                                                             &colorFilterColorUniName);
267
268        builder.fsCodeAppend("\tvec4 filteredColor;\n");
269        const char* color;
270        // add_color_filter requires a real input string.
271        if (knownColorValue == kOnes_GrSLConstantVec) {
272            color = GrGLSLOnesVecf(4);
273        } else if (knownColorValue == kZeros_GrSLConstantVec) {
274            color = GrGLSLZerosVecf(4);
275        } else {
276            color = inColor.c_str();
277        }
278        add_color_filter(&builder, "filteredColor", filterColorCoeff,
279                         colorCoeff, colorFilterColorUniName, color);
280        inColor = "filteredColor";
281    }
282
283    ///////////////////////////////////////////////////////////////////////////
284    // compute the partial coverage
285    SkString inCoverage = builder.getInputCoverage();
286    GrSLConstantVec knownCoverageValue = builder.getKnownCoverageValue();
287
288    for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
289        effectUniformArrays[e] = &fCoverageEffects[e].fSamplerUnis;
290    }
291
292    builder.emitEffects(coverageStages,
293                        fDesc.getEffectKeys() + fDesc.numColorEffects(),
294                        fDesc.numCoverageEffects(),
295                        &inCoverage,
296                        &knownCoverageValue,
297                        effectUniformArrays.get(),
298                        glEffects.get());
299    for (int e = 0; e < fDesc.numCoverageEffects(); ++e) {
300        fCoverageEffects[e].fGLEffect = glEffects[e];
301    }
302
303    // discard if coverage is zero
304    if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageValue) {
305        if (kZeros_GrSLConstantVec == knownCoverageValue) {
306            // This is unfortunate.
307            builder.fsCodeAppend("\tdiscard;\n");
308        } else {
309            builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n",
310                                  inCoverage.c_str());
311        }
312    }
313
314    if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
315        const char* secondaryOutputName = builder.enableSecondaryOutput();
316
317        // default coeff to ones for kCoverage_DualSrcOutput
318        SkString coeff;
319        GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec;
320        if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
321            // Get (1-A) into coeff
322            SkString inColorAlpha;
323            GrGLSLGetComponent4f(&inColorAlpha,
324                                    inColor.c_str(),
325                                    kA_GrColorComponentFlag,
326                                    knownColorValue,
327                                    true);
328            knownCoeffValue = GrGLSLSubtractf<1>(&coeff,
329                                                 NULL,
330                                                 inColorAlpha.c_str(),
331                                                 kOnes_GrSLConstantVec,
332                                                 knownColorValue,
333                                                 true);
334        } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == header.fCoverageOutput) {
335            // Get (1-RGBA) into coeff
336            knownCoeffValue = GrGLSLSubtractf<4>(&coeff,
337                                                 NULL,
338                                                 inColor.c_str(),
339                                                 kOnes_GrSLConstantVec,
340                                                 knownColorValue,
341                                                 true);
342        }
343        // Get coeff * coverage into modulate and then write that to the dual source output.
344        SkString modulate;
345        GrGLSLModulatef<4>(&modulate,
346                           coeff.c_str(),
347                           inCoverage.c_str(),
348                           knownCoeffValue,
349                           knownCoverageValue,
350                           false);
351        builder.fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_str());
352    }
353
354    ///////////////////////////////////////////////////////////////////////////
355    // combine color and coverage as frag color
356
357    // Get "color * coverage" into fragColor
358    SkString fragColor;
359    GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor,
360                                                             inColor.c_str(),
361                                                             inCoverage.c_str(),
362                                                             knownColorValue,
363                                                             knownCoverageValue,
364                                                             true);
365    // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
366    if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
367        SkString dstCoeff;
368        GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff,
369                                                                NULL,
370                                                                inCoverage.c_str(),
371                                                                kOnes_GrSLConstantVec,
372                                                                knownCoverageValue,
373                                                                true);
374        SkString dstContribution;
375        GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContribution,
376                                                                       dstCoeff.c_str(),
377                                                                       builder.dstColor(),
378                                                                       knownDstCoeffValue,
379                                                                       kNone_GrSLConstantVec,
380                                                                       true);
381        SkString oldFragColor = fragColor;
382        fragColor.reset();
383        GrGLSLAddf<4>(&fragColor,
384                      oldFragColor.c_str(),
385                      dstContribution.c_str(),
386                      knownFragColorValue,
387                      knownDstContributionValue,
388                      false);
389    } else {
390        expand_known_value4f(&fragColor, knownFragColorValue);
391    }
392    builder.fsCodeAppendf("\t%s = %s;\n", builder.getColorOutputName(), fragColor.c_str());
393
394    if (!builder.finish(&fProgramID)) {
395        return false;
396    }
397
398    fUniformHandles.fRTHeightUni = builder.getRTHeightUniform();
399    fUniformHandles.fDstCopyTopLeftUni = builder.getDstCopyTopLeftUniform();
400    fUniformHandles.fDstCopyScaleUni = builder.getDstCopyScaleUniform();
401    fUniformHandles.fColorUni = builder.getColorUniform();
402    fUniformHandles.fCoverageUni = builder.getCoverageUniform();
403    fUniformHandles.fDstCopySamplerUni = builder.getDstCopySamplerUniform();
404    // This must be called after we set fDstCopySamplerUni above.
405    this->initSamplerUniforms();
406
407    return true;
408}
409
410void GrGLProgram::initSamplerUniforms() {
411    GL_CALL(UseProgram(fProgramID));
412    GrGLint texUnitIdx = 0;
413    if (fUniformHandles.fDstCopySamplerUni.isValid()) {
414        fUniformManager.setSampler(fUniformHandles.fDstCopySamplerUni, texUnitIdx);
415        fDstCopyTexUnit = texUnitIdx++;
416    }
417
418    for (int e = 0; e < fColorEffects.count(); ++e) {
419        this->initEffectSamplerUniforms(&fColorEffects[e], &texUnitIdx);
420    }
421
422    for (int e = 0; e < fCoverageEffects.count(); ++e) {
423        this->initEffectSamplerUniforms(&fCoverageEffects[e], &texUnitIdx);
424    }
425}
426
427void GrGLProgram::initEffectSamplerUniforms(EffectAndSamplers* effect, int* texUnitIdx) {
428    int numSamplers = effect->fSamplerUnis.count();
429    effect->fTextureUnits.reset(numSamplers);
430    for (int s = 0; s < numSamplers; ++s) {
431        UniformHandle handle = effect->fSamplerUnis[s];
432        if (handle.isValid()) {
433            fUniformManager.setSampler(handle, *texUnitIdx);
434            effect->fTextureUnits[s] = (*texUnitIdx)++;
435        }
436    }
437}
438
439///////////////////////////////////////////////////////////////////////////////
440
441void GrGLProgram::setEffectData(const GrEffectStage& stage,
442                                const EffectAndSamplers& effect) {
443
444    // Let the GrGLEffect set its data.
445    bool explicitLocalCoords = -1 != fDesc.getHeader().fLocalCoordAttributeIndex;
446    GrDrawEffect drawEffect(stage, explicitLocalCoords);
447    effect.fGLEffect->setData(fUniformManager, drawEffect);
448
449    // Bind the texures for the effect.
450    int numSamplers = effect.fSamplerUnis.count();
451    SkASSERT((*stage.getEffect())->numTextures() == numSamplers);
452    for (int s = 0; s < numSamplers; ++s) {
453        UniformHandle handle = effect.fSamplerUnis[s];
454        if (handle.isValid()) {
455            const GrTextureAccess& access = (*stage.getEffect())->textureAccess(s);
456            GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture());
457            int unit = effect.fTextureUnits[s];
458            fGpu->bindTexture(unit, access.getParams(), texture);
459        }
460    }
461}
462
463void GrGLProgram::setData(GrDrawState::BlendOptFlags blendOpts,
464                          const GrEffectStage* colorStages[],
465                          const GrEffectStage* coverageStages[],
466                          const GrDeviceCoordTexture* dstCopy,
467                          SharedGLState* sharedState) {
468    const GrDrawState& drawState = fGpu->getDrawState();
469
470    GrColor color;
471    GrColor coverage;
472    if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
473        color = 0;
474        coverage = 0;
475    } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
476        color = 0xffffffff;
477        coverage = drawState.getCoverage();
478    } else {
479        color = drawState.getColor();
480        coverage = drawState.getCoverage();
481    }
482
483    this->setColor(drawState, color, sharedState);
484    this->setCoverage(drawState, coverage, sharedState);
485    this->setMatrixAndRenderTargetHeight(drawState);
486
487    // Setup the SkXfermode::Mode-based colorfilter uniform if necessary
488    if (fUniformHandles.fColorFilterUni.isValid() &&
489        fColorFilterColor != drawState.getColorFilterColor()) {
490        GrGLfloat c[4];
491        GrColorToRGBAFloat(drawState.getColorFilterColor(), c);
492        fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c);
493        fColorFilterColor = drawState.getColorFilterColor();
494    }
495
496    if (NULL != dstCopy) {
497        if (fUniformHandles.fDstCopyTopLeftUni.isValid()) {
498            fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni,
499                                  static_cast<GrGLfloat>(dstCopy->offset().fX),
500                                  static_cast<GrGLfloat>(dstCopy->offset().fY));
501            fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni,
502                                  1.f / dstCopy->texture()->width(),
503                                  1.f / dstCopy->texture()->height());
504            GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
505            static GrTextureParams kParams; // the default is clamp, nearest filtering.
506            fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
507        } else {
508            SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
509            SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
510        }
511    } else {
512        SkASSERT(!fUniformHandles.fDstCopyTopLeftUni.isValid());
513        SkASSERT(!fUniformHandles.fDstCopyScaleUni.isValid());
514        SkASSERT(!fUniformHandles.fDstCopySamplerUni.isValid());
515    }
516
517    for (int e = 0; e < fColorEffects.count(); ++e) {
518        // We may have omitted the GrGLEffect because of the color filter logic in genProgram.
519        // This can be removed when the color filter is an effect.
520        if (NULL != fColorEffects[e].fGLEffect) {
521            this->setEffectData(*colorStages[e], fColorEffects[e]);
522        }
523    }
524
525    for (int e = 0; e < fCoverageEffects.count(); ++e) {
526        if (NULL != fCoverageEffects[e].fGLEffect) {
527            this->setEffectData(*coverageStages[e], fCoverageEffects[e]);
528        }
529    }
530}
531
532void GrGLProgram::setColor(const GrDrawState& drawState,
533                           GrColor color,
534                           SharedGLState* sharedState) {
535    const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
536    if (!drawState.hasColorVertexAttribute()) {
537        switch (header.fColorInput) {
538            case GrGLProgramDesc::kAttribute_ColorInput:
539                SkASSERT(-1 != header.fColorAttributeIndex);
540                if (sharedState->fConstAttribColor != color ||
541                    sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) {
542                    // OpenGL ES only supports the float varieties of glVertexAttrib
543                    GrGLfloat c[4];
544                    GrColorToRGBAFloat(color, c);
545                    GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c));
546                    sharedState->fConstAttribColor = color;
547                    sharedState->fConstAttribColorIndex = header.fColorAttributeIndex;
548                }
549                break;
550            case GrGLProgramDesc::kUniform_ColorInput:
551                if (fColor != color) {
552                    // OpenGL ES doesn't support unsigned byte varieties of glUniform
553                    GrGLfloat c[4];
554                    GrColorToRGBAFloat(color, c);
555                    fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c);
556                    fColor = color;
557                }
558                sharedState->fConstAttribColorIndex = -1;
559                break;
560            case GrGLProgramDesc::kSolidWhite_ColorInput:
561            case GrGLProgramDesc::kTransBlack_ColorInput:
562                sharedState->fConstAttribColorIndex = -1;
563                break;
564            default:
565                GrCrash("Unknown color type.");
566        }
567    } else {
568        sharedState->fConstAttribColorIndex = -1;
569    }
570}
571
572void GrGLProgram::setCoverage(const GrDrawState& drawState,
573                              GrColor coverage,
574                              SharedGLState* sharedState) {
575    const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
576    if (!drawState.hasCoverageVertexAttribute()) {
577        switch (header.fCoverageInput) {
578            case GrGLProgramDesc::kAttribute_ColorInput:
579                if (sharedState->fConstAttribCoverage != coverage ||
580                    sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) {
581                    // OpenGL ES only supports the float varieties of  glVertexAttrib
582                    GrGLfloat c[4];
583                    GrColorToRGBAFloat(coverage, c);
584                    GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c));
585                    sharedState->fConstAttribCoverage = coverage;
586                    sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex;
587                }
588                break;
589            case GrGLProgramDesc::kUniform_ColorInput:
590                if (fCoverage != coverage) {
591                    // OpenGL ES doesn't support unsigned byte varieties of glUniform
592                    GrGLfloat c[4];
593                    GrColorToRGBAFloat(coverage, c);
594                    fUniformManager.set4fv(fUniformHandles.fCoverageUni, 0, 1, c);
595                    fCoverage = coverage;
596                }
597                sharedState->fConstAttribCoverageIndex = -1;
598                break;
599            case GrGLProgramDesc::kSolidWhite_ColorInput:
600            case GrGLProgramDesc::kTransBlack_ColorInput:
601                sharedState->fConstAttribCoverageIndex = -1;
602                break;
603            default:
604                GrCrash("Unknown coverage type.");
605        }
606    } else {
607        sharedState->fConstAttribCoverageIndex = -1;
608    }
609}
610
611void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) {
612    const GrRenderTarget* rt = drawState.getRenderTarget();
613    SkISize size;
614    size.set(rt->width(), rt->height());
615
616    // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
617    if (fUniformHandles.fRTHeightUni.isValid() &&
618        fMatrixState.fRenderTargetSize.fHeight != size.fHeight) {
619        fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight));
620    }
621
622    if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
623        !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) ||
624        fMatrixState.fRenderTargetSize != size) {
625
626        fMatrixState.fViewMatrix = drawState.getViewMatrix();
627        fMatrixState.fRenderTargetSize = size;
628        fMatrixState.fRenderTargetOrigin = rt->origin();
629
630        GrGLfloat viewMatrix[3 * 3];
631        fMatrixState.getGLMatrix<3>(viewMatrix);
632        fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix);
633    }
634}
635