Home | History | Annotate | Download | only in gl
      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 "GrGLEffect.h"
     13 #include "GrGpuGL.h"
     14 #include "GrGLShaderVar.h"
     15 #include "GrBackendEffectFactory.h"
     16 #include "SkTrace.h"
     17 #include "SkXfermode.h"
     18 
     19 #include "SkRTConf.h"
     20 
     21 SK_DEFINE_INST_COUNT(GrGLProgram)
     22 
     23 #define GL_CALL(X) GR_GL_CALL(fContextInfo.interface(), X)
     24 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContextInfo.interface(), R, X)
     25 
     26 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, "Print the source code for all shaders generated.");
     27 
     28 #define COL_ATTR_NAME "aColor"
     29 #define COV_ATTR_NAME "aCoverage"
     30 #define EDGE_ATTR_NAME "aEdge"
     31 
     32 namespace {
     33 inline void tex_attr_name(int coordIdx, SkString* s) {
     34     *s = "aTexCoord";
     35     s->appendS32(coordIdx);
     36 }
     37 
     38 inline const char* declared_color_output_name() { return "fsColorOut"; }
     39 inline const char* dual_source_output_name() { return "dualSourceOut"; }
     40 
     41 }
     42 
     43 GrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl,
     44                                  const Desc& desc,
     45                                  const GrEffectStage* stages[]) {
     46     GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages));
     47     if (!program->succeeded()) {
     48         delete program;
     49         program = NULL;
     50     }
     51     return program;
     52 }
     53 
     54 GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
     55                          const Desc& desc,
     56                          const GrEffectStage* stages[])
     57 : fContextInfo(gl)
     58 , fUniformManager(gl) {
     59     fDesc = desc;
     60     fVShaderID = 0;
     61     fGShaderID = 0;
     62     fFShaderID = 0;
     63     fProgramID = 0;
     64 
     65     fViewMatrix = SkMatrix::InvalidMatrix();
     66     fViewportSize.set(-1, -1);
     67     fColor = GrColor_ILLEGAL;
     68     fColorFilterColor = GrColor_ILLEGAL;
     69     fRTHeight = -1;
     70 
     71     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
     72         fEffects[s] = NULL;
     73     }
     74 
     75     this->genProgram(stages);
     76 }
     77 
     78 GrGLProgram::~GrGLProgram() {
     79     if (fVShaderID) {
     80         GL_CALL(DeleteShader(fVShaderID));
     81     }
     82     if (fGShaderID) {
     83         GL_CALL(DeleteShader(fGShaderID));
     84     }
     85     if (fFShaderID) {
     86         GL_CALL(DeleteShader(fFShaderID));
     87     }
     88     if (fProgramID) {
     89         GL_CALL(DeleteProgram(fProgramID));
     90     }
     91 
     92     for (int i = 0; i < GrDrawState::kNumStages; ++i) {
     93         delete fEffects[i];
     94     }
     95 }
     96 
     97 void GrGLProgram::abandon() {
     98     fVShaderID = 0;
     99     fGShaderID = 0;
    100     fFShaderID = 0;
    101     fProgramID = 0;
    102 }
    103 
    104 void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
    105                                 GrBlendCoeff* dstCoeff) const {
    106     switch (fDesc.fDualSrcOutput) {
    107         case Desc::kNone_DualSrcOutput:
    108             break;
    109         // the prog will write a coverage value to the secondary
    110         // output and the dst is blended by one minus that value.
    111         case Desc::kCoverage_DualSrcOutput:
    112         case Desc::kCoverageISA_DualSrcOutput:
    113         case Desc::kCoverageISC_DualSrcOutput:
    114         *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
    115         break;
    116         default:
    117             GrCrash("Unexpected dual source blend output");
    118             break;
    119     }
    120 }
    121 
    122 namespace {
    123 
    124 // given two blend coeffecients determine whether the src
    125 // and/or dst computation can be omitted.
    126 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff,
    127                               SkXfermode::Coeff dstCoeff,
    128                               bool* needSrcValue,
    129                               bool* needDstValue) {
    130     if (SkXfermode::kZero_Coeff == srcCoeff) {
    131         switch (dstCoeff) {
    132             // these all read the src
    133             case SkXfermode::kSC_Coeff:
    134             case SkXfermode::kISC_Coeff:
    135             case SkXfermode::kSA_Coeff:
    136             case SkXfermode::kISA_Coeff:
    137                 *needSrcValue = true;
    138                 break;
    139             default:
    140                 *needSrcValue = false;
    141                 break;
    142         }
    143     } else {
    144         *needSrcValue = true;
    145     }
    146     if (SkXfermode::kZero_Coeff == dstCoeff) {
    147         switch (srcCoeff) {
    148             // these all read the dst
    149             case SkXfermode::kDC_Coeff:
    150             case SkXfermode::kIDC_Coeff:
    151             case SkXfermode::kDA_Coeff:
    152             case SkXfermode::kIDA_Coeff:
    153                 *needDstValue = true;
    154                 break;
    155             default:
    156                 *needDstValue = false;
    157                 break;
    158         }
    159     } else {
    160         *needDstValue = true;
    161     }
    162 }
    163 
    164 /**
    165  * Create a blend_coeff * value string to be used in shader code. Sets empty
    166  * string if result is trivially zero.
    167  */
    168 inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff,
    169                        const char* src, const char* dst,
    170                        const char* value) {
    171     switch (coeff) {
    172     case SkXfermode::kZero_Coeff:    /** 0 */
    173         *str = "";
    174         break;
    175     case SkXfermode::kOne_Coeff:     /** 1 */
    176         *str = value;
    177         break;
    178     case SkXfermode::kSC_Coeff:
    179         str->printf("(%s * %s)", src, value);
    180         break;
    181     case SkXfermode::kISC_Coeff:
    182         str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value);
    183         break;
    184     case SkXfermode::kDC_Coeff:
    185         str->printf("(%s * %s)", dst, value);
    186         break;
    187     case SkXfermode::kIDC_Coeff:
    188         str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value);
    189         break;
    190     case SkXfermode::kSA_Coeff:      /** src alpha */
    191         str->printf("(%s.a * %s)", src, value);
    192         break;
    193     case SkXfermode::kISA_Coeff:     /** inverse src alpha (i.e. 1 - sa) */
    194         str->printf("((1.0 - %s.a) * %s)", src, value);
    195         break;
    196     case SkXfermode::kDA_Coeff:      /** dst alpha */
    197         str->printf("(%s.a * %s)", dst, value);
    198         break;
    199     case SkXfermode::kIDA_Coeff:     /** inverse dst alpha (i.e. 1 - da) */
    200         str->printf("((1.0 - %s.a) * %s)", dst, value);
    201         break;
    202     default:
    203         GrCrash("Unexpected xfer coeff.");
    204         break;
    205     }
    206 }
    207 /**
    208  * Adds a line to the fragment shader code which modifies the color by
    209  * the specified color filter.
    210  */
    211 void add_color_filter(SkString* fsCode, const char * outputVar,
    212                       SkXfermode::Coeff uniformCoeff,
    213                       SkXfermode::Coeff colorCoeff,
    214                       const char* filterColor,
    215                       const char* inColor) {
    216     SkString colorStr, constStr;
    217     blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor);
    218     blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor);
    219 
    220     fsCode->appendf("\t%s = ", outputVar);
    221     GrGLSLAdd4f(fsCode, colorStr.c_str(), constStr.c_str());
    222     fsCode->append(";\n");
    223 }
    224 }
    225 
    226 bool GrGLProgram::genEdgeCoverage(SkString* coverageVar,
    227                                   GrGLShaderBuilder* builder) const {
    228     if (fDesc.fVertexLayout & GrDrawState::kEdge_VertexLayoutBit) {
    229         const char *vsName, *fsName;
    230         builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName);
    231         builder->fVSAttrs.push_back().set(kVec4f_GrSLType,
    232                                           GrGLShaderVar::kAttribute_TypeModifier,
    233                                           EDGE_ATTR_NAME);
    234         builder->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
    235         switch (fDesc.fVertexEdgeType) {
    236         case GrDrawState::kHairLine_EdgeType:
    237             builder->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", builder->fragmentPosition(), fsName);
    238             builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
    239             break;
    240         case GrDrawState::kQuad_EdgeType:
    241             builder->fFSCode.append("\tfloat edgeAlpha;\n");
    242             // keep the derivative instructions outside the conditional
    243             builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
    244             builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
    245             builder->fFSCode.appendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
    246             // today we know z and w are in device space. We could use derivatives
    247             builder->fFSCode.appendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, fsName);
    248             builder->fFSCode.append ("\t} else {\n");
    249             builder->fFSCode.appendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
    250                                      "\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
    251                                      fsName, fsName);
    252             builder->fFSCode.appendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName);
    253             builder->fFSCode.append("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n"
    254                                     "\t}\n");
    255             if (kES2_GrGLBinding == fContextInfo.binding()) {
    256                 builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n");
    257             }
    258             break;
    259         case GrDrawState::kHairQuad_EdgeType:
    260             builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
    261             builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
    262             builder->fFSCode.appendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
    263                                      "\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
    264                                      fsName, fsName);
    265             builder->fFSCode.appendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName);
    266             builder->fFSCode.append("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
    267             builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
    268             if (kES2_GrGLBinding == fContextInfo.binding()) {
    269                 builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n");
    270             }
    271             break;
    272         case GrDrawState::kCircle_EdgeType:
    273             builder->fFSCode.append("\tfloat edgeAlpha;\n");
    274             builder->fFSCode.appendf("\tfloat d = distance(%s.xy, %s.xy);\n", builder->fragmentPosition(), fsName);
    275             builder->fFSCode.appendf("\tfloat outerAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName);
    276             builder->fFSCode.appendf("\tfloat innerAlpha = %s.w == 0.0 ? 1.0 : smoothstep(%s.w - 0.5, %s.w + 0.5, d);\n", fsName, fsName, fsName);
    277             builder->fFSCode.append("\tedgeAlpha = outerAlpha * innerAlpha;\n");
    278             break;
    279         case GrDrawState::kEllipse_EdgeType:
    280             builder->fFSCode.append("\tfloat edgeAlpha;\n");
    281             builder->fFSCode.appendf("\tvec2 offset = (%s.xy - %s.xy);\n", builder->fragmentPosition(), fsName);
    282             builder->fFSCode.appendf("\toffset.y *= %s.w;\n", fsName);
    283             builder->fFSCode.append("\tfloat d = length(offset);\n");
    284             builder->fFSCode.appendf("\tedgeAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName);
    285             break;
    286         default:
    287             GrCrash("Unknown Edge Type!");
    288             break;
    289         }
    290         if (fDesc.fDiscardIfOutsideEdge) {
    291             builder->fFSCode.appendf("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\t}\n");
    292         }
    293         *coverageVar = "edgeAlpha";
    294         return true;
    295     } else {
    296         coverageVar->reset();
    297         return false;
    298     }
    299 }
    300 
    301 void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) {
    302     switch (fDesc.fColorInput) {
    303         case GrGLProgram::Desc::kAttribute_ColorInput: {
    304             builder->fVSAttrs.push_back().set(kVec4f_GrSLType,
    305                 GrGLShaderVar::kAttribute_TypeModifier,
    306                 COL_ATTR_NAME);
    307             const char *vsName, *fsName;
    308             builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
    309             builder->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
    310             *inColor = fsName;
    311             } break;
    312         case GrGLProgram::Desc::kUniform_ColorInput: {
    313             const char* name;
    314             fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
    315                                                             kVec4f_GrSLType, "Color", &name);
    316             *inColor = name;
    317             break;
    318         }
    319         case GrGLProgram::Desc::kTransBlack_ColorInput:
    320             GrAssert(!"needComputedColor should be false.");
    321             break;
    322         case GrGLProgram::Desc::kSolidWhite_ColorInput:
    323             break;
    324         default:
    325             GrCrash("Unknown color type.");
    326             break;
    327     }
    328 }
    329 
    330 void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) {
    331     const char* covUniName;
    332     fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
    333                                                        kVec4f_GrSLType, "Coverage", &covUniName);
    334     if (inOutCoverage->size()) {
    335         builder->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n",
    336                                   covUniName, inOutCoverage->c_str());
    337         *inOutCoverage = "uniCoverage";
    338     } else {
    339         *inOutCoverage = covUniName;
    340     }
    341 }
    342 
    343 namespace {
    344 void gen_attribute_coverage(GrGLShaderBuilder* segments,
    345                             SkString* inOutCoverage) {
    346     segments->fVSAttrs.push_back().set(kVec4f_GrSLType,
    347                                        GrGLShaderVar::kAttribute_TypeModifier,
    348                                        COV_ATTR_NAME);
    349     const char *vsName, *fsName;
    350     segments->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName);
    351     segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
    352     if (inOutCoverage->size()) {
    353         segments->fFSCode.appendf("\tvec4 attrCoverage = %s * %s;\n",
    354                                   fsName, inOutCoverage->c_str());
    355         *inOutCoverage = "attrCoverage";
    356     } else {
    357         *inOutCoverage = fsName;
    358     }
    359 }
    360 }
    361 
    362 void GrGLProgram::genGeometryShader(GrGLShaderBuilder* segments) const {
    363 #if GR_GL_EXPERIMENTAL_GS
    364     if (fDesc.fExperimentalGS) {
    365         GrAssert(fContextInfo.glslGeneration() >= k150_GrGLSLGeneration);
    366         segments->fGSHeader.append("layout(triangles) in;\n"
    367                                    "layout(triangle_strip, max_vertices = 6) out;\n");
    368         segments->fGSCode.append("\tfor (int i = 0; i < 3; ++i) {\n"
    369                                  "\t\tgl_Position = gl_in[i].gl_Position;\n");
    370         if (fDesc.fEmitsPointSize) {
    371             segments->fGSCode.append("\t\tgl_PointSize = 1.0;\n");
    372         }
    373         GrAssert(segments->fGSInputs.count() == segments->fGSOutputs.count());
    374         int count = segments->fGSInputs.count();
    375         for (int i = 0; i < count; ++i) {
    376             segments->fGSCode.appendf("\t\t%s = %s[i];\n",
    377                                       segments->fGSOutputs[i].getName().c_str(),
    378                                       segments->fGSInputs[i].getName().c_str());
    379         }
    380         segments->fGSCode.append("\t\tEmitVertex();\n"
    381                                  "\t}\n"
    382                                  "\tEndPrimitive();\n");
    383     }
    384 #endif
    385 }
    386 
    387 const char* GrGLProgram::adjustInColor(const SkString& inColor) const {
    388     if (inColor.size()) {
    389           return inColor.c_str();
    390     } else {
    391         if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) {
    392             return GrGLSLOnesVecf(4);
    393         } else {
    394             return GrGLSLZerosVecf(4);
    395         }
    396     }
    397 }
    398 
    399 namespace {
    400 // prints a shader using params similar to glShaderSource
    401 void print_shader(GrGLint stringCnt,
    402                   const GrGLchar** strings,
    403                   GrGLint* stringLengths) {
    404     for (int i = 0; i < stringCnt; ++i) {
    405         if (NULL == stringLengths || stringLengths[i] < 0) {
    406             GrPrintf(strings[i]);
    407         } else {
    408             GrPrintf("%.*s", stringLengths[i], strings[i]);
    409         }
    410     }
    411 }
    412 
    413 // Compiles a GL shader, returns shader ID or 0 if failed params have same meaning as glShaderSource
    414 GrGLuint compile_shader(const GrGLContextInfo& gl,
    415                         GrGLenum type,
    416                         int stringCnt,
    417                         const char** strings,
    418                         int* stringLengths) {
    419     SK_TRACE_EVENT1("GrGLProgram::CompileShader",
    420                     "stringCount", SkStringPrintf("%i", stringCnt).c_str());
    421 
    422     GrGLuint shader;
    423     GR_GL_CALL_RET(gl.interface(), shader, CreateShader(type));
    424     if (0 == shader) {
    425         return 0;
    426     }
    427 
    428     const GrGLInterface* gli = gl.interface();
    429     GrGLint compiled = GR_GL_INIT_ZERO;
    430     GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths));
    431     GR_GL_CALL(gli, CompileShader(shader));
    432     GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled));
    433 
    434     if (!compiled) {
    435         GrGLint infoLen = GR_GL_INIT_ZERO;
    436         GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen));
    437         SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
    438         if (infoLen > 0) {
    439             // retrieve length even though we don't need it to workaround bug in chrome cmd buffer
    440             // param validation.
    441             GrGLsizei length = GR_GL_INIT_ZERO;
    442             GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1,
    443                                              &length, (char*)log.get()));
    444             print_shader(stringCnt, strings, stringLengths);
    445             GrPrintf("\n%s", log.get());
    446         }
    447         GrAssert(!"Shader compilation failed!");
    448         GR_GL_CALL(gli, DeleteShader(shader));
    449         return 0;
    450     }
    451     return shader;
    452 }
    453 
    454 // helper version of above for when shader is already flattened into a single SkString
    455 GrGLuint compile_shader(const GrGLContextInfo& gl, GrGLenum type, const SkString& shader) {
    456     const GrGLchar* str = shader.c_str();
    457     int length = shader.size();
    458     return compile_shader(gl, type, 1, &str, &length);
    459 }
    460 
    461 }
    462 
    463 // compiles all the shaders from builder and stores the shader IDs
    464 bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) {
    465 
    466     SkString shader;
    467 
    468     builder.getShader(GrGLShaderBuilder::kVertex_ShaderType, &shader);
    469     if (c_PrintShaders) {
    470         GrPrintf(shader.c_str());
    471         GrPrintf("\n");
    472     }
    473 
    474     if (!(fVShaderID = compile_shader(fContextInfo, GR_GL_VERTEX_SHADER, shader))) {
    475         return false;
    476     }
    477 
    478     if (builder.fUsesGS) {
    479         builder.getShader(GrGLShaderBuilder::kGeometry_ShaderType, &shader);
    480         if (c_PrintShaders) {
    481             GrPrintf(shader.c_str());
    482             GrPrintf("\n");
    483         }
    484         if (!(fGShaderID = compile_shader(fContextInfo, GR_GL_GEOMETRY_SHADER, shader))) {
    485             return false;
    486         }
    487     } else {
    488         fGShaderID = 0;
    489     }
    490 
    491     builder.getShader(GrGLShaderBuilder::kFragment_ShaderType, &shader);
    492     if (c_PrintShaders) {
    493         GrPrintf(shader.c_str());
    494         GrPrintf("\n");
    495     }
    496     if (!(fFShaderID = compile_shader(fContextInfo, GR_GL_FRAGMENT_SHADER, shader))) {
    497         return false;
    498     }
    499 
    500     return true;
    501 }
    502 
    503 bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
    504     GrAssert(0 == fProgramID);
    505 
    506     GrGLShaderBuilder builder(fContextInfo, fUniformManager);
    507     const uint32_t& layout = fDesc.fVertexLayout;
    508 
    509 #if GR_GL_EXPERIMENTAL_GS
    510     builder.fUsesGS = fDesc.fExperimentalGS;
    511 #endif
    512 
    513     SkXfermode::Coeff colorCoeff, uniformCoeff;
    514     // The rest of transfer mode color filters have not been implemented
    515     if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) {
    516         GR_DEBUGCODE(bool success =)
    517             SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>
    518                                     (fDesc.fColorFilterXfermode),
    519                                     &uniformCoeff, &colorCoeff);
    520         GR_DEBUGASSERT(success);
    521     } else {
    522         colorCoeff = SkXfermode::kOne_Coeff;
    523         uniformCoeff = SkXfermode::kZero_Coeff;
    524     }
    525 
    526     // no need to do the color filter if coverage is 0. The output color is scaled by the coverage.
    527     // All the dual source outputs are scaled by the coverage as well.
    528     if (Desc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
    529         colorCoeff = SkXfermode::kZero_Coeff;
    530         uniformCoeff = SkXfermode::kZero_Coeff;
    531     }
    532 
    533     // If we know the final color is going to be all zeros then we can
    534     // simplify the color filter coefficients. needComputedColor will then
    535     // come out false below.
    536     if (Desc::kTransBlack_ColorInput == fDesc.fColorInput) {
    537         colorCoeff = SkXfermode::kZero_Coeff;
    538         if (SkXfermode::kDC_Coeff == uniformCoeff ||
    539             SkXfermode::kDA_Coeff == uniformCoeff) {
    540             uniformCoeff = SkXfermode::kZero_Coeff;
    541         } else if (SkXfermode::kIDC_Coeff == uniformCoeff ||
    542                    SkXfermode::kIDA_Coeff == uniformCoeff) {
    543             uniformCoeff = SkXfermode::kOne_Coeff;
    544         }
    545     }
    546 
    547     bool needColorFilterUniform;
    548     bool needComputedColor;
    549     need_blend_inputs(uniformCoeff, colorCoeff,
    550                       &needColorFilterUniform, &needComputedColor);
    551 
    552     // the dual source output has no canonical var name, have to
    553     // declare an output, which is incompatible with gl_FragColor/gl_FragData.
    554     bool dualSourceOutputWritten = false;
    555     builder.fHeader.append(GrGetGLSLVersionDecl(fContextInfo.binding(),
    556                                                 fContextInfo.glslGeneration()));
    557 
    558     GrGLShaderVar colorOutput;
    559     bool isColorDeclared = GrGLSLSetupFSColorOuput(fContextInfo.glslGeneration(),
    560                                                    declared_color_output_name(),
    561                                                    &colorOutput);
    562     if (isColorDeclared) {
    563         builder.fFSOutputs.push_back(colorOutput);
    564     }
    565 
    566     const char* viewMName;
    567     fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType,
    568                                                         kMat33f_GrSLType, "ViewM", &viewMName);
    569 
    570 
    571     builder.fVSCode.appendf("\tvec3 pos3 = %s * vec3(%s, 1);\n"
    572                             "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n",
    573                             viewMName, builder.positionAttribute().getName().c_str());
    574 
    575     // incoming color to current stage being processed.
    576     SkString inColor;
    577 
    578     if (needComputedColor) {
    579         this->genInputColor(&builder, &inColor);
    580     }
    581 
    582     // we output point size in the GS if present
    583     if (fDesc.fEmitsPointSize && !builder.fUsesGS){
    584         builder.fVSCode.append("\tgl_PointSize = 1.0;\n");
    585     }
    586 
    587     // add texture coordinates that are used to the list of vertex attr decls
    588     SkString texCoordAttrs[GrDrawState::kMaxTexCoords];
    589     for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
    590         if (GrDrawState::VertexUsesTexCoordIdx(t, layout)) {
    591             tex_attr_name(t, texCoordAttrs + t);
    592             builder.fVSAttrs.push_back().set(kVec2f_GrSLType,
    593                 GrGLShaderVar::kAttribute_TypeModifier,
    594                 texCoordAttrs[t].c_str());
    595         }
    596     }
    597 
    598     ///////////////////////////////////////////////////////////////////////////
    599     // compute the final color
    600 
    601     // if we have color stages string them together, feeding the output color
    602     // of each to the next and generating code for each stage.
    603     if (needComputedColor) {
    604         SkString outColor;
    605         for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) {
    606             if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) {
    607                 // create var to hold stage result
    608                 outColor = "color";
    609                 outColor.appendS32(s);
    610                 builder.fFSCode.appendf("\tvec4 %s;\n", outColor.c_str());
    611 
    612                 const char* inCoords;
    613                 // figure out what our input coords are
    614                 int tcIdx = GrDrawState::VertexTexCoordsForStage(s, layout);
    615                 if (tcIdx < 0) {
    616                     inCoords = builder.positionAttribute().c_str();
    617                 } else {
    618                     // must have input tex coordinates if stage is enabled.
    619                     GrAssert(texCoordAttrs[tcIdx].size());
    620                     inCoords = texCoordAttrs[tcIdx].c_str();
    621                 }
    622 
    623                 builder.setCurrentStage(s);
    624                 fEffects[s] = builder.createAndEmitGLEffect(*stages[s],
    625                                                             fDesc.fEffectKeys[s],
    626                                                             inColor.size() ? inColor.c_str() : NULL,
    627                                                             outColor.c_str(),
    628                                                             inCoords,
    629                                                             &fUniformHandles.fSamplerUnis[s]);
    630                 builder.setNonStage();
    631                 inColor = outColor;
    632             }
    633         }
    634     }
    635 
    636     // if have all ones or zeros for the "dst" input to the color filter then we
    637     // may be able to make additional optimizations.
    638     if (needColorFilterUniform && needComputedColor && !inColor.size()) {
    639         GrAssert(Desc::kSolidWhite_ColorInput == fDesc.fColorInput);
    640         bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff ||
    641                                   SkXfermode::kIDA_Coeff == uniformCoeff;
    642         if (uniformCoeffIsZero) {
    643             uniformCoeff = SkXfermode::kZero_Coeff;
    644             bool bogus;
    645             need_blend_inputs(SkXfermode::kZero_Coeff, colorCoeff,
    646                               &needColorFilterUniform, &bogus);
    647         }
    648     }
    649     const char* colorFilterColorUniName = NULL;
    650     if (needColorFilterUniform) {
    651         fUniformHandles.fColorFilterUni = builder.addUniform(
    652                                                         GrGLShaderBuilder::kFragment_ShaderType,
    653                                                         kVec4f_GrSLType, "FilterColor",
    654                                                         &colorFilterColorUniName);
    655     }
    656     bool wroteFragColorZero = false;
    657     if (SkXfermode::kZero_Coeff == uniformCoeff &&
    658         SkXfermode::kZero_Coeff == colorCoeff) {
    659         builder.fFSCode.appendf("\t%s = %s;\n",
    660                                 colorOutput.getName().c_str(),
    661                                 GrGLSLZerosVecf(4));
    662         wroteFragColorZero = true;
    663     } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) {
    664         builder.fFSCode.append("\tvec4 filteredColor;\n");
    665         const char* color = adjustInColor(inColor);
    666         add_color_filter(&builder.fFSCode, "filteredColor", uniformCoeff,
    667                        colorCoeff, colorFilterColorUniName, color);
    668         inColor = "filteredColor";
    669     }
    670 
    671     ///////////////////////////////////////////////////////////////////////////
    672     // compute the partial coverage (coverage stages and edge aa)
    673 
    674     SkString inCoverage;
    675     bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput;
    676     // we don't need to compute coverage at all if we know the final shader
    677     // output will be zero and we don't have a dual src blend output.
    678     if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
    679 
    680         if (!coverageIsZero) {
    681             bool inCoverageIsScalar  = this->genEdgeCoverage(&inCoverage, &builder);
    682 
    683             switch (fDesc.fCoverageInput) {
    684                 case Desc::kSolidWhite_ColorInput:
    685                     // empty string implies solid white
    686                     break;
    687                 case Desc::kAttribute_ColorInput:
    688                     gen_attribute_coverage(&builder, &inCoverage);
    689                     inCoverageIsScalar = false;
    690                     break;
    691                 case Desc::kUniform_ColorInput:
    692                     this->genUniformCoverage(&builder, &inCoverage);
    693                     inCoverageIsScalar = false;
    694                     break;
    695                 default:
    696                     GrCrash("Unexpected input coverage.");
    697             }
    698 
    699             SkString outCoverage;
    700             const int& startStage = fDesc.fFirstCoverageStage;
    701             for (int s = startStage; s < GrDrawState::kNumStages; ++s) {
    702                 if (fDesc.fEffectKeys[s]) {
    703                     // create var to hold stage output
    704                     outCoverage = "coverage";
    705                     outCoverage.appendS32(s);
    706                     builder.fFSCode.appendf("\tvec4 %s;\n", outCoverage.c_str());
    707 
    708                     const char* inCoords;
    709                     // figure out what our input coords are
    710                     int tcIdx =
    711                         GrDrawState::VertexTexCoordsForStage(s, layout);
    712                     if (tcIdx < 0) {
    713                         inCoords = builder.positionAttribute().c_str();
    714                     } else {
    715                         // must have input tex coordinates if stage is
    716                         // enabled.
    717                         GrAssert(texCoordAttrs[tcIdx].size());
    718                         inCoords = texCoordAttrs[tcIdx].c_str();
    719                     }
    720 
    721                     // stages don't know how to deal with a scalar input. (Maybe they should. We
    722                     // could pass a GrGLShaderVar)
    723                     if (inCoverageIsScalar) {
    724                         builder.fFSCode.appendf("\tvec4 %s4 = vec4(%s);\n",
    725                                                 inCoverage.c_str(), inCoverage.c_str());
    726                         inCoverage.append("4");
    727                     }
    728                     builder.setCurrentStage(s);
    729                     fEffects[s] = builder.createAndEmitGLEffect(
    730                                                     *stages[s],
    731                                                     fDesc.fEffectKeys[s],
    732                                                     inCoverage.size() ? inCoverage.c_str() : NULL,
    733                                                     outCoverage.c_str(),
    734                                                     inCoords,
    735                                                     &fUniformHandles.fSamplerUnis[s]);
    736                     builder.setNonStage();
    737                     inCoverage = outCoverage;
    738                 }
    739             }
    740         }
    741 
    742         if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
    743             builder.fFSOutputs.push_back().set(kVec4f_GrSLType,
    744                                                GrGLShaderVar::kOut_TypeModifier,
    745                                                dual_source_output_name());
    746             bool outputIsZero = coverageIsZero;
    747             SkString coeff;
    748             if (!outputIsZero &&
    749                 Desc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) {
    750                 if (!inColor.size()) {
    751                     outputIsZero = true;
    752                 } else {
    753                     if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
    754                         coeff.printf("(1 - %s.a)", inColor.c_str());
    755                     } else {
    756                         coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str());
    757                     }
    758                 }
    759             }
    760             if (outputIsZero) {
    761                 builder.fFSCode.appendf("\t%s = %s;\n",
    762                                         dual_source_output_name(),
    763                                         GrGLSLZerosVecf(4));
    764             } else {
    765                 builder.fFSCode.appendf("\t%s =", dual_source_output_name());
    766                 GrGLSLModulate4f(&builder.fFSCode, coeff.c_str(), inCoverage.c_str());
    767                 builder.fFSCode.append(";\n");
    768             }
    769             dualSourceOutputWritten = true;
    770         }
    771     }
    772 
    773     ///////////////////////////////////////////////////////////////////////////
    774     // combine color and coverage as frag color
    775 
    776     if (!wroteFragColorZero) {
    777         if (coverageIsZero) {
    778             builder.fFSCode.appendf("\t%s = %s;\n",
    779                                     colorOutput.getName().c_str(),
    780                                     GrGLSLZerosVecf(4));
    781         } else {
    782             builder.fFSCode.appendf("\t%s = ", colorOutput.getName().c_str());
    783             GrGLSLModulate4f(&builder.fFSCode, inColor.c_str(), inCoverage.c_str());
    784             builder.fFSCode.append(";\n");
    785         }
    786     }
    787 
    788     ///////////////////////////////////////////////////////////////////////////
    789     // insert GS
    790 #if GR_DEBUG
    791     this->genGeometryShader(&builder);
    792 #endif
    793 
    794     ///////////////////////////////////////////////////////////////////////////
    795     // compile and setup attribs and unis
    796 
    797     if (!this->compileShaders(builder)) {
    798         return false;
    799     }
    800 
    801     if (!this->bindOutputsAttribsAndLinkProgram(builder,
    802                                                 texCoordAttrs,
    803                                                 isColorDeclared,
    804                                                 dualSourceOutputWritten)) {
    805         return false;
    806     }
    807 
    808     builder.finished(fProgramID);
    809     this->initSamplerUniforms();
    810     fUniformHandles.fRTHeightUni = builder.getRTHeightUniform();
    811 
    812     return true;
    813 }
    814 
    815 bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
    816                                                    SkString texCoordAttrNames[],
    817                                                    bool bindColorOut,
    818                                                    bool bindDualSrcOut) {
    819     GL_CALL_RET(fProgramID, CreateProgram());
    820     if (!fProgramID) {
    821         return false;
    822     }
    823 
    824     GL_CALL(AttachShader(fProgramID, fVShaderID));
    825     if (fGShaderID) {
    826         GL_CALL(AttachShader(fProgramID, fGShaderID));
    827     }
    828     GL_CALL(AttachShader(fProgramID, fFShaderID));
    829 
    830     if (bindColorOut) {
    831         GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()));
    832     }
    833     if (bindDualSrcOut) {
    834         GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name()));
    835     }
    836 
    837     // Bind the attrib locations to same values for all shaders
    838     GL_CALL(BindAttribLocation(fProgramID,
    839                                PositionAttributeIdx(),
    840                                builder.positionAttribute().c_str()));
    841     for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
    842         if (texCoordAttrNames[t].size()) {
    843             GL_CALL(BindAttribLocation(fProgramID,
    844                                        TexCoordAttributeIdx(t),
    845                                        texCoordAttrNames[t].c_str()));
    846         }
    847     }
    848 
    849     GL_CALL(BindAttribLocation(fProgramID, ColorAttributeIdx(), COL_ATTR_NAME));
    850     GL_CALL(BindAttribLocation(fProgramID, CoverageAttributeIdx(), COV_ATTR_NAME));
    851     GL_CALL(BindAttribLocation(fProgramID, EdgeAttributeIdx(), EDGE_ATTR_NAME));
    852 
    853     GL_CALL(LinkProgram(fProgramID));
    854 
    855     GrGLint linked = GR_GL_INIT_ZERO;
    856     GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
    857     if (!linked) {
    858         GrGLint infoLen = GR_GL_INIT_ZERO;
    859         GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
    860         SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
    861         if (infoLen > 0) {
    862             // retrieve length even though we don't need it to workaround
    863             // bug in chrome cmd buffer param validation.
    864             GrGLsizei length = GR_GL_INIT_ZERO;
    865             GL_CALL(GetProgramInfoLog(fProgramID,
    866                                       infoLen+1,
    867                                       &length,
    868                                       (char*)log.get()));
    869             GrPrintf((char*)log.get());
    870         }
    871         GrAssert(!"Error linking program");
    872         GL_CALL(DeleteProgram(fProgramID));
    873         fProgramID = 0;
    874         return false;
    875     }
    876     return true;
    877 }
    878 
    879 void GrGLProgram::initSamplerUniforms() {
    880     GL_CALL(UseProgram(fProgramID));
    881     // We simply bind the uniforms to successive texture units beginning at 0. setData() assumes this
    882     // behavior.
    883     GrGLint texUnitIdx = 0;
    884     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    885         int numSamplers = fUniformHandles.fSamplerUnis[s].count();
    886         for (int u = 0; u < numSamplers; ++u) {
    887             UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
    888             if (GrGLUniformManager::kInvalidUniformHandle != handle) {
    889                 fUniformManager.setSampler(handle, texUnitIdx);
    890                 ++texUnitIdx;
    891             }
    892         }
    893     }
    894 }
    895 
    896 ///////////////////////////////////////////////////////////////////////////////
    897 
    898 void GrGLProgram::setData(GrGpuGL* gpu) {
    899     const GrDrawState& drawState = gpu->getDrawState();
    900 
    901     int rtHeight = drawState.getRenderTarget()->height();
    902     if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni &&
    903         fRTHeight != rtHeight) {
    904         fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(rtHeight));
    905         fRTHeight = rtHeight;
    906     }
    907     GrGLint texUnitIdx = 0;
    908     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    909         if (NULL != fEffects[s]) {
    910             const GrEffectStage& stage = drawState.getStage(s);
    911             GrAssert(NULL != stage.getEffect());
    912             fEffects[s]->setData(fUniformManager, stage);
    913             int numSamplers = fUniformHandles.fSamplerUnis[s].count();
    914             for (int u = 0; u < numSamplers; ++u) {
    915                 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
    916                 if (GrGLUniformManager::kInvalidUniformHandle != handle) {
    917                     const GrTextureAccess& access = (*stage.getEffect())->textureAccess(u);
    918                     GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture());
    919                     gpu->bindTexture(texUnitIdx, access.getParams(), texture);
    920                     ++texUnitIdx;
    921                 }
    922             }
    923         }
    924     }
    925 }
    926