From 2401ae8fd3c1f6282f571b5a7e0a499e9f4c09ab Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Tue, 17 Jan 2012 21:03:05 +0000 Subject: [PATCH] Attempt to reland 3054 git-svn-id: http://skia.googlecode.com/svn/trunk@3056 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/GrDrawState.h | 35 +++++++++- src/gpu/GrDrawTarget.cpp | 10 ++- src/gpu/GrDrawTarget.h | 3 +- src/gpu/GrGLProgram.cpp | 164 ++++++++++++++++++++++++++++++--------------- src/gpu/GrGLProgram.h | 4 ++ src/gpu/GrGpuGLShaders.cpp | 85 ++++++++++++++++++++--- src/gpu/GrGpuGLShaders.h | 5 +- 7 files changed, 234 insertions(+), 72 deletions(-) diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index b8417ba..c736f1e 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -70,6 +70,7 @@ struct GrDrawState { // memset exceptions fColor = 0xffffffff; + fCoverage = 0xffffffff; fFirstCoverageStage = kNumStages; fColorFilterMode = SkXfermode::kDst_Mode; fSrcBlend = kOne_BlendCoeff; @@ -78,9 +79,9 @@ struct GrDrawState { // ensure values that will be memcmp'ed in == but not memset in reset() // are tightly packed - GrAssert(kMemsetSize + sizeof(fColor) + sizeof(fFirstCoverageStage) + - sizeof(fColorFilterMode) + sizeof(fSrcBlend) + - sizeof(fDstBlend) + sizeof(GrMatrix) == + GrAssert(kMemsetSize + sizeof(fColor) + sizeof(fCoverage) + + sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) + + sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(GrMatrix) == reinterpret_cast(&fEdgeAANumEdges) - reinterpret_cast(this)); @@ -125,6 +126,33 @@ struct GrDrawState { /// @} /////////////////////////////////////////////////////////////////////////// + /// @name Coverage + //// + + /** + * Sets a constant fractional coverage to be applied to the draw. The + * initial value (after construction or reset()) is 0xff. The constant + * coverage is ignored when per-vertex coverage is provided. + */ + void setCoverage(uint8_t coverage) { + fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage); + } + + /** + * Version of above that specifies 4 channel per-vertex color. The value + * should be premultiplied. + */ + void setCoverage4(GrColor coverage) { + fCoverage = coverage; + } + + GrColor getCoverage() const { + return fCoverage; + } + + /// @} + + /////////////////////////////////////////////////////////////////////////// /// @name Textures //// @@ -753,6 +781,7 @@ private: // @{ Initialized to values other than zero GrColor fColor; + GrColor fCoverage; int fFirstCoverageStage; SkXfermode::Mode fColorFilterMode; GrBlendCoeff fSrcBlend; diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index be6bd0a..fa266d1 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -885,8 +885,10 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, // When coeffs are (0,1) there is no reason to draw at all, unless // stenciling is enabled. Having color writes disabled is effectively - // (0,1). - if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne)) { + // (0,1). The same applies when coverage is known to be 0. + if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne) || + (!(layout & kCoverage_VertexLayoutBit) && + 0 == drawState.getCoverage())) { if (drawState.getStencil().doesWrite()) { return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; @@ -895,8 +897,10 @@ GrDrawTarget::getBlendOpts(bool forceCoverage, } } - // check for coverage due to edge aa or coverage texture stage + // check for coverage due to constant coverage, per-vertex coverage, + // edge aa or coverage texture stage bool hasCoverage = forceCoverage || + 0xffffffff != drawState.getCoverage() || drawState.getNumAAEdges() > 0 || (layout & kCoverage_VertexLayoutBit) || (layout & kEdge_VertexLayoutBit); diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 2635ddd..5fc420d 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -239,8 +239,7 @@ public: enum VertexLayoutBits { /* vertices have colors (GrColor) */ kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0), - /* vertices have coverage (GrColor where all channels should have the - * same value) + /* vertices have coverage (GrColor) */ kCoverage_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1), /* Use text vertices. (Pos and tex coords may be a different type for diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp index d159f5a..ce5a284 100644 --- a/src/gpu/GrGLProgram.cpp +++ b/src/gpu/GrGLProgram.cpp @@ -92,6 +92,7 @@ typedef GrGLProgram::ProgramDesc::StageDesc StageDesc; #define COV_ATTR_NAME "aCoverage" #define EDGE_ATTR_NAME "aEdge" #define COL_UNI_NAME "uColor" +#define COV_UNI_NAME "uCoverage" #define EDGES_UNI_NAME "uEdges" #define COL_FILTER_UNI_NAME "uColorFilter" #define COL_MATRIX_UNI_NAME "uColorMatrix" @@ -611,21 +612,37 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput, } } -void genPerVertexCoverage(ShaderCodeSegments* segments, - GrStringBuilder* inCoverage) { - segments->fVSAttrs.push_back().set(GrGLShaderVar::kFloat_Type, +void genAttributeCoverage(ShaderCodeSegments* segments, + GrStringBuilder* inOutCoverage) { + segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, GrGLShaderVar::kAttribute_TypeModifier, COV_ATTR_NAME); const char *vsName, *fsName; - append_varying(GrGLShaderVar::kFloat_Type, "Coverage", + append_varying(GrGLShaderVar::kVec4f_Type, "Coverage", segments, &vsName, &fsName); segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName); - if (inCoverage->size()) { - segments->fFSCode.appendf("\tfloat edgeAndAttrCov = %s * %s;\n", - fsName, inCoverage->c_str()); - *inCoverage = "edgeAndAttrCov"; + if (inOutCoverage->size()) { + segments->fFSCode.appendf("\tvec4 attrCoverage = %s * %s;\n", + fsName, inOutCoverage->c_str()); + *inOutCoverage = "attrCoverage"; } else { - *inCoverage = fsName; + *inOutCoverage = fsName; + } +} + +void genUniformCoverage(ShaderCodeSegments* segments, + GrGLProgram::CachedData* programData, + GrStringBuilder* inOutCoverage) { + segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, + GrGLShaderVar::kUniform_TypeModifier, + COV_UNI_NAME); + programData->fUniLocations.fCoverageUni = kUseUniform; + if (inOutCoverage->size()) { + segments->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n", + COV_UNI_NAME, inOutCoverage->c_str()); + *inOutCoverage = "uniCoverage"; + } else { + *inOutCoverage = COV_UNI_NAME; } } @@ -661,7 +678,6 @@ void GrGLProgram::genGeometryShader(const GrGLInterface* gl, } const char* GrGLProgram::adjustInColor(const GrStringBuilder& inColor) const { - const char* color; if (inColor.size()) { return inColor.c_str(); } else { @@ -673,6 +689,7 @@ const char* GrGLProgram::adjustInColor(const GrStringBuilder& inColor) const { } } + bool GrGLProgram::genProgram(const GrGLInterface* gl, GrGLSLGeneration glslGeneration, GrGLProgram::CachedData* programData) const { @@ -687,6 +704,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, #endif SkXfermode::Coeff colorCoeff, uniformCoeff; + bool applyColorMatrix = SkToBool(fProgramDesc.fColorMatrixEnabled); // The rest of transfer mode color filters have not been implemented if (fProgramDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { GR_DEBUGCODE(bool success =) @@ -699,6 +717,15 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, uniformCoeff = SkXfermode::kZero_Coeff; } + // no need to do the color filter / matrix at all if coverage is 0. The + // output color is scaled by the coverage. All the dual source outputs are + // scaled by the coverage as well. + if (ProgramDesc::kTransBlack_ColorInput == fProgramDesc.fCoverageInput) { + colorCoeff = SkXfermode::kZero_Coeff; + uniformCoeff = SkXfermode::kZero_Coeff; + applyColorMatrix = false; + } + // If we know the final color is going to be all zeros then we can // simplify the color filter coeffecients. needComputedColor will then // come out false below. @@ -832,7 +859,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, bool wroteFragColorZero = false; if (SkXfermode::kZero_Coeff == uniformCoeff && SkXfermode::kZero_Coeff == colorCoeff && - !fProgramDesc.fColorMatrixEnabled) { + !applyColorMatrix) { segments.fFSCode.appendf("\t%s = %s;\n", fsColorOutput, all_zeros_vec(4)); @@ -844,7 +871,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, colorCoeff, color); inColor = "filteredColor"; } - if (fProgramDesc.fColorMatrixEnabled) { + if (applyColorMatrix) { segments.fFSUnis.push_back().set(GrGLShaderVar::kMat44f_Type, GrGLShaderVar::kUniform_TypeModifier, COL_MATRIX_UNI_NAME); @@ -863,58 +890,78 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, // compute the partial coverage (coverage stages and edge aa) GrStringBuilder inCoverage; - + bool coverageIsZero = ProgramDesc::kTransBlack_ColorInput == + fProgramDesc.fCoverageInput; // we don't need to compute coverage at all if we know the final shader // output will be zero and we don't have a dual src blend output. if (!wroteFragColorZero || ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) { - // get edge AA coverage and use it as inCoverage to first coverage stage - this->genEdgeCoverage(gl, layout, programData, &inCoverage, &segments); - - // include explicit per-vertex coverage if we have it - if (GrDrawTarget::kCoverage_VertexLayoutBit & layout) { - genPerVertexCoverage(&segments, &inCoverage); - } + if (!coverageIsZero) { + this->genEdgeCoverage(gl, + layout, + programData, + &inCoverage, + &segments); + + switch (fProgramDesc.fCoverageInput) { + case ProgramDesc::kSolidWhite_ColorInput: + // empty string implies solid white + break; + case ProgramDesc::kAttribute_ColorInput: + genAttributeCoverage(&segments, &inCoverage); + break; + case ProgramDesc::kUniform_ColorInput: + genUniformCoverage(&segments, programData, &inCoverage); + break; + default: + GrCrash("Unexpected input coverage."); + } - GrStringBuilder outCoverage; - const int& startStage = fProgramDesc.fFirstCoverageStage; - for (int s = startStage; s < GrDrawState::kNumStages; ++s) { - if (fProgramDesc.fStages[s].isEnabled()) { - // create var to hold stage output - outCoverage = "coverage"; - outCoverage.appendS32(s); - segments.fFSCode.appendf("\tvec4 %s;\n", outCoverage.c_str()); + GrStringBuilder outCoverage; + const int& startStage = fProgramDesc.fFirstCoverageStage; + for (int s = startStage; s < GrDrawState::kNumStages; ++s) { + if (fProgramDesc.fStages[s].isEnabled()) { + // create var to hold stage output + outCoverage = "coverage"; + outCoverage.appendS32(s); + segments.fFSCode.appendf("\tvec4 %s;\n", + outCoverage.c_str()); + + const char* inCoords; + // figure out what our input coords are + if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) & + layout) { + inCoords = POS_ATTR_NAME; + } else { + int tcIdx = + GrDrawTarget::VertexTexCoordsForStage(s, layout); + // we better have input tex coordinates if stage is + // enabled. + GrAssert(tcIdx >= 0); + GrAssert(texCoordAttrs[tcIdx].size()); + inCoords = texCoordAttrs[tcIdx].c_str(); + } - const char* inCoords; - // figure out what our input coords are - if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) & layout) { - inCoords = POS_ATTR_NAME; - } else { - int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout); - // we better have input tex coordinates if stage is enabled. - GrAssert(tcIdx >= 0); - GrAssert(texCoordAttrs[tcIdx].size()); - inCoords = texCoordAttrs[tcIdx].c_str(); + genStageCode(gl, s, + fProgramDesc.fStages[s], + inCoverage.size() ? inCoverage.c_str() : NULL, + outCoverage.c_str(), + inCoords, + &segments, + &programData->fUniLocations.fStages[s]); + inCoverage = outCoverage; } - - genStageCode(gl, s, - fProgramDesc.fStages[s], - inCoverage.size() ? inCoverage.c_str() : NULL, - outCoverage.c_str(), - inCoords, - &segments, - &programData->fUniLocations.fStages[s]); - inCoverage = outCoverage; } } if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) { segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type, GrGLShaderVar::kOut_TypeModifier, dual_source_output_name()); - bool outputIsZero = false; + bool outputIsZero = coverageIsZero; GrStringBuilder coeff; - if (ProgramDesc::kCoverage_DualSrcOutput != + if (!outputIsZero && + ProgramDesc::kCoverage_DualSrcOutput != fProgramDesc.fDualSrcOutput && !wroteFragColorZero) { if (!inColor.size()) { outputIsZero = true; @@ -945,10 +992,16 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, // combine color and coverage as frag color if (!wroteFragColorZero) { - modulate_helper(fsColorOutput, - inColor.c_str(), - inCoverage.c_str(), - &segments.fFSCode); + if (coverageIsZero) { + segments.fFSCode.appendf("\t%s = %s;\n", + fsColorOutput, + all_zeros_vec(4)); + } else { + modulate_helper(fsColorOutput, + inColor.c_str(), + inCoverage.c_str(), + &segments.fFSCode); + } if (ProgramDesc::kNo_OutputPM == fProgramDesc.fOutputPM) { segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(%s.rgb / %s.a, %s.a);\n", fsColorOutput, @@ -1288,6 +1341,11 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLInterface* gl, GR_GL_CALL_RET(gl, programData->fUniLocations.fColorMatrixVecUni, GetUniformLocation(progID, COL_MATRIX_VEC_UNI_NAME)); } + if (kUseUniform == programData->fUniLocations.fCoverageUni) { + GR_GL_CALL_RET(gl, programData->fUniLocations.fCoverageUni, + GetUniformLocation(progID, COV_UNI_NAME)); + GrAssert(kUnusedUniform != programData->fUniLocations.fCoverageUni); + } if (kUseUniform == programData->fUniLocations.fEdgesUni) { GR_GL_CALL_RET(gl, programData->fUniLocations.fEdgesUni, diff --git a/src/gpu/GrGLProgram.h b/src/gpu/GrGLProgram.h index b4ad4af..4d80f50 100644 --- a/src/gpu/GrGLProgram.h +++ b/src/gpu/GrGLProgram.h @@ -211,6 +211,7 @@ public: #endif uint8_t fColorInput; // casts to enum ColorInput + uint8_t fCoverageInput; // casts to enum CoverageInput uint8_t fOutputPM; // cases to enum OutputPM uint8_t fDualSrcOutput; // casts to enum DualSrcOutput int8_t fFirstCoverageStage; @@ -261,6 +262,7 @@ public: struct UniLocations { GrGLint fViewMatrixUni; GrGLint fColorUni; + GrGLint fCoverageUni; GrGLint fEdgesUni; GrGLint fColorFilterUni; GrGLint fColorMatrixUni; @@ -269,6 +271,7 @@ public: void reset() { fViewMatrixUni = kUnusedUniform; fColorUni = kUnusedUniform; + fCoverageUni = kUnusedUniform; fEdgesUni = kUnusedUniform; fColorFilterUni = kUnusedUniform; fColorMatrixUni = kUnusedUniform; @@ -306,6 +309,7 @@ public: // these reflect the current values of uniforms // (GL uniform values travel with program) GrColor fColor; + GrColor fCoverage; GrColor fColorFilterColor; GrMatrix fTextureMatrices[GrDrawState::kNumStages]; // width and height used for normalized texel size diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp index 251fc41..b8e0999 100644 --- a/src/gpu/GrGpuGLShaders.cpp +++ b/src/gpu/GrGpuGLShaders.cpp @@ -198,6 +198,7 @@ bool GrGpuGLShaders::programUnitTest() { pdesc.fVertexLayout = 0; pdesc.fEmitsPointSize = random.nextF() > .5f; pdesc.fColorInput = random_int(&random, ProgramDesc::kColorInputCnt); + pdesc.fCoverageInput = random_int(&random, ProgramDesc::kColorInputCnt); pdesc.fColorFilterXfermode = random_int(&random, SkXfermode::kCoeffModesCnt); @@ -653,7 +654,8 @@ void GrGpuGLShaders::flushColor(GrColor color) { switch (desc.fColorInput) { case ProgramDesc::kAttribute_ColorInput: if (fHWDrawState.getColor() != color) { - // OpenGL ES only supports the float varities of glVertexAttrib + // OpenGL ES only supports the float varieties of + // glVertexAttrib float c[] = GR_COLOR_TO_VEC4(color); GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), c)); @@ -662,7 +664,8 @@ void GrGpuGLShaders::flushColor(GrColor color) { break; case ProgramDesc::kUniform_ColorInput: if (fProgramData->fColor != color) { - // OpenGL ES only supports the float varities of glVertexAttrib + // OpenGL ES doesn't support unsigned byte varieties of + // glUniform float c[] = GR_COLOR_TO_VEC4(color); GrAssert(GrGLProgram::kUnusedUniform != fProgramData->fUniLocations.fColorUni); @@ -688,6 +691,47 @@ void GrGpuGLShaders::flushColor(GrColor color) { } } +void GrGpuGLShaders::flushCoverage(GrColor coverage) { + const ProgramDesc& desc = fCurrentProgram.getDesc(); + const GrDrawState& drawState = this->getDrawState(); + + + if (this->getGeomSrc().fVertexLayout & kCoverage_VertexLayoutBit) { + // coverage will be specified per-vertex as an attribute + // invalidate the const vertex attrib coverage + fHWDrawState.setCoverage4(GrColor_ILLEGAL); + } else { + switch (desc.fCoverageInput) { + case ProgramDesc::kAttribute_ColorInput: + if (fHWDrawState.getCoverage() != coverage) { + // OpenGL ES only supports the float varieties of + // glVertexAttrib + float c[] = GR_COLOR_TO_VEC4(coverage); + GL_CALL(VertexAttrib4fv(GrGLProgram::CoverageAttributeIdx(), + c)); + fHWDrawState.setCoverage(coverage); + } + break; + case ProgramDesc::kUniform_ColorInput: + if (fProgramData->fCoverage != coverage) { + // OpenGL ES doesn't support unsigned byte varieties of + // glUniform + float c[] = GR_COLOR_TO_VEC4(coverage); + GrAssert(GrGLProgram::kUnusedUniform != + fProgramData->fUniLocations.fCoverageUni); + GL_CALL(Uniform4fv(fProgramData->fUniLocations.fCoverageUni, + 1, c)); + fProgramData->fCoverage = coverage; + } + break; + case ProgramDesc::kSolidWhite_ColorInput: + case ProgramDesc::kTransBlack_ColorInput: + break; + default: + GrCrash("Unknown coverage type."); + } + } +} bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { if (!flushGLStateCommon(type)) { @@ -726,14 +770,19 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { this->flushBlend(type, srcCoeff, dstCoeff); GrColor color; + GrColor coverage; if (blendOpts & kEmitTransBlack_BlendOptFlag) { color = 0; + coverage = 0; } else if (blendOpts & kEmitCoverage_BlendOptFlag) { color = 0xffffffff; + coverage = drawState.getCoverage(); } else { color = drawState.getColor(); + coverage = drawState.getCoverage(); } this->flushColor(color); + this->flushCoverage(coverage); this->flushViewMatrix(); @@ -862,15 +911,14 @@ void GrGpuGLShaders::setupGeometry(int* startVertex, } if (newCoverageOffset > 0) { - // bind a single channel, they should all have the same value. GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset); int idx = GrGLProgram::CoverageAttributeIdx(); if (oldCoverageOffset <= 0) { GL_CALL(EnableVertexAttribArray(idx)); - GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE, + GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, coverageOffset)); } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) { - GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE, + GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, coverageOffset)); } } else if (oldCoverageOffset > 0) { @@ -922,10 +970,14 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, bool requiresAttributeColors = !skipColor && SkToBool(desc.fVertexLayout & kColor_VertexLayoutBit); - // fColorInput 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); + bool requiresAttributeCoverage = + !skipCoverage && SkToBool(desc.fVertexLayout & + kCoverage_VertexLayoutBit); + + // fColorInput/fCoverageInput records how colors are specified for the. + // program. So we strip the bits from the layout to avoid false negatives + // when searching for an existing program in the cache. + desc.fVertexLayout &= ~(kColor_VertexLayoutBit | kCoverage_VertexLayoutBit); desc.fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : @@ -953,6 +1005,19 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, } else { desc.fColorInput = ProgramDesc::kAttribute_ColorInput; } + + bool covIsSolidWhite = !requiresAttributeCoverage && + 0xffffffff == drawState.getCoverage(); + + if (skipCoverage) { + desc.fCoverageInput = ProgramDesc::kTransBlack_ColorInput; + } else if (covIsSolidWhite) { + desc.fCoverageInput = ProgramDesc::kSolidWhite_ColorInput; + } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) { + desc.fCoverageInput = ProgramDesc::kUniform_ColorInput; + } else { + desc.fCoverageInput = ProgramDesc::kAttribute_ColorInput; + } desc.fEdgeAANumEdges = skipCoverage ? 0 : drawState.getNumAAEdges(); desc.fEdgeAAConcave = desc.fEdgeAANumEdges > 0 && @@ -1101,7 +1166,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type, if (!hasCoverage) { hasCoverage = desc.fEdgeAANumEdges || - (desc.fVertexLayout & GrDrawTarget::kCoverage_VertexLayoutBit) || + requiresAttributeCoverage || (desc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit); } diff --git a/src/gpu/GrGpuGLShaders.h b/src/gpu/GrGpuGLShaders.h index 4b972b5..d875fe9 100644 --- a/src/gpu/GrGpuGLShaders.h +++ b/src/gpu/GrGpuGLShaders.h @@ -57,9 +57,12 @@ private: // sets the texture domain uniform for currently bound program void flushTextureDomain(int stage); - // sets the color specified by GrDrawTarget::setColor() + // sets the color specified by GrDrawState::setColor() void flushColor(GrColor color); + // sets the color specified by GrDrawState::setCoverage() + void flushCoverage(GrColor color); + // sets the MVP matrix uniform for currently bound program void flushViewMatrix(); -- 2.7.4