aboutsummaryrefslogtreecommitdiffstats
path: root/gpu/src/GrGpuGLShaders.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/src/GrGpuGLShaders.cpp')
-rw-r--r--gpu/src/GrGpuGLShaders.cpp845
1 files changed, 0 insertions, 845 deletions
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
deleted file mode 100644
index 0a933b5..0000000
--- a/gpu/src/GrGpuGLShaders.cpp
+++ /dev/null
@@ -1,845 +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 "GrBinHashKey.h"
-#include "GrGLProgram.h"
-#include "GrGpuGLShaders.h"
-#include "GrGpuVertex.h"
-#include "GrMemory.h"
-#include "GrNoncopyable.h"
-#include "GrStringBuilder.h"
-#include "GrRandom.h"
-
-#define SKIP_CACHE_CHECK true
-#define GR_UINT32_MAX static_cast<uint32_t>(-1)
-
-#include "GrTHashCache.h"
-
-class GrGpuGLShaders::ProgramCache : public ::GrNoncopyable {
-private:
- class Entry;
-
-#if GR_DEBUG
- typedef GrBinHashKey<Entry, 4> ProgramHashKey; // Flex the dynamic allocation muscle in debug
-#else
- typedef GrBinHashKey<Entry, 64> ProgramHashKey;
-#endif
-
- class Entry : public ::GrNoncopyable {
- public:
- Entry() {}
- void copyAndTakeOwnership(Entry& entry) {
- fProgramData.copyAndTakeOwnership(entry.fProgramData);
- fKey.copyAndTakeOwnership(entry.fKey); // ownership transfer
- fLRUStamp = entry.fLRUStamp;
- }
-
- public:
- int compare(const ProgramHashKey& key) const { return fKey.compare(key); }
-
- public:
- GrGLProgram::CachedData fProgramData;
- ProgramHashKey fKey;
- unsigned int fLRUStamp;
- };
-
- GrTHashTable<Entry, ProgramHashKey, 8> fHashCache;
-
- // We may have kMaxEntries+1 shaders in the GL context because
- // we create a new shader before evicting from the cache.
- enum {
- kMaxEntries = 32
- };
- Entry fEntries[kMaxEntries];
- int fCount;
- unsigned int fCurrLRUStamp;
-
-public:
- ProgramCache()
- : fCount(0)
- , fCurrLRUStamp(0) {
- }
-
- ~ProgramCache() {
- for (int i = 0; i < fCount; ++i) {
- GrGpuGLShaders::DeleteProgram(&fEntries[i].fProgramData);
- }
- }
-
- void abandon() {
- fCount = 0;
- }
-
- void invalidateViewMatrices() {
- for (int i = 0; i < fCount; ++i) {
- // set to illegal matrix
- fEntries[i].fProgramData.fViewMatrix = GrMatrix::InvalidMatrix();
- }
- }
-
- GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc) {
- Entry newEntry;
- while (newEntry.fKey.doPass()) {
- desc.buildKey(newEntry.fKey);
- }
- Entry* entry = fHashCache.find(newEntry.fKey);
- if (NULL == entry) {
- if (!desc.genProgram(&newEntry.fProgramData)) {
- return NULL;
- }
- if (fCount < kMaxEntries) {
- entry = fEntries + fCount;
- ++fCount;
- } else {
- GrAssert(kMaxEntries == fCount);
- entry = fEntries;
- for (int i = 1; i < kMaxEntries; ++i) {
- if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
- entry = fEntries + i;
- }
- }
- fHashCache.remove(entry->fKey, entry);
- GrGpuGLShaders::DeleteProgram(&entry->fProgramData);
- }
- entry->copyAndTakeOwnership(newEntry);
- 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->fProgramData;
- }
-};
-
-void GrGpuGLShaders::abandonResources(){
- INHERITED::abandonResources();
- fProgramCache->abandon();
-}
-
-void GrGpuGLShaders::DeleteProgram(GrGLProgram::CachedData* programData) {
- GR_GL(DeleteShader(programData->fVShaderID));
- GR_GL(DeleteShader(programData->fFShaderID));
- GR_GL(DeleteProgram(programData->fProgramID));
- GR_DEBUGCODE(memset(programData, 0, sizeof(*programData));)
-}
-
-void GrGpuGLShaders::ProgramUnitTest() {
-
- static const int STAGE_OPTS[] = {
- 0,
- GrGLProgram::ProgramDesc::StageDesc::kNoPerspective_OptFlagBit,
- GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping
- };
- static const GrGLProgram::ProgramDesc::StageDesc::Modulation STAGE_MODULATES[] = {
- GrGLProgram::ProgramDesc::StageDesc::kColor_Modulation,
- GrGLProgram::ProgramDesc::StageDesc::kAlpha_Modulation
- };
- static const GrGLProgram::ProgramDesc::StageDesc::CoordMapping STAGE_COORD_MAPPINGS[] = {
- GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping,
- GrGLProgram::ProgramDesc::StageDesc::kRadialGradient_CoordMapping,
- GrGLProgram::ProgramDesc::StageDesc::kSweepGradient_CoordMapping,
- GrGLProgram::ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping
- };
- static const GrGLProgram::ProgramDesc::StageDesc::FetchMode FETCH_MODES[] = {
- GrGLProgram::ProgramDesc::StageDesc::kSingle_FetchMode,
- GrGLProgram::ProgramDesc::StageDesc::k2x2_FetchMode,
- };
- GrGLProgram program;
- GrGLProgram::ProgramDesc& pdesc = program.fProgramDesc;
-
- 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) {
-
-#if 0
- GrPrintf("\nTest Program %d\n-------------\n", t);
- static const int stop = -1;
- if (t == stop) {
- int breakpointhere = 9;
- }
-#endif
-
- pdesc.fVertexLayout = 0;
- pdesc.fEmitsPointSize = random.nextF() > .5f;
- float colorType = random.nextF();
- if (colorType < 1.f / 3.f) {
- pdesc.fColorType = GrGLProgram::ProgramDesc::kAttribute_ColorType;
- } else if (colorType < 2.f / 3.f) {
- pdesc.fColorType = GrGLProgram::ProgramDesc::kUniform_ColorType;
- } else {
- pdesc.fColorType = GrGLProgram::ProgramDesc::kNone_ColorType;
- }
-
- int idx = (int)(random.nextF() * (SkXfermode::kCoeffModesCnt));
- pdesc.fColorFilterXfermode = (SkXfermode::Mode)idx;
-
- idx = (int)(random.nextF() * (kNumStages+1));
- pdesc.fFirstCoverageStage = idx;
-
- pdesc.fEdgeAANumEdges = (random.nextF() * (getMaxEdges() + 1));
-
- if (fDualSourceBlendingSupport) {
- pdesc.fDualSrcOutput =
- (GrGLProgram::ProgramDesc::DualSrcOutput)
- (int)(random.nextF() * GrGLProgram::ProgramDesc::kDualSrcOutputCnt);
- } else {
- pdesc.fDualSrcOutput =
- GrGLProgram::ProgramDesc::kNone_DualSrcOutput;
- }
-
- 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;
- }
- idx = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS));
- pdesc.fStages[s].fOptFlags = STAGE_OPTS[idx];
- idx = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_MODULATES));
- pdesc.fStages[s].fModulation = STAGE_MODULATES[idx];
- idx = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_COORD_MAPPINGS));
- pdesc.fStages[s].fCoordMapping = STAGE_COORD_MAPPINGS[idx];
- idx = (int)(random.nextF() * GR_ARRAY_COUNT(FETCH_MODES));
- pdesc.fStages[s].fFetchMode = FETCH_MODES[idx];
- pdesc.fStages[s].setEnabled(VertexUsesStage(s, pdesc.fVertexLayout));
- }
- GrGLProgram::CachedData cachedData;
- program.genProgram(&cachedData);
- DeleteProgram(&cachedData);
- bool again = false;
- if (again) {
- program.genProgram(&cachedData);
- DeleteProgram(&cachedData);
- }
- }
-}
-
-GrGpuGLShaders::GrGpuGLShaders() {
-
- resetContext();
- int major, minor;
- gl_version(&major, &minor);
-
- f4X4DownsampleFilterSupport = true;
- if (GR_GL_SUPPORT_DESKTOP) {
- fDualSourceBlendingSupport =
- major > 3 ||(3 == major && 3 <= minor) ||
- has_gl_extension("GL_ARB_blend_func_extended");
- } else {
- fDualSourceBlendingSupport = false;
- }
-
- fProgramData = NULL;
- fProgramCache = new ProgramCache();
-
-#if 0
- ProgramUnitTest();
-#endif
-}
-
-GrGpuGLShaders::~GrGpuGLShaders() {
- delete fProgramCache;
-}
-
-const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
- GrAssert(fProgramData);
-
- if (GrGLProgram::kSetAsAttribute ==
- fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
- return fHWDrawState.fSamplerStates[stage].getMatrix();
- } else {
- return fProgramData->fTextureMatrices[stage];
- }
-}
-
-void GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
- GrAssert(fProgramData);
- if (GrGLProgram::kSetAsAttribute ==
- fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
- fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
- } else {
- fProgramData->fTextureMatrices[stage] = matrix;
- }
-}
-
-void GrGpuGLShaders::resetContext() {
- INHERITED::resetContext();
-
- fHWGeometryState.fVertexLayout = 0;
- fHWGeometryState.fVertexOffset = ~0;
- GR_GL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
- for (int t = 0; t < kMaxTexCoords; ++t) {
- GR_GL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
- }
- GR_GL(EnableVertexAttribArray(GrGLProgram::PositionAttributeIdx()));
-
- fHWProgramID = 0;
-}
-
-void GrGpuGLShaders::flushViewMatrix() {
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
- GrMatrix m;
- m.setAll(
- 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
- GrGLfloat mt[] = {
- GrScalarToFloat(m[GrMatrix::kMScaleX]),
- GrScalarToFloat(m[GrMatrix::kMSkewY]),
- GrScalarToFloat(m[GrMatrix::kMPersp0]),
- GrScalarToFloat(m[GrMatrix::kMSkewX]),
- GrScalarToFloat(m[GrMatrix::kMScaleY]),
- GrScalarToFloat(m[GrMatrix::kMPersp1]),
- GrScalarToFloat(m[GrMatrix::kMTransX]),
- GrScalarToFloat(m[GrMatrix::kMTransY]),
- GrScalarToFloat(m[GrMatrix::kMPersp2])
- };
-
- if (GrGLProgram::kSetAsAttribute ==
- fProgramData->fUniLocations.fViewMatrixUni) {
- int baseIdx = GrGLProgram::ViewMatrixAttributeIdx();
- GR_GL(VertexAttrib4fv(baseIdx + 0, mt+0));
- GR_GL(VertexAttrib4fv(baseIdx + 1, mt+3));
- GR_GL(VertexAttrib4fv(baseIdx + 2, mt+6));
- } else {
- GrAssert(GrGLProgram::kUnusedUniform !=
- fProgramData->fUniLocations.fViewMatrixUni);
- GR_GL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
- 1, false, mt));
- }
-}
-
-void GrGpuGLShaders::flushTextureDomain(int s) {
- const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni;
- if (GrGLProgram::kUnusedUniform != uni) {
- const GrRect &texDom =
- fCurrDrawState.fSamplerStates[s].getTextureDomain();
-
- if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
- fProgramData->fTextureDomain[s] != texDom) {
-
- fProgramData->fTextureDomain[s] = texDom;
-
- float values[4] = {
- GrScalarToFloat(texDom.left()),
- GrScalarToFloat(texDom.top()),
- GrScalarToFloat(texDom.right()),
- GrScalarToFloat(texDom.bottom())
- };
-
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
- GrGLTexture::Orientation orientation = texture->orientation();
-
- // vertical flip if necessary
- if (GrGLTexture::kBottomUp_Orientation == orientation) {
- values[1] = 1.0f - values[1];
- values[3] = 1.0f - values[3];
- // The top and bottom were just flipped, so correct the ordering
- // of elements so that values = (l, t, r, b).
- SkTSwap(values[1], values[3]);
- }
-
- values[0] *= SkScalarToFloat(texture->contentScaleX());
- values[2] *= SkScalarToFloat(texture->contentScaleX());
- values[1] *= SkScalarToFloat(texture->contentScaleY());
- values[3] *= SkScalarToFloat(texture->contentScaleY());
-
- GR_GL(Uniform4fv(uni, 1, values));
- }
- }
-}
-
-void GrGpuGLShaders::flushTextureMatrix(int s) {
- const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni;
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
- if (NULL != texture) {
- if (GrGLProgram::kUnusedUniform != uni &&
- (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
- getHWSamplerMatrix(s) != getSamplerMatrix(s))) {
-
- GrAssert(NULL != fCurrDrawState.fTextures[s]);
-
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
-
- GrMatrix m = getSamplerMatrix(s);
- GrSamplerState::SampleMode mode =
- fCurrDrawState.fSamplerStates[s].getSampleMode();
- AdjustTextureMatrix(texture, mode, &m);
-
- // ES doesn't allow you to pass true to the transpose param,
- // so do our own transpose
- GrGLfloat mt[] = {
- GrScalarToFloat(m[GrMatrix::kMScaleX]),
- GrScalarToFloat(m[GrMatrix::kMSkewY]),
- GrScalarToFloat(m[GrMatrix::kMPersp0]),
- GrScalarToFloat(m[GrMatrix::kMSkewX]),
- GrScalarToFloat(m[GrMatrix::kMScaleY]),
- GrScalarToFloat(m[GrMatrix::kMPersp1]),
- GrScalarToFloat(m[GrMatrix::kMTransX]),
- GrScalarToFloat(m[GrMatrix::kMTransY]),
- GrScalarToFloat(m[GrMatrix::kMPersp2])
- };
-
- if (GrGLProgram::kSetAsAttribute ==
- fProgramData->fUniLocations.fStages[s].fTextureMatrixUni) {
- int baseIdx = GrGLProgram::TextureMatrixAttributeIdx(s);
- GR_GL(VertexAttrib4fv(baseIdx + 0, mt+0));
- GR_GL(VertexAttrib4fv(baseIdx + 1, mt+3));
- GR_GL(VertexAttrib4fv(baseIdx + 2, mt+6));
- } else {
- GR_GL(UniformMatrix3fv(uni, 1, false, mt));
- }
- recordHWSamplerMatrix(s, getSamplerMatrix(s));
- }
- }
-}
-
-void GrGpuGLShaders::flushRadial2(int s) {
-
- const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
- const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
- if (GrGLProgram::kUnusedUniform != uni &&
- (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
- fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() ||
- fProgramData->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) {
-
- GrScalar centerX1 = sampler.getRadial2CenterX1();
- GrScalar radius0 = sampler.getRadial2Radius0();
-
- GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
-
- float values[6] = {
- GrScalarToFloat(a),
- 1 / (2.f * values[0]),
- GrScalarToFloat(centerX1),
- GrScalarToFloat(radius0),
- GrScalarToFloat(GrMul(radius0, radius0)),
- sampler.isRadial2PosRoot() ? 1.f : -1.f
- };
- GR_GL(Uniform1fv(uni, 6, values));
- fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
- fProgramData->fRadial2Radius0[s] = sampler.getRadial2Radius0();
- fProgramData->fRadial2PosRoot[s] = sampler.isRadial2PosRoot();
- }
-}
-
-void GrGpuGLShaders::flushTexelSize(int s) {
- const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
- if (GrGLProgram::kUnusedUniform != uni) {
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
- if (texture->allocWidth() != fProgramData->fTextureWidth[s] ||
- texture->allocHeight() != fProgramData->fTextureWidth[s]) {
-
- float texelSize[] = {1.f / texture->allocWidth(),
- 1.f / texture->allocHeight()};
- GR_GL(Uniform2fv(uni, 1, texelSize));
- }
- }
-}
-
-void GrGpuGLShaders::flushEdgeAAData() {
- const int& uni = fProgramData->fUniLocations.fEdgesUni;
- if (GrGLProgram::kUnusedUniform != uni) {
- int count = fCurrDrawState.fEdgeAANumEdges;
- Edge edges[kMaxEdges];
- // Flip the edges in Y
- float height = fCurrDrawState.fRenderTarget->height();
- for (int i = 0; i < count; ++i) {
- edges[i] = fCurrDrawState.fEdgeAAEdges[i];
- float b = edges[i].fY;
- edges[i].fY = -b;
- edges[i].fZ += b * height;
- }
- GR_GL(Uniform3fv(uni, count, &edges[0].fX));
- }
-}
-
-static const float ONE_OVER_255 = 1.f / 255.f;
-
-#define GR_COLOR_TO_VEC4(color) {\
- GrColorUnpackR(color) * ONE_OVER_255,\
- GrColorUnpackG(color) * ONE_OVER_255,\
- GrColorUnpackB(color) * ONE_OVER_255,\
- GrColorUnpackA(color) * ONE_OVER_255 \
-}
-
-void GrGpuGLShaders::flushColor() {
- const GrGLProgram::ProgramDesc& desc = fCurrentProgram.getDesc();
- 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 GrGLProgram::ProgramDesc::kAttribute_ColorType:
- if (fHWDrawState.fColor != fCurrDrawState.fColor) {
- // OpenGL ES only supports the float varities of glVertexAttrib
- float c[] = GR_COLOR_TO_VEC4(fCurrDrawState.fColor);
- GR_GL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), c));
- fHWDrawState.fColor = fCurrDrawState.fColor;
- }
- break;
- case GrGLProgram::ProgramDesc::kUniform_ColorType:
- if (fProgramData->fColor != fCurrDrawState.fColor) {
- // OpenGL ES only supports the float varities of glVertexAttrib
- float c[] = GR_COLOR_TO_VEC4(fCurrDrawState.fColor);
- GrAssert(GrGLProgram::kUnusedUniform !=
- fProgramData->fUniLocations.fColorUni);
- GR_GL(Uniform4fv(fProgramData->fUniLocations.fColorUni, 1, c));
- fProgramData->fColor = fCurrDrawState.fColor;
- }
- break;
- case GrGLProgram::ProgramDesc::kNone_ColorType:
- GrAssert(0xffffffff == fCurrDrawState.fColor);
- break;
- default:
- GrCrash("Unknown color type.");
- }
- }
- if (fProgramData->fUniLocations.fColorFilterUni
- != GrGLProgram::kUnusedUniform
- && fProgramData->fColorFilterColor
- != fCurrDrawState.fColorFilterColor) {
- float c[] = GR_COLOR_TO_VEC4(fCurrDrawState.fColorFilterColor);
- GR_GL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c));
- fProgramData->fColorFilterColor = fCurrDrawState.fColorFilterColor;
- }
-}
-
-
-bool GrGpuGLShaders::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.
- fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
- // we assume all shader matrices may be wrong after viewport changes
- fProgramCache->invalidateViewMatrices();
- }
-
- buildProgram(type);
- fProgramData = fProgramCache->getProgramData(fCurrentProgram);
- if (NULL == fProgramData) {
- GrAssert(!"Failed to create program!");
- return false;
- }
-
- if (fHWProgramID != fProgramData->fProgramID) {
- GR_GL(UseProgram(fProgramData->fProgramID));
- fHWProgramID = fProgramData->fProgramID;
- }
- GrBlendCoeff srcCoeff = fCurrDrawState.fSrcBlend;
- GrBlendCoeff dstCoeff = fCurrDrawState.fDstBlend;
-
- fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff);
- this->flushBlend(type, srcCoeff, dstCoeff);
-
- this->flushColor();
-
- GrMatrix* currViewMatrix;
- if (GrGLProgram::kSetAsAttribute ==
- fProgramData->fUniLocations.fViewMatrixUni) {
- currViewMatrix = &fHWDrawState.fViewMatrix;
- } else {
- currViewMatrix = &fProgramData->fViewMatrix;
- }
-
- if (*currViewMatrix != fCurrDrawState.fViewMatrix) {
- flushViewMatrix();
- *currViewMatrix = fCurrDrawState.fViewMatrix;
- }
-
- for (int s = 0; s < kNumStages; ++s) {
- this->flushTextureMatrix(s);
-
- this->flushRadial2(s);
-
- this->flushTexelSize(s);
-
- this->flushTextureDomain(s);
- }
- this->flushEdgeAAData();
- resetDirtyFlags();
- return true;
-}
-
-void GrGpuGLShaders::postDraw() {
-}
-
-void GrGpuGLShaders::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) {
- int idx = GrGLProgram::PositionAttributeIdx();
- GR_GL(VertexAttribPointer(idx, 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]);
- int idx = GrGLProgram::TexCoordAttributeIdx(t);
- if (oldTexCoordOffsets[t] <= 0) {
- GR_GL(EnableVertexAttribArray(idx));
- GR_GL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
- newStride, texCoordOffset));
- } else if (posAndTexChange ||
- newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
- GR_GL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
- newStride, texCoordOffset));
- }
- } else if (oldTexCoordOffsets[t] > 0) {
- GR_GL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
- }
- }
-
- if (newColorOffset > 0) {
- GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
- int idx = GrGLProgram::ColorAttributeIdx();
- if (oldColorOffset <= 0) {
- GR_GL(EnableVertexAttribArray(idx));
- GR_GL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
- true, newStride, colorOffset));
- } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
- GR_GL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
- true, newStride, colorOffset));
- }
- } else if (oldColorOffset > 0) {
- GR_GL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
- }
-
- fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
- fHWGeometryState.fArrayPtrsDirty = false;
-}
-
-void GrGpuGLShaders::buildProgram(GrPrimitiveType type) {
- GrGLProgram::ProgramDesc& desc = fCurrentProgram.fProgramDesc;
-
- // Must initialize all fields or cache will have false negatives!
- desc.fVertexLayout = fGeometrySrc.fVertexLayout;
-
- desc.fEmitsPointSize = kPoints_PrimitiveType == type;
-
- 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);
-
- desc.fColorFilterXfermode = fCurrDrawState.fColorFilterXfermode;
-
-#if GR_AGGRESSIVE_SHADER_OPTS
- if (!requiresAttributeColors && (0xffffffff == fCurrDrawState.fColor)) {
- desc.fColorType = GrGLProgram::ProgramDesc::kNone_ColorType;
- } else
-#endif
-#if GR_GL_NO_CONSTANT_ATTRIBUTES
- if (!requiresAttributeColors) {
- desc.fColorType = GrGLProgram::ProgramDesc::kUniform_ColorType;
- } else
-#endif
- {
- if (requiresAttributeColors) {} // suppress unused var warning
- desc.fColorType = GrGLProgram::ProgramDesc::kAttribute_ColorType;
- }
-
- desc.fEdgeAANumEdges = fCurrDrawState.fEdgeAANumEdges;
-
- int lastEnabledStage = -1;
-
- for (int s = 0; s < kNumStages; ++s) {
- GrGLProgram::ProgramDesc::StageDesc& stage = desc.fStages[s];
-
- stage.fOptFlags = 0;
- stage.setEnabled(this->isStageEnabled(s));
-
- if (stage.isEnabled()) {
- lastEnabledStage = s;
- 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 |= GrGLProgram::ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit;
- } else if (!getSamplerMatrix(s).hasPerspective()) {
- stage.fOptFlags |= GrGLProgram::ProgramDesc::StageDesc::kNoPerspective_OptFlagBit;
- }
- switch (fCurrDrawState.fSamplerStates[s].getSampleMode()) {
- case GrSamplerState::kNormal_SampleMode:
- stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kIdentity_CoordMapping;
- break;
- case GrSamplerState::kRadial_SampleMode:
- stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadialGradient_CoordMapping;
- break;
- case GrSamplerState::kRadial2_SampleMode:
- stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping;
- break;
- case GrSamplerState::kSweep_SampleMode:
- stage.fCoordMapping = GrGLProgram::ProgramDesc::StageDesc::kSweepGradient_CoordMapping;
- break;
- default:
- GrCrash("Unexpected sample mode!");
- break;
- }
-
- switch (fCurrDrawState.fSamplerStates[s].getFilter()) {
- // these both can use a regular texture2D()
- case GrSamplerState::kNearest_Filter:
- case GrSamplerState::kBilinear_Filter:
- stage.fFetchMode = GrGLProgram::ProgramDesc::StageDesc::kSingle_FetchMode;
- break;
- // performs 4 texture2D()s
- case GrSamplerState::k4x4Downsample_Filter:
- stage.fFetchMode = GrGLProgram::ProgramDesc::StageDesc::k2x2_FetchMode;
- break;
- default:
- GrCrash("Unexpected filter!");
- break;
- }
-
- if (fCurrDrawState.fSamplerStates[s].hasTextureDomain()) {
- GrAssert(GrSamplerState::kClamp_WrapMode ==
- fCurrDrawState.fSamplerStates[s].getWrapX() &&
- GrSamplerState::kClamp_WrapMode ==
- fCurrDrawState.fSamplerStates[s].getWrapY());
- stage.fOptFlags |=
- GrGLProgram::ProgramDesc::StageDesc::
- kCustomTextureDomain_OptFlagBit;
- }
-
- if (GrPixelConfigIsAlphaOnly(texture->config())) {
- stage.fModulation = GrGLProgram::ProgramDesc::StageDesc::kAlpha_Modulation;
- } else {
- stage.fModulation = GrGLProgram::ProgramDesc::StageDesc::kColor_Modulation;
- }
- } else {
- stage.fOptFlags = 0;
- stage.fCoordMapping = (GrGLProgram::ProgramDesc::StageDesc::CoordMapping)0;
- stage.fModulation = (GrGLProgram::ProgramDesc::StageDesc::Modulation)0;
- }
- }
-
- desc.fDualSrcOutput = GrGLProgram::ProgramDesc::kNone_DualSrcOutput;
- // use canonical value when coverage/color distinction won't affect
- // generated code to prevent duplicate programs.
- desc.fFirstCoverageStage = kNumStages;
- if (fCurrDrawState.fFirstCoverageStage <= lastEnabledStage) {
- // color filter is applied between color/coverage computation
- if (SkXfermode::kDst_Mode != desc.fColorFilterXfermode) {
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
- }
-
- // We could consider cases where the final color is solid (0xff alpha)
- // and the dst coeff can correctly be set to a non-dualsrc gl value.
- // (e.g. solid draw, and dst coeff is kZero. It's correct to make
- // the dst coeff be kISA. Or solid draw with kSA can be tweaked to be
- // kOne).
- if (fDualSourceBlendingSupport) {
- if (kZero_BlendCoeff == fCurrDrawState.fDstBlend) {
- // write the coverage value to second color
- desc.fDualSrcOutput =
- GrGLProgram::ProgramDesc::kCoverage_DualSrcOutput;
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
- } else if (kSA_BlendCoeff == fCurrDrawState.fDstBlend) {
- // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
- // cover
- desc.fDualSrcOutput =
- GrGLProgram::ProgramDesc::kCoverageISA_DualSrcOutput;
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
- } else if (kSC_BlendCoeff == fCurrDrawState.fDstBlend) {
- // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
- // cover
- desc.fDualSrcOutput =
- GrGLProgram::ProgramDesc::kCoverageISC_DualSrcOutput;
- desc.fFirstCoverageStage = fCurrDrawState.fFirstCoverageStage;
- }
- }
- }
-}