11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "../GrBinHashKey.h"
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrGLProgram.h"
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrGLSL.h"
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrGpuGLShaders.h"
144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "../GrGpuVertex.h"
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrNoncopyable.h"
164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "../GrStringBuilder.h"
174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "../GrRandom.h"
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define SKIP_CACHE_CHECK    true
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define GR_UINT32_MAX   static_cast<uint32_t>(-1)
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "../GrTHashCache.h"
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass GrGpuGLShaders::ProgramCache : public ::GrNoncopyable {
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    class Entry;
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef GrBinHashKey<Entry, GrGLProgram::kProgramKeySize> ProgramHashKey;
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    class Entry : public ::GrNoncopyable {
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    public:
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Entry() {}
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        void copyAndTakeOwnership(Entry& entry) {
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProgramData.copyAndTakeOwnership(entry.fProgramData);
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fKey = entry.fKey; // ownership transfer
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fLRUStamp = entry.fLRUStamp;
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    public:
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int compare(const ProgramHashKey& key) const { return fKey.compare(key); }
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    public:
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrGLProgram::CachedData fProgramData;
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ProgramHashKey          fKey;
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        unsigned int            fLRUStamp;
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTHashTable<Entry, ProgramHashKey, 8> fHashCache;
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We may have kMaxEntries+1 shaders in the GL context because
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we create a new shader before evicting from the cache.
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    enum {
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kMaxEntries = 32
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    Entry                       fEntries[kMaxEntries];
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int                         fCount;
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    unsigned int                fCurrLRUStamp;
584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    const GrGLContextInfo&      fGL;
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    ProgramCache(const GrGLContextInfo& gl)
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        : fCount(0)
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        , fCurrLRUStamp(0)
644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        , fGL(gl) {
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ~ProgramCache() {
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < fCount; ++i) {
694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            GrGpuGLShaders::DeleteProgram(fGL.interface(),
704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                          &fEntries[i].fProgramData);
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    void abandon() {
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fCount = 0;
761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    void invalidateViewMatrices() {
791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < fCount; ++i) {
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // set to illegal matrix
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fEntries[i].fProgramData.fViewMatrix = GrMatrix::InvalidMatrix();
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc) {
861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Entry newEntry;
871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        newEntry.fKey.setKeyData(desc.keyData());
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        Entry* entry = fHashCache.find(newEntry.fKey);
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL == entry) {
914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            if (!desc.genProgram(fGL, &newEntry.fProgramData)) {
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return NULL;
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (fCount < kMaxEntries) {
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                entry = fEntries + fCount;
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                ++fCount;
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrAssert(kMaxEntries == fCount);
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                entry = fEntries;
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                for (int i = 1; i < kMaxEntries; ++i) {
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        entry = fEntries + i;
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    }
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fHashCache.remove(entry->fKey, entry);
1064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                GrGpuGLShaders::DeleteProgram(fGL.interface(),
1074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                              &entry->fProgramData);
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            entry->copyAndTakeOwnership(newEntry);
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fHashCache.insert(entry->fKey, entry);
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        entry->fLRUStamp = fCurrLRUStamp;
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (GR_UINT32_MAX == fCurrLRUStamp) {
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // wrap around! just trash our LRU, one time hit.
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (int i = 0; i < fCount; ++i) {
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fEntries[i].fLRUStamp = 0;
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ++fCurrLRUStamp;
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return &entry->fProgramData;
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::abandonResources(){
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    INHERITED::abandonResources();
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fProgramCache->abandon();
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl,
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   CachedData* programData) {
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GR_GL_CALL(gl, DeleteShader(programData->fVShaderID));
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (programData->fGShaderID) {
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GR_GL_CALL(gl, DeleteShader(programData->fGShaderID));
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GR_GL_CALL(gl, DeleteShader(programData->fFShaderID));
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GR_GL_CALL(gl, DeleteProgram(programData->fProgramID));
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GR_DEBUGCODE(memset(programData, 0, sizeof(*programData));)
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace {
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// GrRandoms nextU() values have patterns in the low bits
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// So using nextU() % array_count might never take some values.
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint random_int(GrRandom* r, int count) {
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return (int)(r->nextF() * count);
1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// min is inclusive, max is exclusive
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint random_int(GrRandom* r, int min, int max) {
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return (int)(r->nextF() * (max-min)) + min;
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool random_bool(GrRandom* r) {
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return r->nextF() > .5f;
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrGpuGLShaders::programUnitTest() {
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrGLSLGeneration glslGeneration =
1674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            GrGetGLSLGeneration(this->glBinding(), this->glInterface());
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const int STAGE_OPTS[] = {
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        0,
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        StageDesc::kNoPerspective_OptFlagBit,
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        StageDesc::kIdentity_CoordMapping
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const int IN_CONFIG_FLAGS[] = {
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        StageDesc::kNone_InConfigFlag,
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        StageDesc::kSwapRAndB_InConfigFlag,
1764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        StageDesc::kSwapRAndB_InConfigFlag |
1774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag,
1784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag,
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        StageDesc::kSmearAlpha_InConfigFlag,
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrGLProgram program;
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ProgramDesc& pdesc = program.fProgramDesc;
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const int NUM_TESTS = 512;
1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRandom random;
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int t = 0; t < NUM_TESTS; ++t) {
1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 0
1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("\nTest Program %d\n-------------\n", t);
1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static const int stop = -1;
1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (t == stop) {
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int breakpointhere = 9;
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fVertexLayout = 0;
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fEmitsPointSize = random.nextF() > .5f;
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fColorInput = random_int(&random, ProgramDesc::kColorInputCnt);
2004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        pdesc.fCoverageInput = random_int(&random, ProgramDesc::kColorInputCnt);
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fColorFilterXfermode = random_int(&random, SkXfermode::kCoeffModesCnt);
2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fFirstCoverageStage = random_int(&random, GrDrawState::kNumStages);
2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fVertexLayout |= random_bool(&random) ?
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    GrDrawTarget::kCoverage_VertexLayoutBit :
2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    0;
2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_GL_EXPERIMENTAL_GS
2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fExperimentalGS = this->getCaps().fGeometryShaderSupport &&
2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                random_bool(&random);
2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
2144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        pdesc.fOutputConfig =  random_int(&random, ProgramDesc::kOutputConfigCnt);
2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool edgeAA = random_bool(&random);
2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (edgeAA) {
2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            bool vertexEdgeAA = random_bool(&random);
2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (vertexEdgeAA) {
2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pdesc.fVertexLayout |= GrDrawTarget::kEdge_VertexLayoutBit;
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (this->getCaps().fShaderDerivativeSupport) {
2224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    pdesc.fVertexEdgeType = (GrDrawState::VertexEdgeType) random_int(&random, GrDrawState::kVertexEdgeTypeCnt);
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                } else {
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    pdesc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pdesc.fEdgeAANumEdges = 0;
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pdesc.fEdgeAANumEdges = random_int(&random, 1, this->getMaxEdges());
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pdesc.fEdgeAAConcave = random_bool(&random);
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            pdesc.fEdgeAANumEdges = 0;
2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pdesc.fColorMatrixEnabled = random_bool(&random);
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (this->getCaps().fDualSourceBlendingSupport) {
2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            pdesc.fDualSrcOutput = random_int(&random, ProgramDesc::kDualSrcOutputCnt);
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            pdesc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // enable the stage?
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (random_bool(&random)) {
2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // use separate tex coords?
2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (random_bool(&random)) {
2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    int t = random_int(&random, GrDrawState::kMaxTexCoords);
2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t);
2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                } else {
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    pdesc.fVertexLayout |= StagePosAsTexCoordVertexLayoutBit(s);
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // use text-formatted verts?
2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (random_bool(&random)) {
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            StageDesc& stage = pdesc.fStages[s];
2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fOptFlags = STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))];
2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fInConfigFlags = IN_CONFIG_FLAGS[random_int(&random, GR_ARRAY_COUNT(IN_CONFIG_FLAGS))];
2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fCoordMapping =  random_int(&random, StageDesc::kCoordMappingCnt);
2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fFetchMode = random_int(&random, StageDesc::kFetchModeCnt);
2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // convolution shaders don't work with persp tex matrix
2644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            if (stage.fFetchMode == StageDesc::kConvolution_FetchMode ||
2654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                stage.fFetchMode == StageDesc::kDilate_FetchMode ||
2664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                stage.fFetchMode == StageDesc::kErode_FetchMode) {
2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.setEnabled(VertexUsesStage(s, pdesc.fVertexLayout));
2704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            static const uint32_t kMulByAlphaMask =
2714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
2724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            switch (stage.fFetchMode) {
2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case StageDesc::kSingle_FetchMode:
2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fKernelWidth = 0;
2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case StageDesc::kConvolution_FetchMode:
2784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                case StageDesc::kDilate_FetchMode:
2794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                case StageDesc::kErode_FetchMode:
2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fKernelWidth = random_int(&random, 2, 8);
2814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    stage.fInConfigFlags &= ~kMulByAlphaMask;
2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case StageDesc::k2x2_FetchMode:
2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fKernelWidth = 0;
2854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    stage.fInConfigFlags &= ~kMulByAlphaMask;
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        CachedData cachedData;
2904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (!program.genProgram(this->glContextInfo(), &cachedData)) {
2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return false;
2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        DeleteProgram(this->glInterface(), &cachedData);
2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2984f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerGrGpuGLShaders::GrGpuGLShaders(const GrGLContextInfo& ctxInfo)
2994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    : GrGpuGL(ctxInfo) {
3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Enable supported shader-related caps
3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kDesktop_GrGLBinding == this->glBinding()) {
3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fCaps.fDualSourceBlendingSupport =
3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            this->glVersion() >= GR_GL_VER(3,3) ||
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            this->hasExtension("GL_ARB_blend_func_extended");
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fCaps.fShaderDerivativeSupport = true;
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fCaps.fGeometryShaderSupport =
3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                this->glVersion() >= GR_GL_VER(3,2) &&
3104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                this->glslGeneration() >= k150_GrGLSLGeneration;
3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fCaps.fShaderDerivativeSupport =
3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            this->hasExtension("GL_OES_standard_derivatives");
3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GR_GL_GetIntegerv(this->glInterface(),
3174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                      GR_GL_MAX_VERTEX_ATTRIBS,
3184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                      &fMaxVertexAttribs);
3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fProgramData = NULL;
3214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fProgramCache = new ProgramCache(this->glContextInfo());
3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 0
3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->programUnitTest();
3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3281cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrGpuGLShaders::~GrGpuGLShaders() {
3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fProgramCache;
3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrMatrix& GrGpuGLShaders::getHWViewMatrix() {
3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(fProgramData);
3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kSetAsAttribute ==
3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fUniLocations.fViewMatrixUni) {
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return fHWDrawState.getViewMatrix();
3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return fProgramData->fViewMatrix;
3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::recordHWViewMatrix(const GrMatrix& matrix) {
3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(fProgramData);
3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kSetAsAttribute ==
3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fUniLocations.fViewMatrixUni) {
3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fHWDrawState.setViewMatrix(matrix);
3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fViewMatrix = matrix;
3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(fProgramData);
3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kSetAsAttribute ==
3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return fHWDrawState.getSampler(stage).getMatrix();
3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return fProgramData->fTextureMatrices[stage];
3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(fProgramData);
3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kSetAsAttribute ==
3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *fHWDrawState.sampler(stage)->matrix() = matrix;
3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fTextureMatrices[stage] = matrix;
3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::onResetContext() {
3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    INHERITED::onResetContext();
3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fHWGeometryState.fVertexOffset = ~0;
3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Third party GL code may have left vertex attributes enabled. Some GL
3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // implementations (osmesa) may read vetex attributes that are not required
3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // by the current shader. Therefore, we have to ensure that only the
3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // attributes we require for the current draw are enabled or we may cause an
3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // invalid read.
3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Disable all vertex layout bits so that next flush will assume all
3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // optional vertex attributes are disabled.
3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fHWGeometryState.fVertexLayout = 0;
3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We always use the this attribute and assume it is always enabled.
3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int posAttrIdx = GrGLProgram::PositionAttributeIdx();
3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GL_CALL(EnableVertexAttribArray(posAttrIdx));
3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Disable all other vertex attributes.
3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for  (int va = 0; va < fMaxVertexAttribs; ++va) {
3941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (va != posAttrIdx) {
3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(DisableVertexAttribArray(va));
3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fHWProgramID = 0;
4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushViewMatrix() {
4031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrMatrix& vm = this->getDrawState().getViewMatrix();
4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGpuGLShaders::getHWViewMatrix() != vm) {
4051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(NULL != rt);
4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrMatrix m;
4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        m.setAll(
4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrIntToScalar(2) / rt->width(), 0, -GR_Scalar1,
4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            0,-GrIntToScalar(2) / rt->height(), GR_Scalar1,
4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            0, 0, GrMatrix::I()[8]);
4131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        m.setConcat(m, vm);
4141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // ES doesn't allow you to pass true to the transpose param,
4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // so do our own transpose
4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrGLfloat mt[]  = {
4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMScaleX]),
4191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMSkewY]),
4201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMPersp0]),
4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMSkewX]),
4221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMScaleY]),
4231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMPersp1]),
4241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMTransX]),
4251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMTransY]),
4261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(m[GrMatrix::kMPersp2])
4271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (GrGLProgram::kSetAsAttribute ==
4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProgramData->fUniLocations.fViewMatrixUni) {
4311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int baseIdx = GrGLProgram::ViewMatrixAttributeIdx();
4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
4351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
4361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrAssert(GrGLProgram::kUnusedUniform !=
4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     fProgramData->fUniLocations.fViewMatrixUni);
4381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     1, false, mt));
4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->recordHWViewMatrix(vm);
4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushTextureDomain(int s) {
4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni;
4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawState& drawState = this->getDrawState();
4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kUnusedUniform != uni) {
4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrRect &texDom = drawState.getSampler(s).getTextureDomain();
4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProgramData->fTextureDomain[s] != texDom) {
4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProgramData->fTextureDomain[s] = texDom;
4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            float values[4] = {
4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(texDom.left()),
4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(texDom.top()),
4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(texDom.right()),
4601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(texDom.bottom())
4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            };
4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrGLTexture* texture =
4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                static_cast<const GrGLTexture*>(drawState.getTexture(s));
4651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrGLTexture::Orientation orientation = texture->orientation();
4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // vertical flip if necessary
4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (GrGLTexture::kBottomUp_Orientation == orientation) {
4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                values[1] = 1.0f - values[1];
4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                values[3] = 1.0f - values[3];
4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // The top and bottom were just flipped, so correct the ordering
4721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // of elements so that values = (l, t, r, b).
4731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkTSwap(values[1], values[3]);
4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
4751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(Uniform4fv(uni, 1, values));
4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushTextureMatrix(int s) {
4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni;
4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawState& drawState = this->getDrawState();
4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrGLTexture* texture =
4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static_cast<const GrGLTexture*>(drawState.getTexture(s));
4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != texture) {
4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (GrGLProgram::kUnusedUniform != uni &&
4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->getHWSamplerMatrix(s) != drawState.getSampler(s).getMatrix())) {
4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrMatrix m = drawState.getSampler(s).getMatrix();
4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrSamplerState::SampleMode mode =
4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                drawState.getSampler(s).getSampleMode();
4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            AdjustTextureMatrix(texture, mode, &m);
4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // ES doesn't allow you to pass true to the transpose param,
4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // so do our own transpose
4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrGLfloat mt[]  = {
4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMScaleX]),
5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMSkewY]),
5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMPersp0]),
5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMSkewX]),
5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMScaleY]),
5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMPersp1]),
5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMTransX]),
5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMTransY]),
5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrScalarToFloat(m[GrMatrix::kMPersp2])
5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            };
5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (GrGLProgram::kSetAsAttribute ==
5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fProgramData->fUniLocations.fStages[s].fTextureMatrixUni) {
5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                int baseIdx = GrGLProgram::TextureMatrixAttributeIdx(s);
5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GL_CALL(UniformMatrix3fv(uni, 1, false, mt));
5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->recordHWSamplerMatrix(s, drawState.getSampler(s).getMatrix());
5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushRadial2(int s) {
5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrSamplerState& sampler = this->getDrawState().getSampler(s);
5281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kUnusedUniform != uni &&
5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         fProgramData->fRadial2Radius0[s]  != sampler.getRadial2Radius0()  ||
5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger         fProgramData->fRadial2PosRoot[s]  != sampler.isRadial2PosRoot())) {
5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrScalar centerX1 = sampler.getRadial2CenterX1();
5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrScalar radius0 = sampler.getRadial2Radius0();
5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // when were in the degenerate (linear) case the second
5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // value will be INF but the program doesn't read it. (We
5401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // use the same 6 uniforms even though we don't need them
5411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // all in the linear case just to keep the code complexity
5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // down).
5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        float values[6] = {
5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(a),
5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            1 / (2.f * GrScalarToFloat(a)),
5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(centerX1),
5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(radius0),
5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrScalarToFloat(GrMul(radius0, radius0)),
5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            sampler.isRadial2PosRoot() ? 1.f : -1.f
5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(Uniform1fv(uni, 6, values));
5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fRadial2Radius0[s]  = sampler.getRadial2Radius0();
5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fRadial2PosRoot[s]  = sampler.isRadial2PosRoot();
5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushConvolution(int s) {
5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrSamplerState& sampler = this->getDrawState().getSampler(s);
5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni;
5611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kUnusedUniform != kernelUni) {
5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(Uniform1fv(kernelUni, sampler.getKernelWidth(),
5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           sampler.getKernel()));
5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int imageIncrementUni = fProgramData->fUniLocations.fStages[s].fImageIncrementUni;
5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kUnusedUniform != imageIncrementUni) {
5674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        const GrGLTexture* texture =
5684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            static_cast<const GrGLTexture*>(this->getDrawState().getTexture(s));
5694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        float imageIncrement[2] = { 0 };
5704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        switch (sampler.getFilterDirection()) {
5714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            case GrSamplerState::kX_FilterDirection:
5724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                imageIncrement[0] = 1.0f / texture->width();
5734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                break;
5744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            case GrSamplerState::kY_FilterDirection:
5754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                imageIncrement[1] = 1.0f / texture->height();
5764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                break;
5774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            default:
5784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                GrCrash("Unknown filter direction.");
5794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        }
5804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        GL_CALL(Uniform2fv(imageIncrementUni, 1, imageIncrement));
5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushTexelSize(int s) {
5851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
5861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kUnusedUniform != uni) {
5871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrGLTexture* texture =
5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            static_cast<const GrGLTexture*>(this->getDrawState().getTexture(s));
5891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (texture->width() != fProgramData->fTextureWidth[s] ||
5901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            texture->height() != fProgramData->fTextureHeight[s]) {
5911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            float texelSize[] = {1.f / texture->width(),
5931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 1.f / texture->height()};
5941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(Uniform2fv(uni, 1, texelSize));
5951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProgramData->fTextureWidth[s] = texture->width();
5961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProgramData->fTextureHeight[s] = texture->height();
5971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushEdgeAAData() {
6021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const int& uni = fProgramData->fUniLocations.fEdgesUni;
6031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kUnusedUniform != uni) {
6041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int count = this->getDrawState().getNumAAEdges();
6051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawState::Edge edges[GrDrawState::kMaxEdges];
6061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Flip the edges in Y
6071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        float height =
6081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            static_cast<float>(this->getDrawState().getRenderTarget()->height());
6091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < count; ++i) {
6101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            edges[i] = this->getDrawState().getAAEdges()[i];
6111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            float b = edges[i].fY;
6121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            edges[i].fY = -b;
6131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            edges[i].fZ += b * height;
6141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
6151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(Uniform3fv(uni, count, &edges[0].fX));
6161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushColorMatrix() {
6201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const ProgramDesc& desc = fCurrentProgram.getDesc();
6211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int matrixUni = fProgramData->fUniLocations.fColorMatrixUni;
6221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int vecUni = fProgramData->fUniLocations.fColorMatrixVecUni;
6231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrGLProgram::kUnusedUniform != matrixUni
6241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     && GrGLProgram::kUnusedUniform != vecUni) {
6251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const float* m = this->getDrawState().getColorMatrix();
6261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrGLfloat mt[]  = {
6271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            m[0], m[5], m[10], m[15],
6281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            m[1], m[6], m[11], m[16],
6291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            m[2], m[7], m[12], m[17],
6301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            m[3], m[8], m[13], m[18],
6311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
6321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static float scale = 1.0f / 255.0f;
6331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrGLfloat vec[] = {
6341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            m[4] * scale, m[9] * scale, m[14] * scale, m[19] * scale,
6351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
6361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(UniformMatrix4fv(matrixUni, 1, false, mt));
6371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(Uniform4fv(vecUni, 1, vec));
6381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const float ONE_OVER_255 = 1.f / 255.f;
6421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define GR_COLOR_TO_VEC4(color) {\
6441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrColorUnpackR(color) * ONE_OVER_255,\
6451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrColorUnpackG(color) * ONE_OVER_255,\
6461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrColorUnpackB(color) * ONE_OVER_255,\
6471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrColorUnpackA(color) * ONE_OVER_255 \
6481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::flushColor(GrColor color) {
6511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const ProgramDesc& desc = fCurrentProgram.getDesc();
6521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawState& drawState = this->getDrawState();
6531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
6551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // color will be specified per-vertex as an attribute
6561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // invalidate the const vertex attrib color
6571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fHWDrawState.setColor(GrColor_ILLEGAL);
6581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
6591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        switch (desc.fColorInput) {
6601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case ProgramDesc::kAttribute_ColorInput:
6611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (fHWDrawState.getColor() != color) {
6624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // OpenGL ES only supports the float varieties of
6634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // glVertexAttrib
6641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    float c[] = GR_COLOR_TO_VEC4(color);
6651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(),
6661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            c));
6671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    fHWDrawState.setColor(color);
6681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
6691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
6701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case ProgramDesc::kUniform_ColorInput:
6711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (fProgramData->fColor != color) {
6724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // OpenGL ES doesn't support unsigned byte varieties of
6734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // glUniform
6741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    float c[] = GR_COLOR_TO_VEC4(color);
6751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    GrAssert(GrGLProgram::kUnusedUniform !=
6761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             fProgramData->fUniLocations.fColorUni);
6771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorUni,
6781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        1, c));
6791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    fProgramData->fColor = color;
6801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
6811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
6821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case ProgramDesc::kSolidWhite_ColorInput:
6831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case ProgramDesc::kTransBlack_ColorInput:
6841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
6851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            default:
6861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrCrash("Unknown color type.");
6871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
6881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fProgramData->fUniLocations.fColorFilterUni
6901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                != GrGLProgram::kUnusedUniform
6911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            && fProgramData->fColorFilterColor
6921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                != drawState.getColorFilterColor()) {
6931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        float c[] = GR_COLOR_TO_VEC4(drawState.getColorFilterColor());
6941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c));
6951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramData->fColorFilterColor = drawState.getColorFilterColor();
6961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid GrGpuGLShaders::flushCoverage(GrColor coverage) {
7004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    const ProgramDesc& desc = fCurrentProgram.getDesc();
7014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    const GrDrawState& drawState = this->getDrawState();
7024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
7034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
7044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (this->getGeomSrc().fVertexLayout & kCoverage_VertexLayoutBit) {
7054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        // coverage will be specified per-vertex as an attribute
7064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        // invalidate the const vertex attrib coverage
7074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        fHWDrawState.setCoverage4(GrColor_ILLEGAL);
7084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else {
7094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        switch (desc.fCoverageInput) {
7104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            case ProgramDesc::kAttribute_ColorInput:
7114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (fHWDrawState.getCoverage() != coverage) {
7124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // OpenGL ES only supports the float varieties of
7134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // glVertexAttrib
7144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    float c[] = GR_COLOR_TO_VEC4(coverage);
7154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    GL_CALL(VertexAttrib4fv(GrGLProgram::CoverageAttributeIdx(),
7164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                            c));
7174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    fHWDrawState.setCoverage(coverage);
7184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                }
7194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                break;
7204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            case ProgramDesc::kUniform_ColorInput:
7214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (fProgramData->fCoverage != coverage) {
7224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // OpenGL ES doesn't support unsigned byte varieties of
7234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    // glUniform
7244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    float c[] = GR_COLOR_TO_VEC4(coverage);
7254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    GrAssert(GrGLProgram::kUnusedUniform !=
7264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                             fProgramData->fUniLocations.fCoverageUni);
7274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    GL_CALL(Uniform4fv(fProgramData->fUniLocations.fCoverageUni,
7284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                        1, c));
7294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    fProgramData->fCoverage = coverage;
7304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                }
7314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                break;
7324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            case ProgramDesc::kSolidWhite_ColorInput:
7334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            case ProgramDesc::kTransBlack_ColorInput:
7344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                break;
7354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            default:
7364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                GrCrash("Unknown coverage type.");
7374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        }
7384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
7394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
7401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
7421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!flushGLStateCommon(type)) {
7431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
7441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawState& drawState = this->getDrawState();
7471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fDirtyFlags.fRenderTargetChanged) {
7491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // our coords are in pixel space and the GL matrices map to NDC
7501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // so if the viewport changed, our matrix is now wrong.
7511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
7521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // we assume all shader matrices may be wrong after viewport changes
7531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fProgramCache->invalidateViewMatrices();
7541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrBlendCoeff srcCoeff;
7571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrBlendCoeff dstCoeff;
7581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    BlendOptFlags blendOpts = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
7591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kSkipDraw_BlendOptFlag & blendOpts) {
7601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
7611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->buildProgram(type, blendOpts, dstCoeff);
7641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fProgramData = fProgramCache->getProgramData(fCurrentProgram);
7651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == fProgramData) {
7661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(!"Failed to create program!");
7671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
7681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fHWProgramID != fProgramData->fProgramID) {
7711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(UseProgram(fProgramData->fProgramID));
7721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fHWProgramID = fProgramData->fProgramID;
7731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff);
7751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flushBlend(type, srcCoeff, dstCoeff);
7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrColor color;
7784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    GrColor coverage;
7791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (blendOpts & kEmitTransBlack_BlendOptFlag) {
7801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        color = 0;
7814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        coverage = 0;
7821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else if (blendOpts & kEmitCoverage_BlendOptFlag) {
7831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        color = 0xffffffff;
7844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        coverage = drawState.getCoverage();
7851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
7861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        color = drawState.getColor();
7874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        coverage = drawState.getCoverage();
7881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flushColor(color);
7904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    this->flushCoverage(coverage);
7911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flushViewMatrix();
7931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
7951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (this->isStageEnabled(s)) {
7961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->flushTextureMatrix(s);
7971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->flushRadial2(s);
7991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->flushConvolution(s);
8011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->flushTexelSize(s);
8031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->flushTextureDomain(s);
8051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
8061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flushEdgeAAData();
8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flushColorMatrix();
8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    resetDirtyFlags();
8101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
8111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
8121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::postDraw() {
8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
8151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::setupGeometry(int* startVertex,
8171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    int* startIndex,
8181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    int vertexCount,
8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    int indexCount) {
8201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int newColorOffset;
8221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int newCoverageOffset;
8231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int newTexCoordOffsets[GrDrawState::kMaxTexCoords];
8241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int newEdgeOffset;
8251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
8271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            this->getGeomSrc().fVertexLayout,
8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            newTexCoordOffsets,
8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            &newColorOffset,
8301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            &newCoverageOffset,
8311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            &newEdgeOffset);
8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int oldColorOffset;
8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int oldCoverageOffset;
8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int oldTexCoordOffsets[GrDrawState::kMaxTexCoords];
8351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int oldEdgeOffset;
8361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
8381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            fHWGeometryState.fVertexLayout,
8391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            oldTexCoordOffsets,
8401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            &oldColorOffset,
8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            &oldCoverageOffset,
8421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            &oldEdgeOffset);
8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool indexed = NULL != startIndex;
8441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int extraVertexOffset;
8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int extraIndexOffset;
8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
8481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrGLenum scalarType;
8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool texCoordNorm;
8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        scalarType = GrGLTextType;
8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        scalarType = GrGLType;
8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        texCoordNorm = false;
8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *startVertex = 0;
8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (indexed) {
8621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *startIndex += extraIndexOffset;
8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // all the Pointers must be set if any of these are true
8661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
8671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             vertexOffset != fHWGeometryState.fVertexOffset ||
8681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             newStride != oldStride;
8691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // position and tex coord offsets change if above conditions are true
8711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // or the type/normalization changed based on text vs nontext type coords.
8721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool posAndTexChange = allOffsetsChange ||
8731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
8741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                (kTextFormat_VertexLayoutBit &
8751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  (fHWGeometryState.fVertexLayout ^
8761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   this->getGeomSrc().fVertexLayout)));
8771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (posAndTexChange) {
8791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int idx = GrGLProgram::PositionAttributeIdx();
8801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(VertexAttribPointer(idx, 2, scalarType, false, newStride,
8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  (GrGLvoid*)vertexOffset));
8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fHWGeometryState.fVertexOffset = vertexOffset;
8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
8861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (newTexCoordOffsets[t] > 0) {
8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]);
8881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int idx = GrGLProgram::TexCoordAttributeIdx(t);
8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (oldTexCoordOffsets[t] <= 0) {
8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GL_CALL(EnableVertexAttribArray(idx));
8911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
8921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          newStride, texCoordOffset));
8931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else if (posAndTexChange ||
8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                       newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
8951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
8961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          newStride, texCoordOffset));
8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
8981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (oldTexCoordOffsets[t] > 0) {
8991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
9001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
9011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (newColorOffset > 0) {
9041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
9051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int idx = GrGLProgram::ColorAttributeIdx();
9061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (oldColorOffset <= 0) {
9071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(EnableVertexAttribArray(idx));
9081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
9091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      true, newStride, colorOffset));
9101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
9121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      true, newStride, colorOffset));
9131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
9141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else if (oldColorOffset > 0) {
9151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
9161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (newCoverageOffset > 0) {
9191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset);
9201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int idx = GrGLProgram::CoverageAttributeIdx();
9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (oldCoverageOffset <= 0) {
9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(EnableVertexAttribArray(idx));
9234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        true, newStride, coverageOffset));
9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) {
9264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
9271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        true, newStride, coverageOffset));
9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else if (oldCoverageOffset > 0) {
9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx()));
9311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (newEdgeOffset > 0) {
9341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset);
9351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int idx = GrGLProgram::EdgeAttributeIdx();
9361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (oldEdgeOffset <= 0) {
9371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(EnableVertexAttribArray(idx));
9381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(VertexAttribPointer(idx, 4, scalarType,
9391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        false, newStride, edgeOffset));
9401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) {
9411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GL_CALL(VertexAttribPointer(idx, 4, scalarType,
9421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        false, newStride, edgeOffset));
9431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
9441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else if (oldEdgeOffset > 0) {
9451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
9461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fHWGeometryState.fArrayPtrsDirty = false;
9501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGpuGLShaders::buildProgram(GrPrimitiveType type,
9531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  BlendOptFlags blendOpts,
9541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  GrBlendCoeff dstCoeff) {
9551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ProgramDesc& desc = fCurrentProgram.fProgramDesc;
9561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawState& drawState = this->getDrawState();
9571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // This should already have been caught
9591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(!(kSkipDraw_BlendOptFlag & blendOpts));
9601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool skipCoverage = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
9621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool skipColor = SkToBool(blendOpts & (kEmitTransBlack_BlendOptFlag |
9641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           kEmitCoverage_BlendOptFlag));
9651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // The descriptor is used as a cache key. Thus when a field of the
9671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // descriptor will not affect program generation (because of the vertex
9681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // layout in use or other descriptor field settings) it should be set
9691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // to a canonical value to avoid duplicate programs with different keys.
9701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Must initialize all fields or cache will have false negatives!
9721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fVertexLayout = this->getGeomSrc().fVertexLayout;
9731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fEmitsPointSize = kPoints_PrimitiveType == type;
9751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool requiresAttributeColors =
9771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        !skipColor && SkToBool(desc.fVertexLayout & kColor_VertexLayoutBit);
9784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    bool requiresAttributeCoverage =
9794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        !skipCoverage && SkToBool(desc.fVertexLayout &
9804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                  kCoverage_VertexLayoutBit);
9814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
9824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // fColorInput/fCoverageInput records how colors are specified for the.
9834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // program. So we strip the bits from the layout to avoid false negatives
9844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // when searching for an existing program in the cache.
9854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    desc.fVertexLayout &= ~(kColor_VertexLayoutBit | kCoverage_VertexLayoutBit);
9861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fColorFilterXfermode = skipColor ?
9881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                SkXfermode::kDst_Mode :
9891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                drawState.getColorFilterMode();
9901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fColorMatrixEnabled = drawState.isStateFlagEnabled(GrDrawState::kColorMatrix_StateBit);
9921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // no reason to do edge aa or look at per-vertex coverage if coverage is
9941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // ignored
9951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (skipCoverage) {
9961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fVertexLayout &= ~(kEdge_VertexLayoutBit |
9971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                kCoverage_VertexLayoutBit);
9981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
10011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) ||
10021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             (!requiresAttributeColors &&
10031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              0xffffffff == drawState.getColor());
10041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GR_AGGRESSIVE_SHADER_OPTS && colorIsTransBlack) {
10051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fColorInput = ProgramDesc::kTransBlack_ColorInput;
10061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else if (GR_AGGRESSIVE_SHADER_OPTS && colorIsSolidWhite) {
10071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fColorInput = ProgramDesc::kSolidWhite_ColorInput;
10081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) {
10091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fColorInput = ProgramDesc::kUniform_ColorInput;
10101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
10111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fColorInput = ProgramDesc::kAttribute_ColorInput;
10121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
10144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    bool covIsSolidWhite = !requiresAttributeCoverage &&
10154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                           0xffffffff == drawState.getCoverage();
10164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
10174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (skipCoverage) {
10184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        desc.fCoverageInput = ProgramDesc::kTransBlack_ColorInput;
10194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (covIsSolidWhite) {
10204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        desc.fCoverageInput = ProgramDesc::kSolidWhite_ColorInput;
10214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) {
10224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        desc.fCoverageInput = ProgramDesc::kUniform_ColorInput;
10234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else {
10244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        desc.fCoverageInput = ProgramDesc::kAttribute_ColorInput;
10254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
10261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fEdgeAANumEdges = skipCoverage ? 0 : drawState.getNumAAEdges();
10281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fEdgeAAConcave = desc.fEdgeAANumEdges > 0 &&
10291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                          drawState.isConcaveEdgeAAState();
10301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int lastEnabledStage = -1;
10321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!skipCoverage && (desc.fVertexLayout &
10341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                          GrDrawTarget::kEdge_VertexLayoutBit)) {
10351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fVertexEdgeType = drawState.getVertexEdgeType();
10361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
10371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // use canonical value when not set to avoid cache misses
10381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
10391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
10421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        StageDesc& stage = desc.fStages[s];
10431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        stage.fOptFlags = 0;
10451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        stage.setEnabled(this->isStageEnabled(s));
10461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool skip = s < drawState.getFirstCoverageStage() ? skipColor :
10481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                             skipCoverage;
10491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!skip && stage.isEnabled()) {
10511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            lastEnabledStage = s;
10521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrGLTexture* texture =
10531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                static_cast<const GrGLTexture*>(drawState.getTexture(s));
10541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrAssert(NULL != texture);
10551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrSamplerState& sampler = drawState.getSampler(s);
10561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // we matrix to invert when orientation is TopDown, so make sure
10571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // we aren't in that case before flagging as identity.
10581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (TextureMatrixIsIdentity(texture, sampler)) {
10591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
10601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else if (!sampler.getMatrix().hasPerspective()) {
10611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
10621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
10631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            switch (sampler.getSampleMode()) {
10641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::kNormal_SampleMode:
10651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
10661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::kRadial_SampleMode:
10681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
10691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::kRadial2_SampleMode:
10711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    if (sampler.radial2IsDegenerate()) {
10721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        stage.fCoordMapping =
10731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            StageDesc::kRadial2GradientDegenerate_CoordMapping;
10741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    } else {
10751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        stage.fCoordMapping =
10761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            StageDesc::kRadial2Gradient_CoordMapping;
10771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    }
10781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::kSweep_SampleMode:
10801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
10811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                default:
10831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    GrCrash("Unexpected sample mode!");
10841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
10861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            switch (sampler.getFilter()) {
10881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // these both can use a regular texture2D()
10891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::kNearest_Filter:
10901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::kBilinear_Filter:
10911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fFetchMode = StageDesc::kSingle_FetchMode;
10921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // performs 4 texture2D()s
10941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::k4x4Downsample_Filter:
10951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fFetchMode = StageDesc::k2x2_FetchMode;
10961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // performs fKernelWidth texture2D()s
10981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case GrSamplerState::kConvolution_Filter:
10991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fFetchMode = StageDesc::kConvolution_FetchMode;
11001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
11014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                case GrSamplerState::kDilate_Filter:
11024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    stage.fFetchMode = StageDesc::kDilate_FetchMode;
11034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    break;
11044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                case GrSamplerState::kErode_Filter:
11054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    stage.fFetchMode = StageDesc::kErode_FetchMode;
11064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    break;
11071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                default:
11081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    GrCrash("Unexpected filter!");
11091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
11101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
11111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (sampler.hasTextureDomain()) {
11131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrAssert(GrSamplerState::kClamp_WrapMode ==
11141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            sampler.getWrapX() &&
11151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         GrSamplerState::kClamp_WrapMode ==
11161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            sampler.getWrapY());
11171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                stage.fOptFlags |= StageDesc::kCustomTextureDomain_OptFlagBit;
11181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
11191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fInConfigFlags = 0;
11214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            if (!this->glCaps().textureSwizzleSupport()) {
11221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (GrPixelConfigIsAlphaOnly(texture->config())) {
11231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    // if we don't have texture swizzle support then
11241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    // the shader must do an alpha smear after reading
11251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    // the texture
11261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
11271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                } else if (sampler.swapsRAndB()) {
11281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    stage.fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag;
11291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
11301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
11311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (GrPixelConfigIsUnpremultiplied(texture->config())) {
11324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                // The shader generator assumes that color channels are bytes
11334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                // when rounding.
11344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                GrAssert(4 == GrBytesPerPixel(texture->config()));
11354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (kUpOnWrite_DownOnRead_UnpremulConversion ==
11364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    fUnpremulConversion) {
11374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    stage.fInConfigFlags |=
11384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                        StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
11394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                } else {
11404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    stage.fInConfigFlags |=
11414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                        StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag;
11424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                }
11431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
11441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            if (sampler.getFilter() == GrSamplerState::kConvolution_Filter ||
11464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                sampler.getFilter() == GrSamplerState::kDilate_Filter ||
11474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                sampler.getFilter() == GrSamplerState::kErode_Filter) {
11481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                stage.fKernelWidth = sampler.getKernelWidth();
11491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
11501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                stage.fKernelWidth = 0;
11511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
11521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
11531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fOptFlags         = 0;
11541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fCoordMapping     = (StageDesc::CoordMapping) 0;
11551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fInConfigFlags    = 0;
11561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fFetchMode        = (StageDesc::FetchMode) 0;
11571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stage.fKernelWidth      = 0;
11581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
11591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
11624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        // The shader generator assumes that color channels are bytes
11634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        // when rounding.
11644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        GrAssert(4 == GrBytesPerPixel(drawState.getRenderTarget()->config()));
11654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (kUpOnWrite_DownOnRead_UnpremulConversion == fUnpremulConversion) {
11664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            desc.fOutputConfig =
11674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                ProgramDesc::kUnpremultiplied_RoundUp_OutputConfig;
11684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        } else {
11694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            desc.fOutputConfig =
11704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                ProgramDesc::kUnpremultiplied_RoundDown_OutputConfig;
11714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        }
11721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
11734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        desc.fOutputConfig = ProgramDesc::kPremultiplied_OutputConfig;
11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;
11771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // currently the experimental GS will only work with triangle prims
11791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // (and it doesn't do anything other than pass through values from
11801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the VS to the FS anyway).
11811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 0 && GR_GL_EXPERIMENTAL_GS
11821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fExperimentalGS = this->getCaps().fGeometryShaderSupport;
11831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
11841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we want to avoid generating programs with different "first cov stage"
11861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // values when they would compute the same result.
11871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We set field in the desc to kNumStages when either there are no
11881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // coverage stages or the distinction between coverage and color is
11891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // immaterial.
11901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int firstCoverageStage = GrDrawState::kNumStages;
11911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fFirstCoverageStage = GrDrawState::kNumStages;
11921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage;
11931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (hasCoverage) {
11941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        firstCoverageStage = drawState.getFirstCoverageStage();
11951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // other coverage inputs
11981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!hasCoverage) {
11991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        hasCoverage =
12001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger               desc.fEdgeAANumEdges ||
12014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger               requiresAttributeCoverage ||
12021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger               (desc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit);
12031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (hasCoverage) {
12061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // color filter is applied between color/coverage computation
12071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (SkXfermode::kDst_Mode != desc.fColorFilterXfermode) {
12081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fFirstCoverageStage = firstCoverageStage;
12091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
12101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (this->getCaps().fDualSourceBlendingSupport &&
12121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            !(blendOpts & (kEmitCoverage_BlendOptFlag |
12131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           kCoverageAsAlpha_BlendOptFlag))) {
12141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (kZero_BlendCoeff == dstCoeff) {
12151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // write the coverage value to second color
12161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                desc.fDualSrcOutput =  ProgramDesc::kCoverage_DualSrcOutput;
12171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                desc.fFirstCoverageStage = firstCoverageStage;
12181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else if (kSA_BlendCoeff == dstCoeff) {
12191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
12201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // cover
12211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                desc.fDualSrcOutput = ProgramDesc::kCoverageISA_DualSrcOutput;
12221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                desc.fFirstCoverageStage = firstCoverageStage;
12231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else if (kSC_BlendCoeff == dstCoeff) {
12241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
12251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                // cover
12261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                desc.fDualSrcOutput = ProgramDesc::kCoverageISC_DualSrcOutput;
12271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                desc.fFirstCoverageStage = firstCoverageStage;
12281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
12291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
12301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1232