diff options
author | 2011-05-09 18:44:52 +0000 | |
---|---|---|
committer | 2011-05-09 18:44:52 +0000 | |
commit | b9afba31931659ff3aac72a2c01b665f2f5b0f86 (patch) | |
tree | 41f36df65fb3088c5c2aa90414e09aa4e7ab0c64 /gpu/src/GrGpuGLShaders2.cpp | |
parent | 9196130af83782fcac4334117142475a837dd74d (diff) |
Remove previous shader generator class. No longer compiles due to elimination of separate GrStringBuilder class in favor or SkString.
git-svn-id: http://skia.googlecode.com/svn/trunk@1282 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu/src/GrGpuGLShaders2.cpp')
-rw-r--r-- | gpu/src/GrGpuGLShaders2.cpp | 1476 |
1 files changed, 0 insertions, 1476 deletions
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp deleted file mode 100644 index 171a031ee3..0000000000 --- a/gpu/src/GrGpuGLShaders2.cpp +++ /dev/null @@ -1,1476 +0,0 @@ -/* - Copyright 2011 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - -#include "GrGLConfig.h" - -#include "GrGpuGLShaders2.h" -#include "GrGpuVertex.h" -#include "GrMemory.h" -#include "GrStringBuilder.h" - -#define PRINT_SHADERS 0 - -#define SKIP_CACHE_CHECK true - -#define POS_ATTR_LOCATION 0 -#define TEX_ATTR_LOCATION(X) (1 + X) -#define COL_ATTR_LOCATION (2 + GrDrawTarget::kMaxTexCoords) -#if GR_GL_ATTRIBUTE_MATRICES - #define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords) - #define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X)) - #define BOGUS_MATRIX_UNI_LOCATION 1000 -#endif - -#define GR_UINT32_MAX static_cast<uint32_t>(-1) - -namespace { - -const char* GrPrecision() { - if (GR_GL_SUPPORT_ES2) { - return "mediump"; - } else { - return ""; - } -} - -const char* GrShaderPrecision() { - if (GR_GL_SUPPORT_ES2) { - return "precision mediump float;\n"; - } else { - return ""; - } -} - -} // namespace - -struct GrGpuGLShaders2::StageUniLocations { - GrGLint fTextureMatrixUni; - GrGLint fSamplerUni; - GrGLint fRadial2Uni; -}; - -struct GrGpuGLShaders2::UniLocations { - GrGLint fViewMatrixUni; - GrGLint fColorUni; - StageUniLocations fStages[kNumStages]; -}; - -// Records per-program information -// we can specify the attribute locations so that they are constant -// across our shaders. But the driver determines the uniform locations -// at link time. We don't need to remember the sampler uniform location -// because we will bind a texture slot to it and never change it -// Uniforms are program-local so we can't rely on fHWState to hold the -// previous uniform state after a program change. -struct GrGpuGLShaders2::Program { - // IDs - GrGLuint fVShaderID; - GrGLuint fFShaderID; - GrGLuint fProgramID; - - // shader uniform locations (-1 if shader doesn't use them) - UniLocations fUniLocations; - - // these reflect the current values of uniforms - // (GL uniform values travel with program) - GrMatrix fViewMatrix; - GrColor fColor; - GrMatrix fTextureMatrices[kNumStages]; - GrScalar fRadial2CenterX1[kNumStages]; - GrScalar fRadial2Radius0[kNumStages]; - bool fRadial2PosRoot[kNumStages]; - -}; - -// must be tightly packed -struct GrGpuGLShaders2::StageDesc { - enum OptFlagBits { - kNoPerspective_OptFlagBit = 0x1, - kIdentityMatrix_OptFlagBit = 0x2, - }; - unsigned fOptFlags : 8; - - unsigned fEnabled : 8; - - enum Modulation { - kColor_Modulation, - kAlpha_Modulation, - } fModulation : 8; - - enum CoordMapping { - kIdentity_CoordMapping, - kRadialGradient_CoordMapping, - kSweepGradient_CoordMapping, - kRadial2Gradient_CoordMapping, - } fCoordMapping : 8; -}; - -// must be tightly packed -struct GrGpuGLShaders2::ProgramDesc { - ProgramDesc() { - // since we use this as a key we can't have any unitialized padding - memset(this, 0, sizeof(ProgramDesc)); - } - - GrVertexLayout fVertexLayout; // stripped of bits that don't affect - // program generation. - enum { - kNone_ColorType = 0, - kAttribute_ColorType = 1, - kUniform_ColorType = 2, - } fColorType; - bool fEmitsPointSize; - - StageDesc fStages[kNumStages]; - - bool operator == (const ProgramDesc& desc) const { - return 0 == memcmp(this, &desc, sizeof(ProgramDesc)); - } -}; - -#include "GrTHashCache.h" - -class GrGpuGLShaders2::ProgramCache : public ::GrNoncopyable { -private: - struct Entry; - class HashKey { - public: - HashKey(); - HashKey(const ProgramDesc& desc); - static const HashKey& GetKey(const Entry&); - static bool EQ(const Entry&, const HashKey&); - static bool LT(const Entry&, const HashKey&); - bool operator <(const HashKey& key) const; - bool operator ==(const HashKey& key) const; - uint32_t getHash() const; - private: - ProgramDesc fDesc; - uint32_t fHash; - }; - - struct Entry { - Program fProgram; - HashKey fKey; - uint32_t fLRUStamp; - }; - - // if hash bits is changed, need to change hash function - GrTHashTable<Entry, HashKey, 8> fHashCache; - - static const int MAX_ENTRIES = 16; - Entry fEntries[MAX_ENTRIES]; - int fCount; - uint32_t fCurrLRUStamp; - -public: - ProgramCache() { - fCount = 0; - fCurrLRUStamp = 0; - } - - ~ProgramCache() { - for (int i = 0; i < fCount; ++i) { - GrGpuGLShaders2::DeleteProgram(&fEntries[i].fProgram); - } - } - - void abandon() { - fCount = 0; - } - - void invalidateViewMatrices() { - for (int i = 0; i < fCount; ++i) { - // set to illegal matrix - fEntries[i].fProgram.fViewMatrix = GrMatrix::InvalidMatrix(); - } - } - - Program* getProgram(const ProgramDesc& desc) { - HashKey key(desc); - Entry* entry = fHashCache.find(key); - if (NULL == entry) { - if (fCount < MAX_ENTRIES) { - entry = fEntries + fCount; - ++fCount; - } else { - GrAssert(MAX_ENTRIES == fCount); - entry = fEntries; - for (int i = 1; i < MAX_ENTRIES; ++i) { - if (fEntries[i].fLRUStamp < entry->fLRUStamp) { - entry = fEntries + i; - } - } - fHashCache.remove(entry->fKey, entry); - GrGpuGLShaders2::DeleteProgram(&entry->fProgram); - } - entry->fKey = key; - GrGpuGLShaders2::GenProgram(desc, &entry->fProgram); - fHashCache.insert(entry->fKey, entry); - } - - entry->fLRUStamp = fCurrLRUStamp; - if (GR_UINT32_MAX == fCurrLRUStamp) { - // wrap around! just trash our LRU, one time hit. - for (int i = 0; i < fCount; ++i) { - fEntries[i].fLRUStamp = 0; - } - } - ++fCurrLRUStamp; - return &entry->fProgram; - } -}; - -GrGpuGLShaders2::ProgramCache::HashKey::HashKey() { -} - -static inline uint32_t ror(uint32_t x) { - return (x >> 8) | (x << 24); -} - -static inline uint32_t rol(uint32_t x) { - return (x << 8) | (x >> 24); -} - -static inline uint32_t roh(uint32_t x) { - return (x << 16) | (x >> 16); -} - -static inline uint32_t swapouter(uint32_t x) { - return (x & 0x00ffff00) | (x << 24) | (x >> 24); -} - -GrGpuGLShaders2::ProgramCache::HashKey::HashKey(const ProgramDesc& desc) { - fDesc = desc; - // if you change the size of the desc, need to update the hash function - GR_STATIC_ASSERT(20 == sizeof(ProgramDesc)); - - uint32_t* d = GrTCast<uint32_t*>(&fDesc); - fHash = d[0] ^ ror(d[1]) ^ rol(d[2]) ^ roh(d[3]) ^ swapouter(d[4]); -} - -bool GrGpuGLShaders2::ProgramCache::HashKey::EQ(const Entry& entry, - const HashKey& key) { - return entry.fKey == key; -} - -bool GrGpuGLShaders2::ProgramCache::HashKey::LT(const Entry& entry, - const HashKey& key) { - return entry.fKey < key; -} - -bool GrGpuGLShaders2::ProgramCache::HashKey::operator ==(const HashKey& key) const { - return fDesc == key.fDesc; -} - -bool GrGpuGLShaders2::ProgramCache::HashKey::operator <(const HashKey& key) const { - return memcmp(&fDesc, &key.fDesc, sizeof(HashKey)) < 0; -} - -uint32_t GrGpuGLShaders2::ProgramCache::HashKey::getHash() const { - return fHash; -} - -struct GrGpuGLShaders2::ShaderCodeSegments { - GrSStringBuilder<256> fVSUnis; - GrSStringBuilder<256> fVSAttrs; - GrSStringBuilder<256> fVaryings; - GrSStringBuilder<256> fFSUnis; - GrSStringBuilder<512> fVSCode; - GrSStringBuilder<512> fFSCode; -}; -// for variable names etc -typedef GrSStringBuilder<16> GrTokenString; - -#if GR_GL_ATTRIBUTE_MATRICES - #define VIEW_MATRIX_NAME "aViewM" -#else - #define VIEW_MATRIX_NAME "uViewM" -#endif - -#define POS_ATTR_NAME "aPosition" -#define COL_ATTR_NAME "aColor" -#define COL_UNI_NAME "uColor" - -static inline void tex_attr_name(int coordIdx, GrStringBuilder* s) { - *s = "aTexCoord"; - s->appendInt(coordIdx); -} - -static inline const char* float_vector_type(int count) { - static const char* FLOAT_VECS[] = {"ERROR", "float", "vec2", "vec3", "vec4"}; - GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(FLOAT_VECS)); - return FLOAT_VECS[count]; -} - -static inline const char* vector_homog_coord(int count) { - static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"}; - GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS)); - return HOMOGS[count]; -} - -static inline const char* vector_nonhomog_coords(int count) { - static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"}; - GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS)); - return NONHOMOGS[count]; -} - -static inline const char* vector_all_coords(int count) { - static const char* ALL[] = {"ERROR", "", ".xy", ".xyz", ".xyzw"}; - GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ALL)); - return ALL[count]; -} - -static void tex_matrix_name(int stage, GrStringBuilder* s) { -#if GR_GL_ATTRIBUTE_MATRICES - *s = "aTexM"; -#else - *s = "uTexM"; -#endif - s->appendInt(stage); -} - -static void sampler_name(int stage, GrStringBuilder* s) { - *s = "uSampler"; - s->appendInt(stage); -} - -static void stage_varying_name(int stage, GrStringBuilder* s) { - *s = "vStage"; - s->appendInt(stage); -} - -static void radial2_param_name(int stage, GrStringBuilder* s) { - *s = "uRadial2Params"; - s->appendInt(stage); -} - -static void radial2_varying_name(int stage, GrStringBuilder* s) { - *s = "vB"; - s->appendInt(stage); -} - -#include "GrRandom.h" - -void GrGpuGLShaders2::ProgramUnitTest() { - - static const int STAGE_OPTS[] = { - 0, - StageDesc::kNoPerspective_OptFlagBit, - StageDesc::kIdentity_CoordMapping - }; - static const int STAGE_MODULATES[] = { - StageDesc::kColor_Modulation, - StageDesc::kAlpha_Modulation - }; - static const int STAGE_COORD_MAPPINGS[] = { - StageDesc::kIdentity_CoordMapping, - StageDesc::kRadialGradient_CoordMapping, - StageDesc::kSweepGradient_CoordMapping, - StageDesc::kRadial2Gradient_CoordMapping - }; - ProgramDesc pdesc; - memset(&pdesc, 0, sizeof(pdesc)); - - static const int NUM_TESTS = 512; - - // GrRandoms nextU() values have patterns in the low bits - // So using nextU() % array_count might never take some values. - GrRandom random; - for (int t = 0; t < NUM_TESTS; ++t) { - - pdesc.fVertexLayout = 0; - pdesc.fEmitsPointSize = random.nextF() > .5f; - float colorType = random.nextF(); - if (colorType < 1.f / 3.f) { - pdesc.fColorType = ProgramDesc::kAttribute_ColorType; - } else if (colorType < 2.f / 3.f) { - pdesc.fColorType = ProgramDesc::kUniform_ColorType; - } else { - pdesc.fColorType = ProgramDesc::kNone_ColorType; - } - for (int s = 0; s < kNumStages; ++s) { - // enable the stage? - if (random.nextF() > .5f) { - // use separate tex coords? - if (random.nextF() > .5f) { - int t = (int)(random.nextF() * kMaxTexCoords); - pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t); - } else { - pdesc.fVertexLayout |= StagePosAsTexCoordVertexLayoutBit(s); - } - } - // use text-formatted verts? - if (random.nextF() > .5f) { - pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit; - } - } - - for (int s = 0; s < kNumStages; ++s) { - int x; - pdesc.fStages[s].fEnabled = VertexUsesStage(s, pdesc.fVertexLayout); - x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS)); - pdesc.fStages[s].fOptFlags = STAGE_OPTS[x]; - x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_MODULATES)); - pdesc.fStages[s].fModulation = (StageDesc::Modulation) STAGE_MODULATES[x]; - x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_COORD_MAPPINGS)); - pdesc.fStages[s].fCoordMapping = (StageDesc::CoordMapping) STAGE_COORD_MAPPINGS[x]; - } - Program program; - GenProgram(pdesc, &program); - DeleteProgram(&program); - } -} - -void GrGpuGLShaders2::GenStageCode(int stageNum, - const StageDesc& desc, - const char* fsInColor, // NULL means no incoming color - const char* fsOutColor, - const char* vsInCoord, - ShaderCodeSegments* segments, - StageUniLocations* locations) { - - GrAssert(stageNum >= 0 && stageNum <= 9); - - GrTokenString varyingName; - stage_varying_name(stageNum, &varyingName); - - // First decide how many coords are needed to access the texture - // Right now it's always 2 but we could start using 1D textures for - // gradients. - static const int coordDims = 2; - int varyingDims; - /// Vertex Shader Stuff - - // decide whether we need a matrix to transform texture coords - // and whether the varying needs a perspective coord. - GrTokenString texMName; - tex_matrix_name(stageNum, &texMName); - if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) { - varyingDims = coordDims; - } else { - #if GR_GL_ATTRIBUTE_MATRICES - segments->fVSAttrs += "attribute mat3 "; - segments->fVSAttrs += texMName; - segments->fVSAttrs += ";\n"; - #else - segments->fVSUnis += "uniform mat3 "; - segments->fVSUnis += texMName; - segments->fVSUnis += ";\n"; - locations->fTextureMatrixUni = 1; - #endif - if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) { - varyingDims = coordDims; - } else { - varyingDims = coordDims + 1; - } - } - - GrTokenString samplerName; - sampler_name(stageNum, &samplerName); - segments->fFSUnis += "uniform sampler2D "; - segments->fFSUnis += samplerName; - segments->fFSUnis += ";\n"; - locations->fSamplerUni = 1; - - segments->fVaryings += "varying "; - segments->fVaryings += float_vector_type(varyingDims); - segments->fVaryings += " "; - segments->fVaryings += varyingName; - segments->fVaryings += ";\n"; - - if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) { - GrAssert(varyingDims == coordDims); - segments->fVSCode += "\t"; - segments->fVSCode += varyingName; - segments->fVSCode += " = "; - segments->fVSCode += vsInCoord; - segments->fVSCode += ";\n"; - } else { - segments->fVSCode += "\t"; - segments->fVSCode += varyingName; - segments->fVSCode += " = ("; - segments->fVSCode += texMName; - segments->fVSCode += " * vec3("; - segments->fVSCode += vsInCoord; - segments->fVSCode += ", 1))"; - segments->fVSCode += vector_all_coords(varyingDims); - segments->fVSCode += ";\n"; - } - - GrTokenString radial2ParamsName; - radial2_param_name(stageNum, &radial2ParamsName); - // for radial grads without perspective we can pass the linear - // part of the quadratic as a varying. - GrTokenString radial2VaryingName; - radial2_varying_name(stageNum, &radial2VaryingName); - - if (StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping) { - - segments->fVSUnis += "uniform "; - segments->fVSUnis += GrPrecision(); - segments->fVSUnis += " float "; - segments->fVSUnis += radial2ParamsName; - segments->fVSUnis += "[6];\n"; - - segments->fFSUnis += "uniform "; - segments->fFSUnis += GrPrecision(); - segments->fFSUnis += " float "; - segments->fFSUnis += radial2ParamsName; - segments->fFSUnis += "[6];\n"; - locations->fRadial2Uni = 1; - - // if there is perspective we don't interpolate this - if (varyingDims == coordDims) { - GrAssert(2 == coordDims); - segments->fVaryings += "varying float "; - segments->fVaryings += radial2VaryingName; - segments->fVaryings += ";\n"; - - segments->fVSCode += "\t"; - segments->fVSCode += radial2VaryingName; - segments->fVSCode += " = 2.0 * ("; - segments->fVSCode += radial2ParamsName; - segments->fVSCode += "[2] * "; - segments->fVSCode += varyingName; - segments->fVSCode += ".x "; - segments->fVSCode += " - "; - segments->fVSCode += radial2ParamsName; - segments->fVSCode += "[3]);\n"; - } - } - - /// Fragment Shader Stuff - GrTokenString fsCoordName; - // function used to access the shader, may be made projective - GrTokenString texFunc("texture2D"); - if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit | - StageDesc::kNoPerspective_OptFlagBit)) { - GrAssert(varyingDims == coordDims); - fsCoordName = varyingName; - } else { - // if we have to do some non-matrix op on the varyings to get - // our final tex coords then when in perspective we have to - // do an explicit divide - if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping) { - texFunc += "Proj"; - fsCoordName = varyingName; - } else { - fsCoordName = "tCoord"; - fsCoordName.appendInt(stageNum); - - segments->fFSCode += "\t"; - segments->fFSCode += float_vector_type(coordDims); - segments->fFSCode += " "; - segments->fFSCode += fsCoordName; - segments->fFSCode += " = "; - segments->fFSCode += varyingName; - segments->fFSCode += vector_nonhomog_coords(varyingDims); - segments->fFSCode += " / "; - segments->fFSCode += varyingName; - segments->fFSCode += vector_homog_coord(varyingDims); - segments->fFSCode += ";\n"; - } - } - - GrSStringBuilder<96> sampleCoords; - switch (desc.fCoordMapping) { - case StageDesc::kIdentity_CoordMapping: - sampleCoords = fsCoordName; - break; - case StageDesc::kSweepGradient_CoordMapping: - sampleCoords = "vec2(atan(-"; - sampleCoords += fsCoordName; - sampleCoords += ".y, -"; - sampleCoords += fsCoordName; - sampleCoords += ".x)*0.1591549430918 + 0.5, 0.5)"; - break; - case StageDesc::kRadialGradient_CoordMapping: - sampleCoords = "vec2(length("; - sampleCoords += fsCoordName; - sampleCoords += ".xy), 0.5)"; - break; - case StageDesc::kRadial2Gradient_CoordMapping: { - GrTokenString cName = "c"; - GrTokenString ac4Name = "ac4"; - GrTokenString rootName = "root"; - - cName.appendInt(stageNum); - ac4Name.appendInt(stageNum); - rootName.appendInt(stageNum); - - GrTokenString bVar; - if (coordDims == varyingDims) { - bVar = radial2VaryingName; - GrAssert(2 == varyingDims); - } else { - GrAssert(3 == varyingDims); - bVar = "b"; - bVar.appendInt(stageNum); - segments->fFSCode += "\tfloat "; - segments->fFSCode += bVar; - segments->fFSCode += " = 2.0 * ("; - segments->fFSCode += radial2ParamsName; - segments->fFSCode += "[2] * "; - segments->fFSCode += fsCoordName; - segments->fFSCode += ".x "; - segments->fFSCode += " - "; - segments->fFSCode += radial2ParamsName; - segments->fFSCode += "[3]);\n"; - } - - segments->fFSCode += "\tfloat "; - segments->fFSCode += cName; - segments->fFSCode += " = dot("; - segments->fFSCode += fsCoordName; - segments->fFSCode += ", "; - segments->fFSCode += fsCoordName; - segments->fFSCode += ") + "; - segments->fFSCode += " - "; - segments->fFSCode += radial2ParamsName; - segments->fFSCode += "[4];\n"; - - segments->fFSCode += "\tfloat "; - segments->fFSCode += ac4Name; - segments->fFSCode += " = "; - segments->fFSCode += radial2ParamsName; - segments->fFSCode += "[0] * 4.0 * "; - segments->fFSCode += cName; - segments->fFSCode += ";\n"; - - segments->fFSCode += "\tfloat "; - segments->fFSCode += rootName; - segments->fFSCode += " = sqrt(abs("; - segments->fFSCode += bVar; - segments->fFSCode += " * "; - segments->fFSCode += bVar; - segments->fFSCode += " - "; - segments->fFSCode += ac4Name; - segments->fFSCode += "));\n"; - - sampleCoords = "vec2((-"; - sampleCoords += bVar; - sampleCoords += " + "; - sampleCoords += radial2ParamsName; - sampleCoords += "[5] * "; - sampleCoords += rootName; - sampleCoords += ") * "; - sampleCoords += radial2ParamsName; - sampleCoords += "[1], 0.5)\n"; - break;} - }; - - segments->fFSCode += "\t"; - segments->fFSCode += fsOutColor; - segments->fFSCode += " = "; - if (NULL != fsInColor) { - segments->fFSCode += fsInColor; - segments->fFSCode += " * "; - } - segments->fFSCode += texFunc; - segments->fFSCode += "("; - segments->fFSCode += samplerName; - segments->fFSCode += ", "; - segments->fFSCode += sampleCoords; - segments->fFSCode += ")"; - if (desc.fModulation == StageDesc::kAlpha_Modulation) { - segments->fFSCode += ".aaaa"; - } - segments->fFSCode += ";\n"; - -} - -void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc, - Program* program) { - - ShaderCodeSegments segments; - const uint32_t& layout = desc.fVertexLayout; - - memset(&program->fUniLocations, 0, sizeof(UniLocations)); - -#if GR_GL_ATTRIBUTE_MATRICES - segments.fVSAttrs += "attribute mat3 " VIEW_MATRIX_NAME ";\n"; -#else - segments.fVSUnis += "uniform mat3 " VIEW_MATRIX_NAME ";\n"; -#endif - segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n"; - - segments.fVSCode += "void main() {\n" - "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n" - "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n"; - - // incoming color to current stage being processed. - GrTokenString inColor; - - switch (desc.fColorType) { - case ProgramDesc::kAttribute_ColorType: - segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n"; - segments.fVaryings += "varying vec4 vColor;\n"; - segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n"; - inColor = "vColor"; - break; - case ProgramDesc::kUniform_ColorType: - segments.fFSUnis += "uniform vec4 " COL_UNI_NAME ";\n"; - inColor = COL_UNI_NAME; - break; - case ProgramDesc::kNone_ColorType: - inColor = ""; - break; - } - - if (desc.fEmitsPointSize){ - segments.fVSCode += "\tgl_PointSize = 1.0;\n"; - } - segments.fFSCode += "void main() {\n"; - - // add texture coordinates that are used to the list of vertex attr decls - GrTokenString texCoordAttrs[kMaxTexCoords]; - for (int t = 0; t < kMaxTexCoords; ++t) { - if (VertexUsesTexCoordIdx(t, layout)) { - tex_attr_name(t, texCoordAttrs + t); - - segments.fVSAttrs += "attribute vec2 "; - segments.fVSAttrs += texCoordAttrs[t]; - segments.fVSAttrs += ";\n"; - } - } - - // for each enabled stage figure out what the input coordinates are - // and count the number of stages in use. - const char* stageInCoords[kNumStages]; - int numActiveStages = 0; - - for (int s = 0; s < kNumStages; ++s) { - if (desc.fStages[s].fEnabled) { - if (StagePosAsTexCoordVertexLayoutBit(s) & layout) { - stageInCoords[s] = POS_ATTR_NAME; - } else { - int tcIdx = VertexTexCoordsForStage(s, layout); - // we better have input tex coordinates if stage is enabled. - GrAssert(tcIdx >= 0); - GrAssert(texCoordAttrs[tcIdx].length()); - stageInCoords[s] = texCoordAttrs[tcIdx].cstr(); - } - ++numActiveStages; - } - } - - // if we have active stages string them together, feeding the output color - // of each to the next and generating code for each stage. - if (numActiveStages) { - int currActiveStage = 0; - for (int s = 0; s < kNumStages; ++s) { - if (desc.fStages[s].fEnabled) { - GrTokenString outColor; - if (currActiveStage < (numActiveStages - 1)) { - outColor = "color"; - outColor.appendInt(currActiveStage); - segments.fFSCode += "\tvec4 "; - segments.fFSCode += outColor; - segments.fFSCode += ";\n"; - } else { - outColor = "gl_FragColor"; - } - GenStageCode(s, - desc.fStages[s], - inColor.length() ? inColor.cstr() : NULL, - outColor.cstr(), - stageInCoords[s], - &segments, - &program->fUniLocations.fStages[s]); - ++currActiveStage; - inColor = outColor; - } - } - } else { - segments.fFSCode += "\tgl_FragColor = "; - if (inColor.length()) { - segments.fFSCode += inColor; - } else { - segments.fFSCode += "vec4(1,1,1,1)"; - } - segments.fFSCode += ";\n"; - } - segments.fFSCode += "}\n"; - segments.fVSCode += "}\n"; - - - const char* strings[4]; - int lengths[4]; - int stringCnt = 0; - - if (segments.fVSUnis.length()) { - strings[stringCnt] = segments.fVSUnis.cstr(); - lengths[stringCnt] = segments.fVSUnis.length(); - ++stringCnt; - } - if (segments.fVSAttrs.length()) { - strings[stringCnt] = segments.fVSAttrs.cstr(); - lengths[stringCnt] = segments.fVSAttrs.length(); - ++stringCnt; - } - if (segments.fVaryings.length()) { - strings[stringCnt] = segments.fVaryings.cstr(); - lengths[stringCnt] = segments.fVaryings.length(); - ++stringCnt; - } - - GrAssert(segments.fVSCode.length()); - strings[stringCnt] = segments.fVSCode.cstr(); - lengths[stringCnt] = segments.fVSCode.length(); - ++stringCnt; - -#if PRINT_SHADERS - GrPrintf("%s%s%s%s\n", - segments.fVSUnis.cstr(), - segments.fVSAttrs.cstr(), - segments.fVaryings.cstr(), - segments.fVSCode.cstr()); -#endif - program->fVShaderID = CompileShader(GR_GL_VERTEX_SHADER, - stringCnt, - strings, - lengths); - - stringCnt = 0; - - if (strlen(GrShaderPrecision()) > 1) { - strings[stringCnt] = GrShaderPrecision(); - lengths[stringCnt] = strlen(GrShaderPrecision()); - ++stringCnt; - } - if (segments.fFSUnis.length()) { - strings[stringCnt] = segments.fFSUnis.cstr(); - lengths[stringCnt] = segments.fFSUnis.length(); - ++stringCnt; - } - if (segments.fVaryings.length()) { - strings[stringCnt] = segments.fVaryings.cstr(); - lengths[stringCnt] = segments.fVaryings.length(); - ++stringCnt; - } - - GrAssert(segments.fFSCode.length()); - strings[stringCnt] = segments.fFSCode.cstr(); - lengths[stringCnt] = segments.fFSCode.length(); - ++stringCnt; - -#if PRINT_SHADERS - GrPrintf("%s%s%s%s\n", - GrShaderPrecision(), - segments.fFSUnis.cstr(), - segments.fVaryings.cstr(), - segments.fFSCode.cstr()); -#endif - program->fFShaderID = CompileShader(GR_GL_FRAGMENT_SHADER, - stringCnt, - strings, - lengths); - - program->fProgramID = GR_GL(CreateProgram()); - const GrGLint& progID = program->fProgramID; - - GR_GL(AttachShader(progID, program->fVShaderID)); - GR_GL(AttachShader(progID, program->fFShaderID)); - - // Bind the attrib locations to same values for all shaders - GR_GL(BindAttribLocation(progID, POS_ATTR_LOCATION, POS_ATTR_NAME)); - for (int t = 0; t < kMaxTexCoords; ++t) { - if (texCoordAttrs[t].length()) { - GR_GL(BindAttribLocation(progID, - TEX_ATTR_LOCATION(t), - texCoordAttrs[t].cstr())); - } - } - -#if GR_GL_ATTRIBUTE_MATRICES - // set unis to a bogus value so that checks against -1 before - // flushing will pass. - GR_GL(BindAttribLocation(progID, - VIEWMAT_ATTR_LOCATION, - VIEW_MATRIX_NAME)); - - program->fUniLocations.fViewMatrixUni = BOGUS_MATRIX_UNI_LOCATION; - - for (int s = 0; s < kNumStages; ++s) { - if (desc.fStages[s].fEnabled) { - GrStringBuilder matName; - tex_matrix_name(s, &matName); - GR_GL(BindAttribLocation(progID, - TEXMAT_ATTR_LOCATION(s), - matName.cstr())); - program->fUniLocations.fStages[s].fTextureMatrixUni = - BOGUS_MATRIX_UNI_LOCATION; - } - } -#endif - - GR_GL(BindAttribLocation(progID, COL_ATTR_LOCATION, COL_ATTR_NAME)); - - GR_GL(LinkProgram(progID)); - - GrGLint linked = GR_GL_INIT_ZERO; - GR_GL(GetProgramiv(progID, GR_GL_LINK_STATUS, &linked)); - if (!linked) { - GrGLint infoLen = GR_GL_INIT_ZERO; - GR_GL(GetProgramiv(progID, GR_GL_INFO_LOG_LENGTH, &infoLen)); - GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger - if (infoLen > 0) { - GR_GL(GetProgramInfoLog(progID, - infoLen+1, - NULL, - (char*)log.get())); - GrPrintf((char*)log.get()); - } - GrAssert(!"Error linking program"); - GR_GL(DeleteProgram(progID)); - program->fProgramID = 0; - return; - } - - // Get uniform locations -#if !GR_GL_ATTRIBUTE_MATRICES - program->fUniLocations.fViewMatrixUni = - GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME)); - GrAssert(-1 != program->fUniLocations.fViewMatrixUni); -#endif - if (ProgramDesc::kUniform_ColorType == desc.fColorType) { - program->fUniLocations.fColorUni = - GR_GL(GetUniformLocation(progID, COL_UNI_NAME)); - GrAssert(-1 != program->fUniLocations.fColorUni); - } else { - program->fUniLocations.fColorUni = -1; - } - - for (int s = 0; s < kNumStages; ++s) { - StageUniLocations& locations = program->fUniLocations.fStages[s]; - if (desc.fStages[s].fEnabled) { -#if !GR_GL_ATTRIBUTE_MATRICES - if (locations.fTextureMatrixUni) { - GrTokenString texMName; - tex_matrix_name(s, &texMName); - locations.fTextureMatrixUni = GR_GL(GetUniformLocation( - progID, - texMName.cstr())); - GrAssert(-1 != locations.fTextureMatrixUni); - } else { - locations.fTextureMatrixUni = -1; - - } -#endif - - if (locations.fSamplerUni) { - GrTokenString samplerName; - sampler_name(s, &samplerName); - locations.fSamplerUni = GR_GL(GetUniformLocation( - progID, - samplerName.cstr())); - GrAssert(-1 != locations.fSamplerUni); - } else { - locations.fSamplerUni = -1; - } - - if (locations.fRadial2Uni) { - GrTokenString radial2ParamName; - radial2_param_name(s, &radial2ParamName); - locations.fRadial2Uni = GR_GL(GetUniformLocation( - progID, - radial2ParamName.cstr())); - GrAssert(-1 != locations.fRadial2Uni); - } else { - locations.fRadial2Uni = -1; - } - } else { - locations.fSamplerUni = -1; - locations.fRadial2Uni = -1; - locations.fTextureMatrixUni = -1; - } - } - GR_GL(UseProgram(progID)); - - // init sampler unis and set bogus values for state tracking - for (int s = 0; s < kNumStages; ++s) { - if (-1 != program->fUniLocations.fStages[s].fSamplerUni) { - GR_GL(Uniform1i(program->fUniLocations.fStages[s].fSamplerUni, s)); - } - program->fTextureMatrices[s] = GrMatrix::InvalidMatrix(); - program->fRadial2CenterX1[s] = GR_ScalarMax; - program->fRadial2Radius0[s] = -GR_ScalarMax; - program->fColor = GrColor_ILLEGAL; - } - program->fViewMatrix = GrMatrix::InvalidMatrix(); -} - -void GrGpuGLShaders2::getProgramDesc(GrPrimitiveType primType, ProgramDesc* desc) { - - // Must initialize all fields or cache will have false negatives! - desc->fVertexLayout = fGeometrySrc.fVertexLayout; - - desc->fEmitsPointSize = kPoints_PrimitiveType == primType; - - bool requiresAttributeColors = desc->fVertexLayout & kColor_VertexLayoutBit; - // fColorType records how colors are specified for the program. Strip - // the bit from the layout to avoid false negatives when searching for an - // existing program in the cache. - desc->fVertexLayout &= ~(kColor_VertexLayoutBit); - -#if GR_AGGRESSIVE_SHADER_OPTS - if (!requiresAttributeColors && (0xffffffff == fCurrDrawState.fColor)) { - desc->fColorType = ProgramDesc::kNone_ColorType; - } else -#endif -#if GR_GL_NO_CONSTANT_ATTRIBUTES - if (!requiresAttributeColors) { - desc->fColorType = ProgramDesc::kUniform_ColorType; - } else -#endif - { - if (requiresAttributeColors) {} // suppress unused var warning - desc->fColorType = ProgramDesc::kAttribute_ColorType; - } - - for (int s = 0; s < kNumStages; ++s) { - StageDesc& stage = desc->fStages[s]; - - stage.fEnabled = this->isStageEnabled(s); - - if (stage.fEnabled) { - GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; - GrAssert(NULL != texture); - // we matrix to invert when orientation is TopDown, so make sure - // we aren't in that case before flagging as identity. - if (TextureMatrixIsIdentity(texture, fCurrDrawState.fSamplerStates[s])) { - stage.fOptFlags = StageDesc::kIdentityMatrix_OptFlagBit; - } else if (!getSamplerMatrix(s).hasPerspective()) { - stage.fOptFlags = StageDesc::kNoPerspective_OptFlagBit; - } else { - stage.fOptFlags = 0; - } - switch (fCurrDrawState.fSamplerStates[s].getSampleMode()) { - case GrSamplerState::kNormal_SampleMode: - stage.fCoordMapping = StageDesc::kIdentity_CoordMapping; - break; - case GrSamplerState::kRadial_SampleMode: - stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping; - break; - case GrSamplerState::kRadial2_SampleMode: - stage.fCoordMapping = StageDesc::kRadial2Gradient_CoordMapping; - break; - case GrSamplerState::kSweep_SampleMode: - stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping; - break; - default: - GrAssert(!"Unexpected sample mode!"); - break; - } - if (GrPixelConfigIsAlphaOnly(texture->config())) { - stage.fModulation = StageDesc::kAlpha_Modulation; - } else { - stage.fModulation = StageDesc::kColor_Modulation; - } - } else { - stage.fOptFlags = 0; - stage.fCoordMapping = (StageDesc::CoordMapping)0; - stage.fModulation = (StageDesc::Modulation)0; - } - } -} - -GrGLuint GrGpuGLShaders2::CompileShader(GrGLenum type, - int stringCnt, - const char** strings, - int* stringLengths) { - GrGLuint shader = GR_GL(CreateShader(type)); - if (0 == shader) { - return 0; - } - - GrGLint compiled = GR_GL_INIT_ZERO; - GR_GL(ShaderSource(shader, stringCnt, strings, stringLengths)); - GR_GL(CompileShader(shader)); - GR_GL(GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); - - if (!compiled) { - GrGLint infoLen = GR_GL_INIT_ZERO; - GR_GL(GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); - GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger - if (infoLen > 0) { - GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get())); - for (int i = 0; i < stringCnt; ++i) { - if (NULL == stringLengths || stringLengths[i] < 0) { - GrPrintf(strings[i]); - } else { - GrPrintf("%.*s", stringLengths[i], strings[i]); - } - } - GrPrintf("\n%s", log.get()); - } - GrAssert(!"Shader compilation failed!"); - GR_GL(DeleteShader(shader)); - return 0; - } - return shader; -} - -void GrGpuGLShaders2::DeleteProgram(Program* program) { - GR_GL(DeleteShader(program->fVShaderID)); - GR_GL(DeleteShader(program->fFShaderID)); - GR_GL(DeleteProgram(program->fProgramID)); - GR_DEBUGCODE(memset(program, 0, sizeof(Program))); -} - - -GrGpuGLShaders2::GrGpuGLShaders2() { - - f4X4DownsampleFilterSupport = false; - fProgram = NULL; - fProgramCache = new ProgramCache(); - -#if 0 - ProgramUnitTest(); -#endif -} - -GrGpuGLShaders2::~GrGpuGLShaders2() { - delete fProgramCache; -} - -const GrMatrix& GrGpuGLShaders2::getHWSamplerMatrix(int stage) { -#if GR_GL_ATTRIBUTE_MATRICES - return fHWDrawState.fSamplerStates[stage].getMatrix(); -#else - return fProgram->fTextureMatrices[stage]; -#endif -} - -void GrGpuGLShaders2::recordHWSamplerMatrix(int stage, const GrMatrix& matrix){ -#if GR_GL_ATTRIBUTE_MATRICES - fHWDrawState.fSamplerStates[stage].setMatrix(matrix); -#else - fProgram->fTextureMatrices[stage] = matrix; -#endif -} - -void GrGpuGLShaders2::resetContext() { - - INHERITED::resetContext(); - - fHWGeometryState.fVertexLayout = 0; - fHWGeometryState.fVertexOffset = ~0; - GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION)); - for (int t = 0; t < kMaxTexCoords; ++t) { - GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t))); - } - GR_GL(EnableVertexAttribArray(POS_ATTR_LOCATION)); - - fHWProgramID = 0; -} - -void GrGpuGLShaders2::flushViewMatrix() { - GrAssert(NULL != fCurrDrawState.fRenderTarget); - GrMatrix m ( - GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1, - 0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1, - 0, 0, GrMatrix::I()[8]); - m.setConcat(m, fCurrDrawState.fViewMatrix); - - // ES doesn't allow you to pass true to the transpose param, - // so do our own transpose - GrScalar mt[] = { - m[GrMatrix::kScaleX], - m[GrMatrix::kSkewY], - m[GrMatrix::kPersp0], - m[GrMatrix::kSkewX], - m[GrMatrix::kScaleY], - m[GrMatrix::kPersp1], - m[GrMatrix::kTransX], - m[GrMatrix::kTransY], - m[GrMatrix::kPersp2] - }; -#if GR_GL_ATTRIBUTE_MATRICES - GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+0, mt+0)); - GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+1, mt+3)); - GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+2, mt+6)); -#else - GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fViewMatrixUni,1,false,mt)); -#endif -} - -void GrGpuGLShaders2::flushTextureMatrix(int stage) { - GrAssert(NULL != fCurrDrawState.fTextures[stage]); - - GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[stage]; - - GrMatrix m = getSamplerMatrix(stage); - GrSamplerState::SampleMode mode = - fCurrDrawState.fSamplerStates[stage].getSampleMode(); - AdjustTextureMatrix(texture, mode, &m); - - // ES doesn't allow you to pass true to the transpose param, - // so do our own transpose - GrScalar mt[] = { - m[GrMatrix::kScaleX], - m[GrMatrix::kSkewY], - m[GrMatrix::kPersp0], - m[GrMatrix::kSkewX], - m[GrMatrix::kScaleY], - m[GrMatrix::kPersp1], - m[GrMatrix::kTransX], - m[GrMatrix::kTransY], - m[GrMatrix::kPersp2] - }; -#if GR_GL_ATTRIBUTE_MATRICES - GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0)); - GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3)); - GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6)); -#else - GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fStages[stage].fTextureMatrixUni, - 1, false, mt)); -#endif -} - -void GrGpuGLShaders2::flushRadial2(int stage) { - - const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[stage]; - - GrScalar centerX1 = sampler.getRadial2CenterX1(); - GrScalar radius0 = sampler.getRadial2Radius0(); - - GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1; - - float unis[6] = { - GrScalarToFloat(a), - 1 / (2.f * unis[0]), - GrScalarToFloat(centerX1), - GrScalarToFloat(radius0), - GrScalarToFloat(GrMul(radius0, radius0)), - sampler.isRadial2PosRoot() ? 1.f : -1.f - }; - GR_GL(Uniform1fv(fProgram->fUniLocations.fStages[stage].fRadial2Uni, - 6, - unis)); -} - -void GrGpuGLShaders2::flushProgram(GrPrimitiveType type, ProgramDesc* desc) { - getProgramDesc(type, desc); - fProgram = fProgramCache->getProgram(*desc); - - if (fHWProgramID != fProgram->fProgramID) { - GR_GL(UseProgram(fProgram->fProgramID)); - fHWProgramID = fProgram->fProgramID; -#if GR_COLLECT_STATS - ++fStats.fProgChngCnt; -#endif - } -} - -void GrGpuGLShaders2::flushColor(const ProgramDesc& desc) { - if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) { - // color will be specified per-vertex as an attribute - // invalidate the const vertex attrib color - fHWDrawState.fColor = GrColor_ILLEGAL; - } else { - switch (desc.fColorType) { - case ProgramDesc::kAttribute_ColorType: - if (fHWDrawState.fColor != fCurrDrawState.fColor) { - // OpenGL ES only supports the float varities of glVertexAttrib - float c[] = { - GrColorUnpackR(fCurrDrawState.fColor) / 255.f, - GrColorUnpackG(fCurrDrawState.fColor) / 255.f, - GrColorUnpackB(fCurrDrawState.fColor) / 255.f, - GrColorUnpackA(fCurrDrawState.fColor) / 255.f - }; - GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c)); - fHWDrawState.fColor = fCurrDrawState.fColor; - } - break; - case ProgramDesc::kUniform_ColorType: - if (fProgram->fColor != fCurrDrawState.fColor) { - // OpenGL ES only supports the float varities of glVertexAttrib - float c[] = { - GrColorUnpackR(fCurrDrawState.fColor) / 255.f, - GrColorUnpackG(fCurrDrawState.fColor) / 255.f, - GrColorUnpackB(fCurrDrawState.fColor) / 255.f, - GrColorUnpackA(fCurrDrawState.fColor) / 255.f - }; - GrAssert(-1 != fProgram->fUniLocations.fColorUni); - GR_GL(Uniform4fv(fProgram->fUniLocations.fColorUni, 1, c)); - fProgram->fColor = fCurrDrawState.fColor; - } - break; - case ProgramDesc::kNone_ColorType: - GrAssert(0xffffffff == fCurrDrawState.fColor); - break; - default: - GrCrash("Unknown color type."); - } - } -} - -bool GrGpuGLShaders2::flushGraphicsState(GrPrimitiveType type) { - - if (!flushGLStateCommon(type)) { - return false; - } - - if (fDirtyFlags.fRenderTargetChanged) { - // our coords are in pixel space and the GL matrices map to NDC - // so if the viewport changed, our matrix is now wrong. -#if GR_GL_ATTRIBUTE_MATRICES - fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); -#else - // we assume all shader matrices may be wrong after viewport changes - fProgramCache->invalidateViewMatrices(); -#endif - } - - ProgramDesc desc; - flushProgram(type, &desc); - - flushColor(desc); - -#if GR_GL_ATTRIBUTE_MATRICES - GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix; -#else - GrMatrix& currViewMatrix = fProgram->fViewMatrix; -#endif - - if (currViewMatrix != fCurrDrawState.fViewMatrix) { - flushViewMatrix(); - currViewMatrix = fCurrDrawState.fViewMatrix; - } - - for (int s = 0; s < kNumStages; ++s) { - GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; - if (NULL != texture) { - if (-1 != fProgram->fUniLocations.fStages[s].fTextureMatrixUni && - (((1 << s) & fDirtyFlags.fTextureChangedMask) || - getHWSamplerMatrix(s) != getSamplerMatrix(s))) { - flushTextureMatrix(s); - recordHWSamplerMatrix(s, getSamplerMatrix(s)); - } - } - - const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s]; - if (-1 != fProgram->fUniLocations.fStages[s].fRadial2Uni && - (fProgram->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() || - fProgram->fRadial2Radius0[s] != sampler.getRadial2Radius0() || - fProgram->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) { - - flushRadial2(s); - - fProgram->fRadial2CenterX1[s] = sampler.getRadial2CenterX1(); - fProgram->fRadial2Radius0[s] = sampler.getRadial2Radius0(); - fProgram->fRadial2PosRoot[s] = sampler.isRadial2PosRoot(); - } - } - resetDirtyFlags(); - return true; -} - -void GrGpuGLShaders2::setupGeometry(int* startVertex, - int* startIndex, - int vertexCount, - int indexCount) { - - int newColorOffset; - int newTexCoordOffsets[kMaxTexCoords]; - - GrGLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout, - newTexCoordOffsets, - &newColorOffset); - int oldColorOffset; - int oldTexCoordOffsets[kMaxTexCoords]; - GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout, - oldTexCoordOffsets, - &oldColorOffset); - bool indexed = NULL != startIndex; - - int extraVertexOffset; - int extraIndexOffset; - setBuffers(indexed, &extraVertexOffset, &extraIndexOffset); - - GrGLenum scalarType; - bool texCoordNorm; - if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) { - scalarType = GrGLTextType; - texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED; - } else { - scalarType = GrGLType; - texCoordNorm = false; - } - - size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride; - *startVertex = 0; - if (indexed) { - *startIndex += extraIndexOffset; - } - - // all the Pointers must be set if any of these are true - bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty || - vertexOffset != fHWGeometryState.fVertexOffset || - newStride != oldStride; - - // position and tex coord offsets change if above conditions are true - // or the type/normalization changed based on text vs nontext type coords. - bool posAndTexChange = allOffsetsChange || - (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) && - (kTextFormat_VertexLayoutBit & - (fHWGeometryState.fVertexLayout ^ - fGeometrySrc.fVertexLayout))); - - if (posAndTexChange) { - GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType, - false, newStride, (GrGLvoid*)vertexOffset)); - fHWGeometryState.fVertexOffset = vertexOffset; - } - - for (int t = 0; t < kMaxTexCoords; ++t) { - if (newTexCoordOffsets[t] > 0) { - GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]); - if (oldTexCoordOffsets[t] <= 0) { - GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t))); - GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType, - texCoordNorm, newStride, texCoordOffset)); - } else if (posAndTexChange || - newTexCoordOffsets[t] != oldTexCoordOffsets[t]) { - GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType, - texCoordNorm, newStride, texCoordOffset)); - } - } else if (oldTexCoordOffsets[t] > 0) { - GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t))); - } - } - - if (newColorOffset > 0) { - GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset); - if (oldColorOffset <= 0) { - GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION)); - GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4, - GR_GL_UNSIGNED_BYTE, - true, newStride, colorOffset)); - } else if (allOffsetsChange || newColorOffset != oldColorOffset) { - GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4, - GR_GL_UNSIGNED_BYTE, - true, newStride, colorOffset)); - } - } else if (oldColorOffset > 0) { - GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION)); - } - - fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout; - fHWGeometryState.fArrayPtrsDirty = false; -} |