Home | History | Annotate | Download | only in gl
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "../GrBinHashKey.h"
     11 #include "GrGLProgram.h"
     12 #include "GrGLSL.h"
     13 #include "GrGpuGLShaders.h"
     14 #include "../GrGpuVertex.h"
     15 #include "GrNoncopyable.h"
     16 #include "../GrStringBuilder.h"
     17 #include "../GrRandom.h"
     18 
     19 #define SKIP_CACHE_CHECK    true
     20 #define GR_UINT32_MAX   static_cast<uint32_t>(-1)
     21 
     22 #include "../GrTHashCache.h"
     23 
     24 class GrGpuGLShaders::ProgramCache : public ::GrNoncopyable {
     25 private:
     26     class Entry;
     27 
     28     typedef GrBinHashKey<Entry, GrGLProgram::kProgramKeySize> ProgramHashKey;
     29 
     30     class Entry : public ::GrNoncopyable {
     31     public:
     32         Entry() {}
     33         void copyAndTakeOwnership(Entry& entry) {
     34             fProgramData.copyAndTakeOwnership(entry.fProgramData);
     35             fKey = entry.fKey; // ownership transfer
     36             fLRUStamp = entry.fLRUStamp;
     37         }
     38 
     39     public:
     40         int compare(const ProgramHashKey& key) const { return fKey.compare(key); }
     41 
     42     public:
     43         GrGLProgram::CachedData fProgramData;
     44         ProgramHashKey          fKey;
     45         unsigned int            fLRUStamp;
     46     };
     47 
     48     GrTHashTable<Entry, ProgramHashKey, 8> fHashCache;
     49 
     50     // We may have kMaxEntries+1 shaders in the GL context because
     51     // we create a new shader before evicting from the cache.
     52     enum {
     53         kMaxEntries = 32
     54     };
     55     Entry                       fEntries[kMaxEntries];
     56     int                         fCount;
     57     unsigned int                fCurrLRUStamp;
     58     const GrGLContextInfo&      fGL;
     59 
     60 public:
     61     ProgramCache(const GrGLContextInfo& gl)
     62         : fCount(0)
     63         , fCurrLRUStamp(0)
     64         , fGL(gl) {
     65     }
     66 
     67     ~ProgramCache() {
     68         for (int i = 0; i < fCount; ++i) {
     69             GrGpuGLShaders::DeleteProgram(fGL.interface(),
     70                                           &fEntries[i].fProgramData);
     71         }
     72     }
     73 
     74     void abandon() {
     75         fCount = 0;
     76     }
     77 
     78     void invalidateViewMatrices() {
     79         for (int i = 0; i < fCount; ++i) {
     80             // set to illegal matrix
     81             fEntries[i].fProgramData.fViewMatrix = GrMatrix::InvalidMatrix();
     82         }
     83     }
     84 
     85     GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc) {
     86         Entry newEntry;
     87         newEntry.fKey.setKeyData(desc.keyData());
     88 
     89         Entry* entry = fHashCache.find(newEntry.fKey);
     90         if (NULL == entry) {
     91             if (!desc.genProgram(fGL, &newEntry.fProgramData)) {
     92                 return NULL;
     93             }
     94             if (fCount < kMaxEntries) {
     95                 entry = fEntries + fCount;
     96                 ++fCount;
     97             } else {
     98                 GrAssert(kMaxEntries == fCount);
     99                 entry = fEntries;
    100                 for (int i = 1; i < kMaxEntries; ++i) {
    101                     if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
    102                         entry = fEntries + i;
    103                     }
    104                 }
    105                 fHashCache.remove(entry->fKey, entry);
    106                 GrGpuGLShaders::DeleteProgram(fGL.interface(),
    107                                               &entry->fProgramData);
    108             }
    109             entry->copyAndTakeOwnership(newEntry);
    110             fHashCache.insert(entry->fKey, entry);
    111         }
    112 
    113         entry->fLRUStamp = fCurrLRUStamp;
    114         if (GR_UINT32_MAX == fCurrLRUStamp) {
    115             // wrap around! just trash our LRU, one time hit.
    116             for (int i = 0; i < fCount; ++i) {
    117                 fEntries[i].fLRUStamp = 0;
    118             }
    119         }
    120         ++fCurrLRUStamp;
    121         return &entry->fProgramData;
    122     }
    123 };
    124 
    125 void GrGpuGLShaders::abandonResources(){
    126     INHERITED::abandonResources();
    127     fProgramCache->abandon();
    128 }
    129 
    130 void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl,
    131                                    CachedData* programData) {
    132     GR_GL_CALL(gl, DeleteShader(programData->fVShaderID));
    133     if (programData->fGShaderID) {
    134         GR_GL_CALL(gl, DeleteShader(programData->fGShaderID));
    135     }
    136     GR_GL_CALL(gl, DeleteShader(programData->fFShaderID));
    137     GR_GL_CALL(gl, DeleteProgram(programData->fProgramID));
    138     GR_DEBUGCODE(memset(programData, 0, sizeof(*programData));)
    139 }
    140 
    141 ////////////////////////////////////////////////////////////////////////////////
    142 
    143 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
    144 
    145 namespace {
    146 
    147 // GrRandoms nextU() values have patterns in the low bits
    148 // So using nextU() % array_count might never take some values.
    149 int random_int(GrRandom* r, int count) {
    150     return (int)(r->nextF() * count);
    151 }
    152 
    153 // min is inclusive, max is exclusive
    154 int random_int(GrRandom* r, int min, int max) {
    155     return (int)(r->nextF() * (max-min)) + min;
    156 }
    157 
    158 bool random_bool(GrRandom* r) {
    159     return r->nextF() > .5f;
    160 }
    161 
    162 }
    163 
    164 bool GrGpuGLShaders::programUnitTest() {
    165 
    166     GrGLSLGeneration glslGeneration =
    167             GrGetGLSLGeneration(this->glBinding(), this->glInterface());
    168     static const int STAGE_OPTS[] = {
    169         0,
    170         StageDesc::kNoPerspective_OptFlagBit,
    171         StageDesc::kIdentity_CoordMapping
    172     };
    173     static const int IN_CONFIG_FLAGS[] = {
    174         StageDesc::kNone_InConfigFlag,
    175         StageDesc::kSwapRAndB_InConfigFlag,
    176         StageDesc::kSwapRAndB_InConfigFlag |
    177         StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag,
    178         StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag,
    179         StageDesc::kSmearAlpha_InConfigFlag,
    180     };
    181     GrGLProgram program;
    182     ProgramDesc& pdesc = program.fProgramDesc;
    183 
    184     static const int NUM_TESTS = 512;
    185 
    186     GrRandom random;
    187     for (int t = 0; t < NUM_TESTS; ++t) {
    188 
    189 #if 0
    190         GrPrintf("\nTest Program %d\n-------------\n", t);
    191         static const int stop = -1;
    192         if (t == stop) {
    193             int breakpointhere = 9;
    194         }
    195 #endif
    196 
    197         pdesc.fVertexLayout = 0;
    198         pdesc.fEmitsPointSize = random.nextF() > .5f;
    199         pdesc.fColorInput = random_int(&random, ProgramDesc::kColorInputCnt);
    200         pdesc.fCoverageInput = random_int(&random, ProgramDesc::kColorInputCnt);
    201 
    202         pdesc.fColorFilterXfermode = random_int(&random, SkXfermode::kCoeffModesCnt);
    203 
    204         pdesc.fFirstCoverageStage = random_int(&random, GrDrawState::kNumStages);
    205 
    206         pdesc.fVertexLayout |= random_bool(&random) ?
    207                                     GrDrawTarget::kCoverage_VertexLayoutBit :
    208                                     0;
    209 
    210 #if GR_GL_EXPERIMENTAL_GS
    211         pdesc.fExperimentalGS = this->getCaps().fGeometryShaderSupport &&
    212                                 random_bool(&random);
    213 #endif
    214         pdesc.fOutputConfig =  random_int(&random, ProgramDesc::kOutputConfigCnt);
    215 
    216         bool edgeAA = random_bool(&random);
    217         if (edgeAA) {
    218             bool vertexEdgeAA = random_bool(&random);
    219             if (vertexEdgeAA) {
    220                 pdesc.fVertexLayout |= GrDrawTarget::kEdge_VertexLayoutBit;
    221                 if (this->getCaps().fShaderDerivativeSupport) {
    222                     pdesc.fVertexEdgeType = (GrDrawState::VertexEdgeType) random_int(&random, GrDrawState::kVertexEdgeTypeCnt);
    223                 } else {
    224                     pdesc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
    225                 }
    226                 pdesc.fEdgeAANumEdges = 0;
    227             } else {
    228                 pdesc.fEdgeAANumEdges = random_int(&random, 1, this->getMaxEdges());
    229                 pdesc.fEdgeAAConcave = random_bool(&random);
    230             }
    231         } else {
    232             pdesc.fEdgeAANumEdges = 0;
    233         }
    234 
    235         pdesc.fColorMatrixEnabled = random_bool(&random);
    236 
    237         if (this->getCaps().fDualSourceBlendingSupport) {
    238             pdesc.fDualSrcOutput = random_int(&random, ProgramDesc::kDualSrcOutputCnt);
    239         } else {
    240             pdesc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;
    241         }
    242 
    243         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    244             // enable the stage?
    245             if (random_bool(&random)) {
    246                 // use separate tex coords?
    247                 if (random_bool(&random)) {
    248                     int t = random_int(&random, GrDrawState::kMaxTexCoords);
    249                     pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t);
    250                 } else {
    251                     pdesc.fVertexLayout |= StagePosAsTexCoordVertexLayoutBit(s);
    252                 }
    253             }
    254             // use text-formatted verts?
    255             if (random_bool(&random)) {
    256                 pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
    257             }
    258             StageDesc& stage = pdesc.fStages[s];
    259             stage.fOptFlags = STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))];
    260             stage.fInConfigFlags = IN_CONFIG_FLAGS[random_int(&random, GR_ARRAY_COUNT(IN_CONFIG_FLAGS))];
    261             stage.fCoordMapping =  random_int(&random, StageDesc::kCoordMappingCnt);
    262             stage.fFetchMode = random_int(&random, StageDesc::kFetchModeCnt);
    263             // convolution shaders don't work with persp tex matrix
    264             if (stage.fFetchMode == StageDesc::kConvolution_FetchMode ||
    265                 stage.fFetchMode == StageDesc::kDilate_FetchMode ||
    266                 stage.fFetchMode == StageDesc::kErode_FetchMode) {
    267                 stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
    268             }
    269             stage.setEnabled(VertexUsesStage(s, pdesc.fVertexLayout));
    270             static const uint32_t kMulByAlphaMask =
    271                 StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
    272                 StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
    273             switch (stage.fFetchMode) {
    274                 case StageDesc::kSingle_FetchMode:
    275                     stage.fKernelWidth = 0;
    276                     break;
    277                 case StageDesc::kConvolution_FetchMode:
    278                 case StageDesc::kDilate_FetchMode:
    279                 case StageDesc::kErode_FetchMode:
    280                     stage.fKernelWidth = random_int(&random, 2, 8);
    281                     stage.fInConfigFlags &= ~kMulByAlphaMask;
    282                     break;
    283                 case StageDesc::k2x2_FetchMode:
    284                     stage.fKernelWidth = 0;
    285                     stage.fInConfigFlags &= ~kMulByAlphaMask;
    286                     break;
    287             }
    288         }
    289         CachedData cachedData;
    290         if (!program.genProgram(this->glContextInfo(), &cachedData)) {
    291             return false;
    292         }
    293         DeleteProgram(this->glInterface(), &cachedData);
    294     }
    295     return true;
    296 }
    297 
    298 GrGpuGLShaders::GrGpuGLShaders(const GrGLContextInfo& ctxInfo)
    299     : GrGpuGL(ctxInfo) {
    300 
    301     // Enable supported shader-related caps
    302     if (kDesktop_GrGLBinding == this->glBinding()) {
    303         fCaps.fDualSourceBlendingSupport =
    304                             this->glVersion() >= GR_GL_VER(3,3) ||
    305                             this->hasExtension("GL_ARB_blend_func_extended");
    306         fCaps.fShaderDerivativeSupport = true;
    307         // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
    308         fCaps.fGeometryShaderSupport =
    309                                 this->glVersion() >= GR_GL_VER(3,2) &&
    310                                 this->glslGeneration() >= k150_GrGLSLGeneration;
    311     } else {
    312         fCaps.fShaderDerivativeSupport =
    313                             this->hasExtension("GL_OES_standard_derivatives");
    314     }
    315 
    316     GR_GL_GetIntegerv(this->glInterface(),
    317                       GR_GL_MAX_VERTEX_ATTRIBS,
    318                       &fMaxVertexAttribs);
    319 
    320     fProgramData = NULL;
    321     fProgramCache = new ProgramCache(this->glContextInfo());
    322 
    323 #if 0
    324     this->programUnitTest();
    325 #endif
    326 }
    327 
    328 GrGpuGLShaders::~GrGpuGLShaders() {
    329     delete fProgramCache;
    330 }
    331 
    332 const GrMatrix& GrGpuGLShaders::getHWViewMatrix() {
    333     GrAssert(fProgramData);
    334 
    335     if (GrGLProgram::kSetAsAttribute ==
    336         fProgramData->fUniLocations.fViewMatrixUni) {
    337         return fHWDrawState.getViewMatrix();
    338     } else {
    339         return fProgramData->fViewMatrix;
    340     }
    341 }
    342 
    343 void GrGpuGLShaders::recordHWViewMatrix(const GrMatrix& matrix) {
    344     GrAssert(fProgramData);
    345     if (GrGLProgram::kSetAsAttribute ==
    346         fProgramData->fUniLocations.fViewMatrixUni) {
    347         fHWDrawState.setViewMatrix(matrix);
    348     } else {
    349         fProgramData->fViewMatrix = matrix;
    350     }
    351 }
    352 
    353 const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
    354     GrAssert(fProgramData);
    355 
    356     if (GrGLProgram::kSetAsAttribute ==
    357         fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
    358         return fHWDrawState.getSampler(stage).getMatrix();
    359     } else {
    360         return fProgramData->fTextureMatrices[stage];
    361     }
    362 }
    363 
    364 void GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
    365     GrAssert(fProgramData);
    366     if (GrGLProgram::kSetAsAttribute ==
    367         fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
    368         *fHWDrawState.sampler(stage)->matrix() = matrix;
    369     } else {
    370         fProgramData->fTextureMatrices[stage] = matrix;
    371     }
    372 }
    373 
    374 void GrGpuGLShaders::onResetContext() {
    375     INHERITED::onResetContext();
    376 
    377     fHWGeometryState.fVertexOffset = ~0;
    378 
    379     // Third party GL code may have left vertex attributes enabled. Some GL
    380     // implementations (osmesa) may read vetex attributes that are not required
    381     // by the current shader. Therefore, we have to ensure that only the
    382     // attributes we require for the current draw are enabled or we may cause an
    383     // invalid read.
    384 
    385     // Disable all vertex layout bits so that next flush will assume all
    386     // optional vertex attributes are disabled.
    387     fHWGeometryState.fVertexLayout = 0;
    388 
    389     // We always use the this attribute and assume it is always enabled.
    390     int posAttrIdx = GrGLProgram::PositionAttributeIdx();
    391     GL_CALL(EnableVertexAttribArray(posAttrIdx));
    392     // Disable all other vertex attributes.
    393     for  (int va = 0; va < fMaxVertexAttribs; ++va) {
    394         if (va != posAttrIdx) {
    395             GL_CALL(DisableVertexAttribArray(va));
    396         }
    397     }
    398 
    399     fHWProgramID = 0;
    400 }
    401 
    402 void GrGpuGLShaders::flushViewMatrix() {
    403     const GrMatrix& vm = this->getDrawState().getViewMatrix();
    404     if (GrGpuGLShaders::getHWViewMatrix() != vm) {
    405 
    406         const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
    407         GrAssert(NULL != rt);
    408         GrMatrix m;
    409         m.setAll(
    410             GrIntToScalar(2) / rt->width(), 0, -GR_Scalar1,
    411             0,-GrIntToScalar(2) / rt->height(), GR_Scalar1,
    412             0, 0, GrMatrix::I()[8]);
    413         m.setConcat(m, vm);
    414 
    415         // ES doesn't allow you to pass true to the transpose param,
    416         // so do our own transpose
    417         GrGLfloat mt[]  = {
    418             GrScalarToFloat(m[GrMatrix::kMScaleX]),
    419             GrScalarToFloat(m[GrMatrix::kMSkewY]),
    420             GrScalarToFloat(m[GrMatrix::kMPersp0]),
    421             GrScalarToFloat(m[GrMatrix::kMSkewX]),
    422             GrScalarToFloat(m[GrMatrix::kMScaleY]),
    423             GrScalarToFloat(m[GrMatrix::kMPersp1]),
    424             GrScalarToFloat(m[GrMatrix::kMTransX]),
    425             GrScalarToFloat(m[GrMatrix::kMTransY]),
    426             GrScalarToFloat(m[GrMatrix::kMPersp2])
    427         };
    428 
    429         if (GrGLProgram::kSetAsAttribute ==
    430             fProgramData->fUniLocations.fViewMatrixUni) {
    431             int baseIdx = GrGLProgram::ViewMatrixAttributeIdx();
    432             GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
    433             GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
    434             GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
    435         } else {
    436             GrAssert(GrGLProgram::kUnusedUniform !=
    437                      fProgramData->fUniLocations.fViewMatrixUni);
    438             GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
    439                                      1, false, mt));
    440         }
    441         this->recordHWViewMatrix(vm);
    442     }
    443 }
    444 
    445 void GrGpuGLShaders::flushTextureDomain(int s) {
    446     const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni;
    447     const GrDrawState& drawState = this->getDrawState();
    448     if (GrGLProgram::kUnusedUniform != uni) {
    449         const GrRect &texDom = drawState.getSampler(s).getTextureDomain();
    450 
    451         if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
    452             fProgramData->fTextureDomain[s] != texDom) {
    453 
    454             fProgramData->fTextureDomain[s] = texDom;
    455 
    456             float values[4] = {
    457                 GrScalarToFloat(texDom.left()),
    458                 GrScalarToFloat(texDom.top()),
    459                 GrScalarToFloat(texDom.right()),
    460                 GrScalarToFloat(texDom.bottom())
    461             };
    462 
    463             const GrGLTexture* texture =
    464                 static_cast<const GrGLTexture*>(drawState.getTexture(s));
    465             GrGLTexture::Orientation orientation = texture->orientation();
    466 
    467             // vertical flip if necessary
    468             if (GrGLTexture::kBottomUp_Orientation == orientation) {
    469                 values[1] = 1.0f - values[1];
    470                 values[3] = 1.0f - values[3];
    471                 // The top and bottom were just flipped, so correct the ordering
    472                 // of elements so that values = (l, t, r, b).
    473                 SkTSwap(values[1], values[3]);
    474             }
    475 
    476             GL_CALL(Uniform4fv(uni, 1, values));
    477         }
    478     }
    479 }
    480 
    481 void GrGpuGLShaders::flushTextureMatrix(int s) {
    482     const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni;
    483     const GrDrawState& drawState = this->getDrawState();
    484     const GrGLTexture* texture =
    485         static_cast<const GrGLTexture*>(drawState.getTexture(s));
    486     if (NULL != texture) {
    487         if (GrGLProgram::kUnusedUniform != uni &&
    488             (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
    489             this->getHWSamplerMatrix(s) != drawState.getSampler(s).getMatrix())) {
    490 
    491             GrMatrix m = drawState.getSampler(s).getMatrix();
    492             GrSamplerState::SampleMode mode =
    493                 drawState.getSampler(s).getSampleMode();
    494             AdjustTextureMatrix(texture, mode, &m);
    495 
    496             // ES doesn't allow you to pass true to the transpose param,
    497             // so do our own transpose
    498             GrGLfloat mt[]  = {
    499                 GrScalarToFloat(m[GrMatrix::kMScaleX]),
    500                 GrScalarToFloat(m[GrMatrix::kMSkewY]),
    501                 GrScalarToFloat(m[GrMatrix::kMPersp0]),
    502                 GrScalarToFloat(m[GrMatrix::kMSkewX]),
    503                 GrScalarToFloat(m[GrMatrix::kMScaleY]),
    504                 GrScalarToFloat(m[GrMatrix::kMPersp1]),
    505                 GrScalarToFloat(m[GrMatrix::kMTransX]),
    506                 GrScalarToFloat(m[GrMatrix::kMTransY]),
    507                 GrScalarToFloat(m[GrMatrix::kMPersp2])
    508             };
    509 
    510             if (GrGLProgram::kSetAsAttribute ==
    511                 fProgramData->fUniLocations.fStages[s].fTextureMatrixUni) {
    512                 int baseIdx = GrGLProgram::TextureMatrixAttributeIdx(s);
    513                 GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
    514                 GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
    515                 GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
    516             } else {
    517                 GL_CALL(UniformMatrix3fv(uni, 1, false, mt));
    518             }
    519             this->recordHWSamplerMatrix(s, drawState.getSampler(s).getMatrix());
    520         }
    521     }
    522 }
    523 
    524 void GrGpuGLShaders::flushRadial2(int s) {
    525 
    526     const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
    527     const GrSamplerState& sampler = this->getDrawState().getSampler(s);
    528     if (GrGLProgram::kUnusedUniform != uni &&
    529         (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
    530          fProgramData->fRadial2Radius0[s]  != sampler.getRadial2Radius0()  ||
    531          fProgramData->fRadial2PosRoot[s]  != sampler.isRadial2PosRoot())) {
    532 
    533         GrScalar centerX1 = sampler.getRadial2CenterX1();
    534         GrScalar radius0 = sampler.getRadial2Radius0();
    535 
    536         GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
    537 
    538         // when were in the degenerate (linear) case the second
    539         // value will be INF but the program doesn't read it. (We
    540         // use the same 6 uniforms even though we don't need them
    541         // all in the linear case just to keep the code complexity
    542         // down).
    543         float values[6] = {
    544             GrScalarToFloat(a),
    545             1 / (2.f * GrScalarToFloat(a)),
    546             GrScalarToFloat(centerX1),
    547             GrScalarToFloat(radius0),
    548             GrScalarToFloat(GrMul(radius0, radius0)),
    549             sampler.isRadial2PosRoot() ? 1.f : -1.f
    550         };
    551         GL_CALL(Uniform1fv(uni, 6, values));
    552         fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
    553         fProgramData->fRadial2Radius0[s]  = sampler.getRadial2Radius0();
    554         fProgramData->fRadial2PosRoot[s]  = sampler.isRadial2PosRoot();
    555     }
    556 }
    557 
    558 void GrGpuGLShaders::flushConvolution(int s) {
    559     const GrSamplerState& sampler = this->getDrawState().getSampler(s);
    560     int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni;
    561     if (GrGLProgram::kUnusedUniform != kernelUni) {
    562         GL_CALL(Uniform1fv(kernelUni, sampler.getKernelWidth(),
    563                            sampler.getKernel()));
    564     }
    565     int imageIncrementUni = fProgramData->fUniLocations.fStages[s].fImageIncrementUni;
    566     if (GrGLProgram::kUnusedUniform != imageIncrementUni) {
    567         const GrGLTexture* texture =
    568             static_cast<const GrGLTexture*>(this->getDrawState().getTexture(s));
    569         float imageIncrement[2] = { 0 };
    570         switch (sampler.getFilterDirection()) {
    571             case GrSamplerState::kX_FilterDirection:
    572                 imageIncrement[0] = 1.0f / texture->width();
    573                 break;
    574             case GrSamplerState::kY_FilterDirection:
    575                 imageIncrement[1] = 1.0f / texture->height();
    576                 break;
    577             default:
    578                 GrCrash("Unknown filter direction.");
    579         }
    580         GL_CALL(Uniform2fv(imageIncrementUni, 1, imageIncrement));
    581     }
    582 }
    583 
    584 void GrGpuGLShaders::flushTexelSize(int s) {
    585     const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
    586     if (GrGLProgram::kUnusedUniform != uni) {
    587         const GrGLTexture* texture =
    588             static_cast<const GrGLTexture*>(this->getDrawState().getTexture(s));
    589         if (texture->width() != fProgramData->fTextureWidth[s] ||
    590             texture->height() != fProgramData->fTextureHeight[s]) {
    591 
    592             float texelSize[] = {1.f / texture->width(),
    593                                  1.f / texture->height()};
    594             GL_CALL(Uniform2fv(uni, 1, texelSize));
    595             fProgramData->fTextureWidth[s] = texture->width();
    596             fProgramData->fTextureHeight[s] = texture->height();
    597         }
    598     }
    599 }
    600 
    601 void GrGpuGLShaders::flushEdgeAAData() {
    602     const int& uni = fProgramData->fUniLocations.fEdgesUni;
    603     if (GrGLProgram::kUnusedUniform != uni) {
    604         int count = this->getDrawState().getNumAAEdges();
    605         GrDrawState::Edge edges[GrDrawState::kMaxEdges];
    606         // Flip the edges in Y
    607         float height =
    608             static_cast<float>(this->getDrawState().getRenderTarget()->height());
    609         for (int i = 0; i < count; ++i) {
    610             edges[i] = this->getDrawState().getAAEdges()[i];
    611             float b = edges[i].fY;
    612             edges[i].fY = -b;
    613             edges[i].fZ += b * height;
    614         }
    615         GL_CALL(Uniform3fv(uni, count, &edges[0].fX));
    616     }
    617 }
    618 
    619 void GrGpuGLShaders::flushColorMatrix() {
    620     const ProgramDesc& desc = fCurrentProgram.getDesc();
    621     int matrixUni = fProgramData->fUniLocations.fColorMatrixUni;
    622     int vecUni = fProgramData->fUniLocations.fColorMatrixVecUni;
    623     if (GrGLProgram::kUnusedUniform != matrixUni
    624      && GrGLProgram::kUnusedUniform != vecUni) {
    625         const float* m = this->getDrawState().getColorMatrix();
    626         GrGLfloat mt[]  = {
    627             m[0], m[5], m[10], m[15],
    628             m[1], m[6], m[11], m[16],
    629             m[2], m[7], m[12], m[17],
    630             m[3], m[8], m[13], m[18],
    631         };
    632         static float scale = 1.0f / 255.0f;
    633         GrGLfloat vec[] = {
    634             m[4] * scale, m[9] * scale, m[14] * scale, m[19] * scale,
    635         };
    636         GL_CALL(UniformMatrix4fv(matrixUni, 1, false, mt));
    637         GL_CALL(Uniform4fv(vecUni, 1, vec));
    638     }
    639 }
    640 
    641 static const float ONE_OVER_255 = 1.f / 255.f;
    642 
    643 #define GR_COLOR_TO_VEC4(color) {\
    644     GrColorUnpackR(color) * ONE_OVER_255,\
    645     GrColorUnpackG(color) * ONE_OVER_255,\
    646     GrColorUnpackB(color) * ONE_OVER_255,\
    647     GrColorUnpackA(color) * ONE_OVER_255 \
    648 }
    649 
    650 void GrGpuGLShaders::flushColor(GrColor color) {
    651     const ProgramDesc& desc = fCurrentProgram.getDesc();
    652     const GrDrawState& drawState = this->getDrawState();
    653 
    654     if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
    655         // color will be specified per-vertex as an attribute
    656         // invalidate the const vertex attrib color
    657         fHWDrawState.setColor(GrColor_ILLEGAL);
    658     } else {
    659         switch (desc.fColorInput) {
    660             case ProgramDesc::kAttribute_ColorInput:
    661                 if (fHWDrawState.getColor() != color) {
    662                     // OpenGL ES only supports the float varieties of
    663                     // glVertexAttrib
    664                     float c[] = GR_COLOR_TO_VEC4(color);
    665                     GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(),
    666                                             c));
    667                     fHWDrawState.setColor(color);
    668                 }
    669                 break;
    670             case ProgramDesc::kUniform_ColorInput:
    671                 if (fProgramData->fColor != color) {
    672                     // OpenGL ES doesn't support unsigned byte varieties of
    673                     // glUniform
    674                     float c[] = GR_COLOR_TO_VEC4(color);
    675                     GrAssert(GrGLProgram::kUnusedUniform !=
    676                              fProgramData->fUniLocations.fColorUni);
    677                     GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorUni,
    678                                         1, c));
    679                     fProgramData->fColor = color;
    680                 }
    681                 break;
    682             case ProgramDesc::kSolidWhite_ColorInput:
    683             case ProgramDesc::kTransBlack_ColorInput:
    684                 break;
    685             default:
    686                 GrCrash("Unknown color type.");
    687         }
    688     }
    689     if (fProgramData->fUniLocations.fColorFilterUni
    690                 != GrGLProgram::kUnusedUniform
    691             && fProgramData->fColorFilterColor
    692                 != drawState.getColorFilterColor()) {
    693         float c[] = GR_COLOR_TO_VEC4(drawState.getColorFilterColor());
    694         GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c));
    695         fProgramData->fColorFilterColor = drawState.getColorFilterColor();
    696     }
    697 }
    698 
    699 void GrGpuGLShaders::flushCoverage(GrColor coverage) {
    700     const ProgramDesc& desc = fCurrentProgram.getDesc();
    701     const GrDrawState& drawState = this->getDrawState();
    702 
    703 
    704     if (this->getGeomSrc().fVertexLayout & kCoverage_VertexLayoutBit) {
    705         // coverage will be specified per-vertex as an attribute
    706         // invalidate the const vertex attrib coverage
    707         fHWDrawState.setCoverage4(GrColor_ILLEGAL);
    708     } else {
    709         switch (desc.fCoverageInput) {
    710             case ProgramDesc::kAttribute_ColorInput:
    711                 if (fHWDrawState.getCoverage() != coverage) {
    712                     // OpenGL ES only supports the float varieties of
    713                     // glVertexAttrib
    714                     float c[] = GR_COLOR_TO_VEC4(coverage);
    715                     GL_CALL(VertexAttrib4fv(GrGLProgram::CoverageAttributeIdx(),
    716                                             c));
    717                     fHWDrawState.setCoverage(coverage);
    718                 }
    719                 break;
    720             case ProgramDesc::kUniform_ColorInput:
    721                 if (fProgramData->fCoverage != coverage) {
    722                     // OpenGL ES doesn't support unsigned byte varieties of
    723                     // glUniform
    724                     float c[] = GR_COLOR_TO_VEC4(coverage);
    725                     GrAssert(GrGLProgram::kUnusedUniform !=
    726                              fProgramData->fUniLocations.fCoverageUni);
    727                     GL_CALL(Uniform4fv(fProgramData->fUniLocations.fCoverageUni,
    728                                         1, c));
    729                     fProgramData->fCoverage = coverage;
    730                 }
    731                 break;
    732             case ProgramDesc::kSolidWhite_ColorInput:
    733             case ProgramDesc::kTransBlack_ColorInput:
    734                 break;
    735             default:
    736                 GrCrash("Unknown coverage type.");
    737         }
    738     }
    739 }
    740 
    741 bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
    742     if (!flushGLStateCommon(type)) {
    743         return false;
    744     }
    745 
    746     const GrDrawState& drawState = this->getDrawState();
    747 
    748     if (fDirtyFlags.fRenderTargetChanged) {
    749         // our coords are in pixel space and the GL matrices map to NDC
    750         // so if the viewport changed, our matrix is now wrong.
    751         fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
    752         // we assume all shader matrices may be wrong after viewport changes
    753         fProgramCache->invalidateViewMatrices();
    754     }
    755 
    756     GrBlendCoeff srcCoeff;
    757     GrBlendCoeff dstCoeff;
    758     BlendOptFlags blendOpts = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
    759     if (kSkipDraw_BlendOptFlag & blendOpts) {
    760         return false;
    761     }
    762 
    763     this->buildProgram(type, blendOpts, dstCoeff);
    764     fProgramData = fProgramCache->getProgramData(fCurrentProgram);
    765     if (NULL == fProgramData) {
    766         GrAssert(!"Failed to create program!");
    767         return false;
    768     }
    769 
    770     if (fHWProgramID != fProgramData->fProgramID) {
    771         GL_CALL(UseProgram(fProgramData->fProgramID));
    772         fHWProgramID = fProgramData->fProgramID;
    773     }
    774     fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff);
    775     this->flushBlend(type, srcCoeff, dstCoeff);
    776 
    777     GrColor color;
    778     GrColor coverage;
    779     if (blendOpts & kEmitTransBlack_BlendOptFlag) {
    780         color = 0;
    781         coverage = 0;
    782     } else if (blendOpts & kEmitCoverage_BlendOptFlag) {
    783         color = 0xffffffff;
    784         coverage = drawState.getCoverage();
    785     } else {
    786         color = drawState.getColor();
    787         coverage = drawState.getCoverage();
    788     }
    789     this->flushColor(color);
    790     this->flushCoverage(coverage);
    791 
    792     this->flushViewMatrix();
    793 
    794     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    795         if (this->isStageEnabled(s)) {
    796             this->flushTextureMatrix(s);
    797 
    798             this->flushRadial2(s);
    799 
    800             this->flushConvolution(s);
    801 
    802             this->flushTexelSize(s);
    803 
    804             this->flushTextureDomain(s);
    805         }
    806     }
    807     this->flushEdgeAAData();
    808     this->flushColorMatrix();
    809     resetDirtyFlags();
    810     return true;
    811 }
    812 
    813 void GrGpuGLShaders::postDraw() {
    814 }
    815 
    816 void GrGpuGLShaders::setupGeometry(int* startVertex,
    817                                     int* startIndex,
    818                                     int vertexCount,
    819                                     int indexCount) {
    820 
    821     int newColorOffset;
    822     int newCoverageOffset;
    823     int newTexCoordOffsets[GrDrawState::kMaxTexCoords];
    824     int newEdgeOffset;
    825 
    826     GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
    827                                             this->getGeomSrc().fVertexLayout,
    828                                             newTexCoordOffsets,
    829                                             &newColorOffset,
    830                                             &newCoverageOffset,
    831                                             &newEdgeOffset);
    832     int oldColorOffset;
    833     int oldCoverageOffset;
    834     int oldTexCoordOffsets[GrDrawState::kMaxTexCoords];
    835     int oldEdgeOffset;
    836 
    837     GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
    838                                             fHWGeometryState.fVertexLayout,
    839                                             oldTexCoordOffsets,
    840                                             &oldColorOffset,
    841                                             &oldCoverageOffset,
    842                                             &oldEdgeOffset);
    843     bool indexed = NULL != startIndex;
    844 
    845     int extraVertexOffset;
    846     int extraIndexOffset;
    847     this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
    848 
    849     GrGLenum scalarType;
    850     bool texCoordNorm;
    851     if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
    852         scalarType = GrGLTextType;
    853         texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
    854     } else {
    855         scalarType = GrGLType;
    856         texCoordNorm = false;
    857     }
    858 
    859     size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
    860     *startVertex = 0;
    861     if (indexed) {
    862         *startIndex += extraIndexOffset;
    863     }
    864 
    865     // all the Pointers must be set if any of these are true
    866     bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
    867                              vertexOffset != fHWGeometryState.fVertexOffset ||
    868                              newStride != oldStride;
    869 
    870     // position and tex coord offsets change if above conditions are true
    871     // or the type/normalization changed based on text vs nontext type coords.
    872     bool posAndTexChange = allOffsetsChange ||
    873                            (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
    874                                 (kTextFormat_VertexLayoutBit &
    875                                   (fHWGeometryState.fVertexLayout ^
    876                                    this->getGeomSrc().fVertexLayout)));
    877 
    878     if (posAndTexChange) {
    879         int idx = GrGLProgram::PositionAttributeIdx();
    880         GL_CALL(VertexAttribPointer(idx, 2, scalarType, false, newStride,
    881                                   (GrGLvoid*)vertexOffset));
    882         fHWGeometryState.fVertexOffset = vertexOffset;
    883     }
    884 
    885     for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
    886         if (newTexCoordOffsets[t] > 0) {
    887             GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]);
    888             int idx = GrGLProgram::TexCoordAttributeIdx(t);
    889             if (oldTexCoordOffsets[t] <= 0) {
    890                 GL_CALL(EnableVertexAttribArray(idx));
    891                 GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
    892                                           newStride, texCoordOffset));
    893             } else if (posAndTexChange ||
    894                        newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
    895                 GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
    896                                           newStride, texCoordOffset));
    897             }
    898         } else if (oldTexCoordOffsets[t] > 0) {
    899             GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
    900         }
    901     }
    902 
    903     if (newColorOffset > 0) {
    904         GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
    905         int idx = GrGLProgram::ColorAttributeIdx();
    906         if (oldColorOffset <= 0) {
    907             GL_CALL(EnableVertexAttribArray(idx));
    908             GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
    909                                       true, newStride, colorOffset));
    910         } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
    911             GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
    912                                       true, newStride, colorOffset));
    913         }
    914     } else if (oldColorOffset > 0) {
    915         GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
    916     }
    917 
    918     if (newCoverageOffset > 0) {
    919         GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset);
    920         int idx = GrGLProgram::CoverageAttributeIdx();
    921         if (oldCoverageOffset <= 0) {
    922             GL_CALL(EnableVertexAttribArray(idx));
    923             GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
    924                                         true, newStride, coverageOffset));
    925         } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) {
    926             GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
    927                                         true, newStride, coverageOffset));
    928         }
    929     } else if (oldCoverageOffset > 0) {
    930         GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx()));
    931     }
    932 
    933     if (newEdgeOffset > 0) {
    934         GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset);
    935         int idx = GrGLProgram::EdgeAttributeIdx();
    936         if (oldEdgeOffset <= 0) {
    937             GL_CALL(EnableVertexAttribArray(idx));
    938             GL_CALL(VertexAttribPointer(idx, 4, scalarType,
    939                                         false, newStride, edgeOffset));
    940         } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) {
    941             GL_CALL(VertexAttribPointer(idx, 4, scalarType,
    942                                         false, newStride, edgeOffset));
    943         }
    944     } else if (oldEdgeOffset > 0) {
    945         GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
    946     }
    947 
    948     fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
    949     fHWGeometryState.fArrayPtrsDirty = false;
    950 }
    951 
    952 void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
    953                                   BlendOptFlags blendOpts,
    954                                   GrBlendCoeff dstCoeff) {
    955     ProgramDesc& desc = fCurrentProgram.fProgramDesc;
    956     const GrDrawState& drawState = this->getDrawState();
    957 
    958     // This should already have been caught
    959     GrAssert(!(kSkipDraw_BlendOptFlag & blendOpts));
    960 
    961     bool skipCoverage = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
    962 
    963     bool skipColor = SkToBool(blendOpts & (kEmitTransBlack_BlendOptFlag |
    964                                            kEmitCoverage_BlendOptFlag));
    965 
    966     // The descriptor is used as a cache key. Thus when a field of the
    967     // descriptor will not affect program generation (because of the vertex
    968     // layout in use or other descriptor field settings) it should be set
    969     // to a canonical value to avoid duplicate programs with different keys.
    970 
    971     // Must initialize all fields or cache will have false negatives!
    972     desc.fVertexLayout = this->getGeomSrc().fVertexLayout;
    973 
    974     desc.fEmitsPointSize = kPoints_PrimitiveType == type;
    975 
    976     bool requiresAttributeColors =
    977         !skipColor && SkToBool(desc.fVertexLayout & kColor_VertexLayoutBit);
    978     bool requiresAttributeCoverage =
    979         !skipCoverage && SkToBool(desc.fVertexLayout &
    980                                   kCoverage_VertexLayoutBit);
    981 
    982     // fColorInput/fCoverageInput records how colors are specified for the.
    983     // program. So we strip the bits from the layout to avoid false negatives
    984     // when searching for an existing program in the cache.
    985     desc.fVertexLayout &= ~(kColor_VertexLayoutBit | kCoverage_VertexLayoutBit);
    986 
    987     desc.fColorFilterXfermode = skipColor ?
    988                                 SkXfermode::kDst_Mode :
    989                                 drawState.getColorFilterMode();
    990 
    991     desc.fColorMatrixEnabled = drawState.isStateFlagEnabled(GrDrawState::kColorMatrix_StateBit);
    992 
    993     // no reason to do edge aa or look at per-vertex coverage if coverage is
    994     // ignored
    995     if (skipCoverage) {
    996         desc.fVertexLayout &= ~(kEdge_VertexLayoutBit |
    997                                 kCoverage_VertexLayoutBit);
    998     }
    999 
   1000     bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
   1001     bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) ||
   1002                              (!requiresAttributeColors &&
   1003                               0xffffffff == drawState.getColor());
   1004     if (GR_AGGRESSIVE_SHADER_OPTS && colorIsTransBlack) {
   1005         desc.fColorInput = ProgramDesc::kTransBlack_ColorInput;
   1006     } else if (GR_AGGRESSIVE_SHADER_OPTS && colorIsSolidWhite) {
   1007         desc.fColorInput = ProgramDesc::kSolidWhite_ColorInput;
   1008     } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) {
   1009         desc.fColorInput = ProgramDesc::kUniform_ColorInput;
   1010     } else {
   1011         desc.fColorInput = ProgramDesc::kAttribute_ColorInput;
   1012     }
   1013 
   1014     bool covIsSolidWhite = !requiresAttributeCoverage &&
   1015                            0xffffffff == drawState.getCoverage();
   1016 
   1017     if (skipCoverage) {
   1018         desc.fCoverageInput = ProgramDesc::kTransBlack_ColorInput;
   1019     } else if (covIsSolidWhite) {
   1020         desc.fCoverageInput = ProgramDesc::kSolidWhite_ColorInput;
   1021     } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) {
   1022         desc.fCoverageInput = ProgramDesc::kUniform_ColorInput;
   1023     } else {
   1024         desc.fCoverageInput = ProgramDesc::kAttribute_ColorInput;
   1025     }
   1026 
   1027     desc.fEdgeAANumEdges = skipCoverage ? 0 : drawState.getNumAAEdges();
   1028     desc.fEdgeAAConcave = desc.fEdgeAANumEdges > 0 &&
   1029                           drawState.isConcaveEdgeAAState();
   1030 
   1031     int lastEnabledStage = -1;
   1032 
   1033     if (!skipCoverage && (desc.fVertexLayout &
   1034                           GrDrawTarget::kEdge_VertexLayoutBit)) {
   1035         desc.fVertexEdgeType = drawState.getVertexEdgeType();
   1036     } else {
   1037         // use canonical value when not set to avoid cache misses
   1038         desc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
   1039     }
   1040 
   1041     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
   1042         StageDesc& stage = desc.fStages[s];
   1043 
   1044         stage.fOptFlags = 0;
   1045         stage.setEnabled(this->isStageEnabled(s));
   1046 
   1047         bool skip = s < drawState.getFirstCoverageStage() ? skipColor :
   1048                                                              skipCoverage;
   1049 
   1050         if (!skip && stage.isEnabled()) {
   1051             lastEnabledStage = s;
   1052             const GrGLTexture* texture =
   1053                 static_cast<const GrGLTexture*>(drawState.getTexture(s));
   1054             GrAssert(NULL != texture);
   1055             const GrSamplerState& sampler = drawState.getSampler(s);
   1056             // we matrix to invert when orientation is TopDown, so make sure
   1057             // we aren't in that case before flagging as identity.
   1058             if (TextureMatrixIsIdentity(texture, sampler)) {
   1059                 stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
   1060             } else if (!sampler.getMatrix().hasPerspective()) {
   1061                 stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
   1062             }
   1063             switch (sampler.getSampleMode()) {
   1064                 case GrSamplerState::kNormal_SampleMode:
   1065                     stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
   1066                     break;
   1067                 case GrSamplerState::kRadial_SampleMode:
   1068                     stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
   1069                     break;
   1070                 case GrSamplerState::kRadial2_SampleMode:
   1071                     if (sampler.radial2IsDegenerate()) {
   1072                         stage.fCoordMapping =
   1073                             StageDesc::kRadial2GradientDegenerate_CoordMapping;
   1074                     } else {
   1075                         stage.fCoordMapping =
   1076                             StageDesc::kRadial2Gradient_CoordMapping;
   1077                     }
   1078                     break;
   1079                 case GrSamplerState::kSweep_SampleMode:
   1080                     stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
   1081                     break;
   1082                 default:
   1083                     GrCrash("Unexpected sample mode!");
   1084                     break;
   1085             }
   1086 
   1087             switch (sampler.getFilter()) {
   1088                 // these both can use a regular texture2D()
   1089                 case GrSamplerState::kNearest_Filter:
   1090                 case GrSamplerState::kBilinear_Filter:
   1091                     stage.fFetchMode = StageDesc::kSingle_FetchMode;
   1092                     break;
   1093                 // performs 4 texture2D()s
   1094                 case GrSamplerState::k4x4Downsample_Filter:
   1095                     stage.fFetchMode = StageDesc::k2x2_FetchMode;
   1096                     break;
   1097                 // performs fKernelWidth texture2D()s
   1098                 case GrSamplerState::kConvolution_Filter:
   1099                     stage.fFetchMode = StageDesc::kConvolution_FetchMode;
   1100                     break;
   1101                 case GrSamplerState::kDilate_Filter:
   1102                     stage.fFetchMode = StageDesc::kDilate_FetchMode;
   1103                     break;
   1104                 case GrSamplerState::kErode_Filter:
   1105                     stage.fFetchMode = StageDesc::kErode_FetchMode;
   1106                     break;
   1107                 default:
   1108                     GrCrash("Unexpected filter!");
   1109                     break;
   1110             }
   1111 
   1112             if (sampler.hasTextureDomain()) {
   1113                 GrAssert(GrSamplerState::kClamp_WrapMode ==
   1114                             sampler.getWrapX() &&
   1115                          GrSamplerState::kClamp_WrapMode ==
   1116                             sampler.getWrapY());
   1117                 stage.fOptFlags |= StageDesc::kCustomTextureDomain_OptFlagBit;
   1118             }
   1119 
   1120             stage.fInConfigFlags = 0;
   1121             if (!this->glCaps().textureSwizzleSupport()) {
   1122                 if (GrPixelConfigIsAlphaOnly(texture->config())) {
   1123                     // if we don't have texture swizzle support then
   1124                     // the shader must do an alpha smear after reading
   1125                     // the texture
   1126                     stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
   1127                 } else if (sampler.swapsRAndB()) {
   1128                     stage.fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag;
   1129                 }
   1130             }
   1131             if (GrPixelConfigIsUnpremultiplied(texture->config())) {
   1132                 // The shader generator assumes that color channels are bytes
   1133                 // when rounding.
   1134                 GrAssert(4 == GrBytesPerPixel(texture->config()));
   1135                 if (kUpOnWrite_DownOnRead_UnpremulConversion ==
   1136                     fUnpremulConversion) {
   1137                     stage.fInConfigFlags |=
   1138                         StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
   1139                 } else {
   1140                     stage.fInConfigFlags |=
   1141                         StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag;
   1142                 }
   1143             }
   1144 
   1145             if (sampler.getFilter() == GrSamplerState::kConvolution_Filter ||
   1146                 sampler.getFilter() == GrSamplerState::kDilate_Filter ||
   1147                 sampler.getFilter() == GrSamplerState::kErode_Filter) {
   1148                 stage.fKernelWidth = sampler.getKernelWidth();
   1149             } else {
   1150                 stage.fKernelWidth = 0;
   1151             }
   1152         } else {
   1153             stage.fOptFlags         = 0;
   1154             stage.fCoordMapping     = (StageDesc::CoordMapping) 0;
   1155             stage.fInConfigFlags    = 0;
   1156             stage.fFetchMode        = (StageDesc::FetchMode) 0;
   1157             stage.fKernelWidth      = 0;
   1158         }
   1159     }
   1160 
   1161     if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
   1162         // The shader generator assumes that color channels are bytes
   1163         // when rounding.
   1164         GrAssert(4 == GrBytesPerPixel(drawState.getRenderTarget()->config()));
   1165         if (kUpOnWrite_DownOnRead_UnpremulConversion == fUnpremulConversion) {
   1166             desc.fOutputConfig =
   1167                 ProgramDesc::kUnpremultiplied_RoundUp_OutputConfig;
   1168         } else {
   1169             desc.fOutputConfig =
   1170                 ProgramDesc::kUnpremultiplied_RoundDown_OutputConfig;
   1171         }
   1172     } else {
   1173         desc.fOutputConfig = ProgramDesc::kPremultiplied_OutputConfig;
   1174     }
   1175 
   1176     desc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;
   1177 
   1178     // currently the experimental GS will only work with triangle prims
   1179     // (and it doesn't do anything other than pass through values from
   1180     // the VS to the FS anyway).
   1181 #if 0 && GR_GL_EXPERIMENTAL_GS
   1182     desc.fExperimentalGS = this->getCaps().fGeometryShaderSupport;
   1183 #endif
   1184 
   1185     // we want to avoid generating programs with different "first cov stage"
   1186     // values when they would compute the same result.
   1187     // We set field in the desc to kNumStages when either there are no
   1188     // coverage stages or the distinction between coverage and color is
   1189     // immaterial.
   1190     int firstCoverageStage = GrDrawState::kNumStages;
   1191     desc.fFirstCoverageStage = GrDrawState::kNumStages;
   1192     bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage;
   1193     if (hasCoverage) {
   1194         firstCoverageStage = drawState.getFirstCoverageStage();
   1195     }
   1196 
   1197     // other coverage inputs
   1198     if (!hasCoverage) {
   1199         hasCoverage =
   1200                desc.fEdgeAANumEdges ||
   1201                requiresAttributeCoverage ||
   1202                (desc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit);
   1203     }
   1204 
   1205     if (hasCoverage) {
   1206         // color filter is applied between color/coverage computation
   1207         if (SkXfermode::kDst_Mode != desc.fColorFilterXfermode) {
   1208             desc.fFirstCoverageStage = firstCoverageStage;
   1209         }
   1210 
   1211         if (this->getCaps().fDualSourceBlendingSupport &&
   1212             !(blendOpts & (kEmitCoverage_BlendOptFlag |
   1213                            kCoverageAsAlpha_BlendOptFlag))) {
   1214             if (kZero_BlendCoeff == dstCoeff) {
   1215                 // write the coverage value to second color
   1216                 desc.fDualSrcOutput =  ProgramDesc::kCoverage_DualSrcOutput;
   1217                 desc.fFirstCoverageStage = firstCoverageStage;
   1218             } else if (kSA_BlendCoeff == dstCoeff) {
   1219                 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
   1220                 // cover
   1221                 desc.fDualSrcOutput = ProgramDesc::kCoverageISA_DualSrcOutput;
   1222                 desc.fFirstCoverageStage = firstCoverageStage;
   1223             } else if (kSC_BlendCoeff == dstCoeff) {
   1224                 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
   1225                 // cover
   1226                 desc.fDualSrcOutput = ProgramDesc::kCoverageISC_DualSrcOutput;
   1227                 desc.fFirstCoverageStage = firstCoverageStage;
   1228             }
   1229         }
   1230     }
   1231 }
   1232