diff options
author | egdaniel <egdaniel@google.com> | 2014-09-16 07:18:54 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-16 07:18:54 -0700 |
commit | 8a4c1030ff4b8336b5ac5b0712691e2f65383440 (patch) | |
tree | 99a0918368070a16c004719881503de8c927f878 /src/gpu | |
parent | 08da4f22d790cfc51bbeb10b4b84dab49cf0eaec (diff) |
Revert of Attach GrOptDrawState into shader building pipeline (patchset #11 id:220001 of https://codereview.chromium.org/504203004/)
Reason for revert:
Failing some msaa gm's
Original issue's description:
> Attach GrOptDrawState into shader building pipeline
>
> The OptDrawState is now used for creating the actual gl shader. Current
> optimizations dones in GrOptDrawState include:
> All blend optimizations
> Constant color/coverage stage optimizations
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/ee6206572b42fec11f83ad0c1e6d435903640518
R=bsalomon@google.com, joshualitt@google.com
TBR=bsalomon@google.com, joshualitt@google.com
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Author: egdaniel@google.com
Review URL: https://codereview.chromium.org/560443004
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrDrawState.cpp | 30 | ||||
-rw-r--r-- | src/gpu/GrDrawState.h | 17 | ||||
-rw-r--r-- | src/gpu/GrOptDrawState.cpp | 46 | ||||
-rw-r--r-- | src/gpu/GrOptDrawState.h | 30 | ||||
-rw-r--r-- | src/gpu/GrRODrawState.cpp | 30 | ||||
-rw-r--r-- | src/gpu/GrRODrawState.h | 113 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 46 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 205 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.h | 12 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 46 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp | 11 |
13 files changed, 323 insertions, 274 deletions
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index f639744665..642ec2669f 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -15,17 +15,9 @@ GrOptDrawState* GrDrawState::createOptState() const { if (NULL == fCachedOptState) { - GrBlendCoeff srcCoeff; - GrBlendCoeff dstCoeff; - BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff); - fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoeff, dstCoeff)); + fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this)); } else { -#ifdef SK_DEBUG - GrBlendCoeff srcCoeff; - GrBlendCoeff dstCoeff; - BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff); - SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff) == *fCachedOptState); -#endif + SkASSERT(GrOptDrawState(*this) == *fCachedOptState); } fCachedOptState->ref(); return fCachedOptState; @@ -114,6 +106,9 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) { } fColorStages = that.fColorStages; fCoverageStages = that.fCoverageStages; + fOptSrcBlend = that.fOptSrcBlend; + fOptDstBlend = that.fOptDstBlend; + fBlendOptFlags = that.fBlendOptFlags; fHints = that.fHints; @@ -304,7 +299,7 @@ bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color GrBlendCoeff srcCoeff; GrBlendCoeff dstCoeff; - BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff); + GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff); return GrRODrawState::kNone_BlendOpt != flag || (this->willEffectReadDstColor() && kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); @@ -460,16 +455,3 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co } } -//////////////////////////////////////////////////////////////////////////////// - -void GrDrawState::invalidateOptState() const { - SkSafeSetNull(fCachedOptState); -} - -//////////////////////////////////////////////////////////////////////////////// - -GrDrawState::~GrDrawState() { - SkSafeUnref(fCachedOptState); - SkASSERT(0 == fBlockEffectRemovalCnt); -} - diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 4869658b4f..6a1e38056b 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -9,12 +9,11 @@ #define GrDrawState_DEFINED #include "GrBlend.h" +#include "GrOptDrawState.h" #include "GrProgramResource.h" #include "GrRODrawState.h" #include "effects/GrSimpleTextureEffect.h" -class GrOptDrawState; - /** * Modifiable subclass derived from GrRODrawState. The majority of the data that represents a draw * state is stored in the parent class. GrDrawState contains methods for setting, adding to, etc. @@ -48,7 +47,10 @@ public: **/ GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix); - virtual ~GrDrawState(); + virtual ~GrDrawState() { + SkSafeUnref(fCachedOptState); + SkASSERT(0 == fBlockEffectRemovalCnt); + } /** * Resets to the default state. GrEffects will be removed from all stages. @@ -550,10 +552,17 @@ public: GrOptDrawState* createOptState() const; private: - void invalidateOptState() const; + void invalidateOptState() const { + SkSafeSetNull(fCachedOptState); + fBlendOptFlags = kInvalid_BlendOptFlag; + } void onReset(const SkMatrix* initialViewMatrix); + void invalidateBlendOptFlags() { + fBlendOptFlags = kInvalid_BlendOptFlag; + } + // Some of the auto restore objects assume that no effects are removed during their lifetime. // This is used to assert that this condition holds. SkDEBUGCODE(int fBlockEffectRemovalCnt;) diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp index 5f352966b8..83546ba3b7 100644 --- a/src/gpu/GrOptDrawState.cpp +++ b/src/gpu/GrOptDrawState.cpp @@ -9,10 +9,7 @@ #include "GrDrawState.h" -GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, - BlendOptFlags blendOptFlags, - GrBlendCoeff optSrcCoeff, - GrBlendCoeff optDstCoeff) : INHERITED(drawState) { +GrOptDrawState::GrOptDrawState(const GrDrawState& drawState) : INHERITED(drawState) { fColor = drawState.getColor(); fCoverage = drawState.getCoverage(); fViewMatrix = drawState.getViewMatrix(); @@ -23,15 +20,13 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, fVAStride = drawState.getVertexStride(); fStencilSettings = drawState.getStencil(); fDrawFace = drawState.getDrawFace(); - fBlendOptFlags = blendOptFlags; - fSrcBlend = optSrcCoeff; - fDstBlend = optDstCoeff; + + fBlendOptFlags = drawState.getBlendOpts(false, &fSrcBlend, &fDstBlend); memcpy(fFixedFunctionVertexAttribIndices, drawState.getFixedFunctionVertexAttribIndices(), sizeof(fFixedFunctionVertexAttribIndices)); - fInputColorIsUsed = true; fInputCoverageIsUsed = true; @@ -43,40 +38,8 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, this->copyEffectiveColorStages(drawState); this->copyEffectiveCoverageStages(drawState); - this->adjustFromBlendOpts(); }; -void GrOptDrawState::adjustFromBlendOpts() { - - switch (fBlendOptFlags) { - case kNone_BlendOpt: - case kSkipDraw_BlendOptFlag: - break; - case kCoverageAsAlpha_BlendOptFlag: - fFlagBits |= kCoverageDrawing_StateBit; - break; - case kEmitCoverage_BlendOptFlag: - fColor = 0xffffffff; - fInputColorIsUsed = true; - fColorStages.reset(); - this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding); - break; - case kEmitTransBlack_BlendOptFlag: - fColor = 0; - fCoverage = 0xff; - fInputColorIsUsed = true; - fInputCoverageIsUsed = true; - fColorStages.reset(); - fCoverageStages.reset(); - this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding | - 0x1 << kCoverage_GrVertexAttribBinding); - break; - default: - SkFAIL("Unknown BlendOptFlag"); - - } -} - void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) { int numToRemove = 0; uint8_t maskCheck = 0x1; @@ -87,7 +50,6 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) { } maskCheck <<= 1; } - fOptVA.reset(fVACount - numToRemove); GrVertexAttrib* dst = fOptVA.get(); @@ -102,9 +64,9 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) { fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1; continue; } - fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx; } memcpy(dst, src, sizeof(GrVertexAttrib)); + fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx; ++newIdx; ++dst; } diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h index 457f035423..a4edc01c8a 100644 --- a/src/gpu/GrOptDrawState.h +++ b/src/gpu/GrOptDrawState.h @@ -8,9 +8,10 @@ #ifndef GrOptDrawState_DEFINED #define GrOptDrawState_DEFINED -#include "GrDrawState.h" #include "GrRODrawState.h" +class GrDrawState; + /** * Subclass of GrRODrawState that holds an optimized version of a GrDrawState. Like it's parent * it is meant to be an immutable class, and simply adds a few helpful data members not in the @@ -18,19 +19,15 @@ */ class GrOptDrawState : public GrRODrawState { public: - bool operator== (const GrOptDrawState& that) const; - - bool inputColorIsUsed() const { return fInputColorIsUsed; } - bool inputCoverageIsUsed() const { return fInputCoverageIsUsed; } - -private: /** * Constructs and optimized drawState out of a GrRODrawState. */ - GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags, - GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff); + explicit GrOptDrawState(const GrDrawState& drawState); - /** + bool operator== (const GrOptDrawState& that) const; + +private: + /* * Loops through all the color stage effects to check if the stage will ignore color input or * always output a constant color. In the ignore color input case we can ignore all previous * stages. In the constant color case, we can ignore all previous stages and @@ -40,7 +37,7 @@ private: */ void copyEffectiveColorStages(const GrDrawState& ds); - /** + /* * Loops through all the coverage stage effects to check if the stage will ignore color input. * If a coverage stage will ignore input, then we can ignore all coverage stages before it. We * loop to determine the first effective coverage stage, and then copy all of our effective @@ -48,18 +45,14 @@ private: */ void copyEffectiveCoverageStages(const GrDrawState& ds); - /** + /* * This function takes in a flag and removes the corresponding fixed function vertex attributes. * The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is * set, then vertex attributes with binding (GrVertexAttribute)i will be removed. */ void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags); - /** - * Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the - * BlendOptFlags. - */ - void adjustFromBlendOpts(); + void removeColorVertexAttrib(); // These flags are needed to protect the code from creating an unused uniform color/coverage // which will cause shader compiler errors. @@ -68,9 +61,6 @@ private: SkAutoSTArray<4, GrVertexAttrib> fOptVA; - BlendOptFlags fBlendOptFlags; - - friend GrOptDrawState* GrDrawState::createOptState() const; typedef GrRODrawState INHERITED; }; diff --git a/src/gpu/GrRODrawState.cpp b/src/gpu/GrRODrawState.cpp index e522008cae..f7e486f925 100644 --- a/src/gpu/GrRODrawState.cpp +++ b/src/gpu/GrRODrawState.cpp @@ -184,6 +184,26 @@ GrRODrawState::BlendOptFlags GrRODrawState::getBlendOpts(bool forceCoverage, dstCoeff = &bogusDstCoeff; } + if (forceCoverage) { + return this->calcBlendOpts(true, srcCoeff, dstCoeff); + } + + if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) { + *srcCoeff = fOptSrcBlend; + *dstCoeff = fOptDstBlend; + return fBlendOptFlags; + } + + fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff); + fOptSrcBlend = *srcCoeff; + fOptDstBlend = *dstCoeff; + + return fBlendOptFlags; +} + +GrRODrawState::BlendOptFlags GrRODrawState::calcBlendOpts(bool forceCoverage, + GrBlendCoeff* srcCoeff, + GrBlendCoeff* dstCoeff) const { *srcCoeff = this->getSrcBlendCoeff(); *dstCoeff = this->getDstBlendCoeff(); @@ -352,3 +372,13 @@ bool GrRODrawState::srcAlphaWillBeOne() const { return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color); } +//////////////////////////////////////////////////////////////////////////////// + +bool GrRODrawState::canIgnoreColorAttribute() const { + if (fBlendOptFlags & kInvalid_BlendOptFlag) { + this->getBlendOpts(); + } + return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFlag | + GrRODrawState::kEmitCoverage_BlendOptFlag)); +} + diff --git a/src/gpu/GrRODrawState.h b/src/gpu/GrRODrawState.h index eea6f9b98a..d748e7d83a 100644 --- a/src/gpu/GrRODrawState.h +++ b/src/gpu/GrRODrawState.h @@ -167,12 +167,68 @@ public: GrColor getBlendConstant() const { return fBlendConstant; } /** + * We don't use supplied vertex color attributes if our blend mode is EmitCoverage or + * EmitTransBlack + */ + bool canIgnoreColorAttribute() const; + + /** * Determines whether multiplying the computed per-pixel color by the pixel's fractional * coverage before the blend will give the correct final destination color. In general it * will not as coverage is applied after blending. */ bool canTweakAlphaForCoverage() const; + /** + * Optimizations for blending / coverage to that can be applied based on the current state. + */ + enum BlendOptFlags { + /** + * No optimization + */ + kNone_BlendOpt = 0, + /** + * Don't draw at all + */ + kSkipDraw_BlendOptFlag = 0x1, + /** + * The coverage value does not have to be computed separately from alpha, the output + * color can be the modulation of the two. + */ + kCoverageAsAlpha_BlendOptFlag = 0x2, + /** + * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are + * "don't cares". + */ + kEmitCoverage_BlendOptFlag = 0x4, + /** + * Emit transparent black instead of the src color, no need to compute coverage. + */ + kEmitTransBlack_BlendOptFlag = 0x8, + /** + * Flag used to invalidate the cached BlendOptFlags, OptSrcCoeff, and OptDstCoeff cached by + * the get BlendOpts function. + */ + kInvalid_BlendOptFlag = 1 << 31, + }; + GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); + + /** + * Determines what optimizations can be applied based on the blend. The coefficients may have + * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional + * params that receive the tweaked coefficients. Normally the function looks at the current + * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively + * determine the blend optimizations that would be used if there was partial pixel coverage. + * + * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for + * playback) must call this function and respect the flags that replace the output color. + * + * If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will + * simply returned the cached flags and coefficients. Otherwise it will calculate the values. + */ + BlendOptFlags getBlendOpts(bool forceCoverage = false, + GrBlendCoeff* srcCoeff = NULL, + GrBlendCoeff* dstCoeff = NULL) const; /// @} /////////////////////////////////////////////////////////////////////////// @@ -351,52 +407,6 @@ protected: bool isEqual(const GrRODrawState& that) const; - /** - * Optimizations for blending / coverage to that can be applied based on the current state. - */ - enum BlendOptFlags { - /** - * No optimization - */ - kNone_BlendOpt = 0, - /** - * Don't draw at all - */ - kSkipDraw_BlendOptFlag = 0x1, - /** - * The coverage value does not have to be computed separately from alpha, the the output - * color can be the modulation of the two. - */ - kCoverageAsAlpha_BlendOptFlag = 0x2, - /** - * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are - * "don't cares". - */ - kEmitCoverage_BlendOptFlag = 0x4, - /** - * Emit transparent black instead of the src color, no need to compute coverage. - */ - kEmitTransBlack_BlendOptFlag = 0x8, - }; - GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); - - /** - * Determines what optimizations can be applied based on the blend. The coefficients may have - * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional - * params that receive the tweaked coefficients. Normally the function looks at the current - * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively - * determine the blend optimizations that would be used if there was partial pixel coverage. - * - * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for - * playback) must call this function and respect the flags that replace the output color. - * - * If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will - * simply returned the cached flags and coefficients. Otherwise it will calculate the values. - */ - BlendOptFlags getBlendOpts(bool forceCoverage = false, - GrBlendCoeff* srcCoeff = NULL, - GrBlendCoeff* dstCoeff = NULL) const; - // These fields are roughly sorted by decreasing likelihood of being different in op== GrProgramResource fRenderTarget; GrColor fColor; @@ -419,6 +429,10 @@ protected: uint32_t fHints; + mutable GrBlendCoeff fOptSrcBlend; + mutable GrBlendCoeff fOptDstBlend; + mutable BlendOptFlags fBlendOptFlags; + // This is simply a different representation of info in fVertexAttribs and thus does // not need to be compared in op==. int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt]; @@ -429,6 +443,13 @@ private: */ bool srcAlphaWillBeOne() const; + /** + * Helper function for getBlendOpts. + */ + BlendOptFlags calcBlendOpts(bool forceCoverage = false, + GrBlendCoeff* srcCoeff = NULL, + GrBlendCoeff* dstCoeff = NULL) const; + typedef SkRefCnt INHERITED; }; diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 96c5367c6a..916c31ccbe 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -4,6 +4,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ + #include "GrGLProgram.h" #include "GrAllocator.h" @@ -15,7 +16,6 @@ #include "GrGLPathRendering.h" #include "GrGLShaderVar.h" #include "GrGLSL.h" -#include "GrOptDrawState.h" #include "SkXfermode.h" #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) @@ -109,19 +109,31 @@ void GrGLProgram::initSamplerUniforms() { /////////////////////////////////////////////////////////////////////////////// -void GrGLProgram::setData(const GrOptDrawState& optState, - GrGpu::DrawType drawType, +void GrGLProgram::setData(GrGpu::DrawType drawType, + GrDrawState::BlendOptFlags blendOpts, const GrEffectStage* geometryProcessor, const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[], const GrDeviceCoordTexture* dstCopy, SharedGLState* sharedState) { - GrColor color = optState.getColor(); - GrColor coverage = optState.getCoverageColor(); + const GrDrawState& drawState = fGpu->getDrawState(); + + GrColor color; + GrColor coverage; + if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) { + color = 0; + coverage = 0; + } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) { + color = 0xffffffff; + coverage = drawState.getCoverageColor(); + } else { + color = drawState.getColor(); + coverage = drawState.getCoverageColor(); + } - this->setColor(optState, color, sharedState); - this->setCoverage(optState, coverage, sharedState); - this->setMatrixAndRenderTargetHeight(drawType, optState); + this->setColor(drawState, color, sharedState); + this->setCoverage(drawState, coverage, sharedState); + this->setMatrixAndRenderTargetHeight(drawType, drawState); if (dstCopy) { if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) { @@ -159,11 +171,11 @@ void GrGLProgram::setData(const GrOptDrawState& optState, } } -void GrGLProgram::setColor(const GrOptDrawState& optState, +void GrGLProgram::setColor(const GrDrawState& drawState, GrColor color, SharedGLState* sharedState) { const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); - if (!optState.hasColorVertexAttribute()) { + if (!drawState.hasColorVertexAttribute() || drawState.canIgnoreColorAttribute()) { switch (header.fColorInput) { case GrGLProgramDesc::kAttribute_ColorInput: SkASSERT(-1 != header.fColorAttributeIndex); @@ -198,11 +210,11 @@ void GrGLProgram::setColor(const GrOptDrawState& optState, } } -void GrGLProgram::setCoverage(const GrOptDrawState& optState, +void GrGLProgram::setCoverage(const GrDrawState& drawState, GrColor coverage, SharedGLState* sharedState) { const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); - if (!optState.hasCoverageVertexAttribute()) { + if (!drawState.hasCoverageVertexAttribute()) { switch (header.fCoverageInput) { case GrGLProgramDesc::kAttribute_ColorInput: if (sharedState->fConstAttribCoverage != coverage || @@ -237,8 +249,8 @@ void GrGLProgram::setCoverage(const GrOptDrawState& optState, } void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, - const GrOptDrawState& optState) { - const GrRenderTarget* rt = optState.getRenderTarget(); + const GrDrawState& drawState) { + const GrRenderTarget* rt = drawState.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); @@ -250,13 +262,13 @@ void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, } if (GrGpu::IsPathRenderingDrawType(drawType)) { - fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin()); + fGpu->glPathRendering()->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin()); } else if (fMatrixState.fRenderTargetOrigin != rt->origin() || fMatrixState.fRenderTargetSize != size || - !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) { + !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())) { SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid()); - fMatrixState.fViewMatrix = optState.getViewMatrix(); + fMatrixState.fViewMatrix = drawState.getViewMatrix(); fMatrixState.fRenderTargetSize = size; fMatrixState.fRenderTargetOrigin = rt->origin(); diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index a520bc20de..0f89e07b0d 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -157,8 +157,8 @@ public: * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage * stages come from GrGLProgramDesc::Build(). */ - void setData(const GrOptDrawState&, - GrGpu::DrawType, + void setData(GrGpu::DrawType, + GrDrawState::BlendOptFlags, const GrEffectStage* geometryProcessor, const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[], @@ -177,14 +177,14 @@ private: // Helper for setData(). Makes GL calls to specify the initial color when there is not // per-vertex colors. - void setColor(const GrOptDrawState&, GrColor color, SharedGLState*); + void setColor(const GrDrawState&, GrColor color, SharedGLState*); // Helper for setData(). Makes GL calls to specify the initial coverage when there is not // per-vertex coverages. - void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*); + void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*); // Helper for setData() that sets the view matrix and loads the render target height uniform - void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState&); + void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrDrawState&); // these reflect the current values of uniforms (GL uniform values travel with program) MatrixState fMatrixState; diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index bde4072cc3..d7ba287cfa 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -11,7 +11,6 @@ #include "GrDrawEffect.h" #include "GrEffect.h" #include "GrGpuGL.h" -#include "GrOptDrawState.h" #include "SkChecksum.h" @@ -47,8 +46,9 @@ bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage, return true; } -bool GrGLProgramDesc::Build(const GrOptDrawState& optState, +bool GrGLProgramDesc::Build(const GrDrawState& drawState, GrGpu::DrawType drawType, + GrDrawState::BlendOptFlags blendOpts, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff, const GrGpuGL* gpu, @@ -60,19 +60,47 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, colorStages->reset(); coverageStages->reset(); - bool inputColorIsUsed = optState.inputColorIsUsed(); - bool inputCoverageIsUsed = optState.inputColorIsUsed(); + // This should already have been caught + SkASSERT(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); + + bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); + + bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag | + GrDrawState::kEmitCoverage_BlendOptFlag)); + + int firstEffectiveColorStage = 0; + bool inputColorIsUsed = true; + + if (!skipColor) { + firstEffectiveColorStage = drawState.numColorStages(); + while (firstEffectiveColorStage > 0 && inputColorIsUsed) { + --firstEffectiveColorStage; + const GrEffect* effect = drawState.getColorStage(firstEffectiveColorStage).getEffect(); + inputColorIsUsed = effect->willUseInputColor(); + } + } + + int firstEffectiveCoverageStage = 0; + bool inputCoverageIsUsed = true; + if (!skipCoverage) { + firstEffectiveCoverageStage = drawState.numCoverageStages(); + while (firstEffectiveCoverageStage > 0 && inputCoverageIsUsed) { + --firstEffectiveCoverageStage; + const GrEffect* effect = drawState.getCoverageStage(firstEffectiveCoverageStage).getEffect(); + inputCoverageIsUsed = effect->willUseInputColor(); + } + } // The descriptor is used as a cache key. Thus when a field of the // descriptor will not affect program generation (because of the attribute // bindings in use or other descriptor field settings) it should be set // to a canonical value to avoid duplicate programs with different keys. - bool requiresColorAttrib = optState.hasColorVertexAttribute(); - bool requiresCoverageAttrib = optState.hasCoverageVertexAttribute(); + bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute(); + bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAttribute(); // we only need the local coords if we're actually going to generate effect code - bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 && - optState.hasLocalCoordAttribute(); + bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) && + drawState.hasLocalCoordAttribute(); bool readsDst = false; bool readFragPosition = false; @@ -80,8 +108,16 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, // Provide option for shader programs without vertex shader only when drawing paths. bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType); - int numStages = optState.numTotalStages(); - + int numStages = 0; + if (drawState.hasGeometryProcessor()) { + numStages++; + } + if (!skipColor) { + numStages += drawState.numColorStages() - firstEffectiveColorStage; + } + if (!skipCoverage) { + numStages += drawState.numCoverageStages() - firstEffectiveCoverageStage; + } GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); // Make room for everything up to and including the array of offsets to effect keys. desc->fKey.reset(); @@ -95,7 +131,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, memset(desc->header(), 0, kHeaderSize); // We can only have one effect which touches the vertex shader - if (optState.hasGeometryProcessor()) { + if (drawState.hasGeometryProcessor()) { uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + offsetAndSizeIndex * 2 * sizeof(uint16_t)); @@ -104,7 +140,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, uint16_t effectKeySize; uint32_t effectOffset = desc->fKey.count(); effectKeySuccess |= GetEffectKeyAndUpdateStats( - *optState.getGeometryProcessor(), gpu->glCaps(), + *drawState.getGeometryProcessor(), gpu->glCaps(), requiresLocalCoordAttrib, &b, &effectKeySize, &readsDst, &readFragPosition, &requiresVertexShader); @@ -113,55 +149,57 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, offsetAndSize[0] = SkToU16(effectOffset); offsetAndSize[1] = effectKeySize; ++offsetAndSizeIndex; - *geometryProcessor = optState.getGeometryProcessor(); + *geometryProcessor = drawState.getGeometryProcessor(); SkASSERT(requiresVertexShader); header->fHasGeometryProcessor = true; } - for (int s = 0; s < optState.numColorStages(); ++s) { - uint16_t* offsetAndSize = - reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + - offsetAndSizeIndex * 2 * sizeof(uint16_t)); - - bool effectRequiresVertexShader = false; - GrEffectKeyBuilder b(&desc->fKey); - uint16_t effectKeySize; - uint32_t effectOffset = desc->fKey.count(); - effectKeySuccess |= GetEffectKeyAndUpdateStats( - optState.getColorStage(s), gpu->glCaps(), - requiresLocalCoordAttrib, &b, - &effectKeySize, &readsDst, - &readFragPosition, &effectRequiresVertexShader); - effectKeySuccess |= (effectOffset <= SK_MaxU16); - - offsetAndSize[0] = SkToU16(effectOffset); - offsetAndSize[1] = effectKeySize; - ++offsetAndSizeIndex; - SkASSERT(!effectRequiresVertexShader); - } + if (!skipColor) { + for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) { + uint16_t* offsetAndSize = + reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + + offsetAndSizeIndex * 2 * sizeof(uint16_t)); - for (int s = 0; s < optState.numCoverageStages(); ++s) { - uint16_t* offsetAndSize = - reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + - offsetAndSizeIndex * 2 * sizeof(uint16_t)); - - bool effectRequiresVertexShader = false; - GrEffectKeyBuilder b(&desc->fKey); - uint16_t effectKeySize; - uint32_t effectOffset = desc->fKey.count(); - effectKeySuccess |= GetEffectKeyAndUpdateStats( - optState.getCoverageStage(s), gpu->glCaps(), - requiresLocalCoordAttrib, &b, - &effectKeySize, &readsDst, - &readFragPosition, &effectRequiresVertexShader); - effectKeySuccess |= (effectOffset <= SK_MaxU16); - - offsetAndSize[0] = SkToU16(effectOffset); - offsetAndSize[1] = effectKeySize; - ++offsetAndSizeIndex; - SkASSERT(!effectRequiresVertexShader); + bool effectRequiresVertexShader = false; + GrEffectKeyBuilder b(&desc->fKey); + uint16_t effectKeySize; + uint32_t effectOffset = desc->fKey.count(); + effectKeySuccess |= GetEffectKeyAndUpdateStats( + drawState.getColorStage(s), gpu->glCaps(), + requiresLocalCoordAttrib, &b, + &effectKeySize, &readsDst, + &readFragPosition, &effectRequiresVertexShader); + effectKeySuccess |= (effectOffset <= SK_MaxU16); + + offsetAndSize[0] = SkToU16(effectOffset); + offsetAndSize[1] = effectKeySize; + ++offsetAndSizeIndex; + SkASSERT(!effectRequiresVertexShader); + } } + if (!skipCoverage) { + for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) { + uint16_t* offsetAndSize = + reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + + offsetAndSizeIndex * 2 * sizeof(uint16_t)); + bool effectRequiresVertexShader = false; + GrEffectKeyBuilder b(&desc->fKey); + uint16_t effectKeySize; + uint32_t effectOffset = desc->fKey.count(); + effectKeySuccess |= GetEffectKeyAndUpdateStats( + drawState.getCoverageStage(s), gpu->glCaps(), + requiresLocalCoordAttrib, &b, + &effectKeySize, &readsDst, + &readFragPosition, &effectRequiresVertexShader); + effectKeySuccess |= (effectOffset <= SK_MaxU16); + + offsetAndSize[0] = SkToU16(effectOffset); + offsetAndSize[1] = effectKeySize; + ++offsetAndSizeIndex; + SkASSERT(!effectRequiresVertexShader); + } + } if (!effectKeySuccess) { desc->fKey.reset(); return false; @@ -184,20 +222,20 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, #endif bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->pathRenderingSupport(); - if (!inputColorIsUsed) { + if (!inputColorIsUsed && !skipColor) { header->fColorInput = kAllOnes_ColorInput; - } else if (defaultToUniformInputs && !requiresColorAttrib) { + } else if (defaultToUniformInputs && !requiresColorAttrib && inputColorIsUsed) { header->fColorInput = kUniform_ColorInput; } else { header->fColorInput = kAttribute_ColorInput; header->fRequiresVertexShader = true; } - bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == optState.getCoverageColor(); + bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor(); - if (covIsSolidWhite || !inputCoverageIsUsed) { + if ((covIsSolidWhite || !inputCoverageIsUsed) && !skipCoverage) { header->fCoverageInput = kAllOnes_ColorInput; - } else if (defaultToUniformInputs && !requiresCoverageAttrib) { + } else if (defaultToUniformInputs && !requiresCoverageAttrib && inputCoverageIsUsed) { header->fCoverageInput = kUniform_ColorInput; } else { header->fCoverageInput = kAttribute_ColorInput; @@ -219,19 +257,19 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, if (readFragPosition) { header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( - optState.getRenderTarget(), gpu->glCaps()); + drawState.getRenderTarget(), gpu->glCaps()); } else { header->fFragPosKey = 0; } // Record attribute indices - header->fPositionAttributeIndex = optState.positionAttributeIndex(); - header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); + header->fPositionAttributeIndex = drawState.positionAttributeIndex(); + header->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex(); // For constant color and coverage we need an attribute with an index beyond those already set - int availableAttributeIndex = optState.getVertexAttribCount(); + int availableAttributeIndex = drawState.getVertexAttribCount(); if (requiresColorAttrib) { - header->fColorAttributeIndex = optState.colorVertexAttributeIndex(); + header->fColorAttributeIndex = drawState.colorVertexAttributeIndex(); } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) { SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); header->fColorAttributeIndex = availableAttributeIndex; @@ -241,7 +279,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, } if (requiresCoverageAttrib) { - header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex(); + header->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex(); } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); header->fCoverageAttributeIndex = availableAttributeIndex; @@ -255,13 +293,15 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, header->fCoverageOutput = kModulate_CoverageOutput; // If we do have coverage determine whether it matters. - bool separateCoverageFromColor = optState.hasGeometryProcessor(); - if (!optState.isCoverageDrawing() && - (optState.numCoverageStages() > 0 || - optState.hasGeometryProcessor() || + bool separateCoverageFromColor = drawState.hasGeometryProcessor(); + if (!drawState.isCoverageDrawing() && !skipCoverage && + (drawState.numCoverageStages() > 0 || + drawState.hasGeometryProcessor() || requiresCoverageAttrib)) { - if (gpu->caps()->dualSourceBlendingSupport()) { + if (gpu->caps()->dualSourceBlendingSupport() && + !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | + GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { if (kZero_GrBlendCoeff == dstCoeff) { // write the coverage value to second color header->fCoverageOutput = kSecondaryCoverage_CoverageOutput; @@ -283,19 +323,22 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, } } - for (int s = 0; s < optState.numColorStages(); ++s) { - colorStages->push_back(&optState.getColorStage(s)); - } - SkTArray<const GrEffectStage*, true>* array; - if (separateCoverageFromColor) { - array = coverageStages; - } else { - array = colorStages; + if (!skipColor) { + for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) { + colorStages->push_back(&drawState.getColorStage(s)); + } } - for (int s = 0; s < optState.numCoverageStages(); ++s) { - array->push_back(&optState.getCoverageStage(s)); + if (!skipCoverage) { + SkTArray<const GrEffectStage*, true>* array; + if (separateCoverageFromColor) { + array = coverageStages; + } else { + array = colorStages; + } + for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) { + array->push_back(&drawState.getCoverageStage(s)); + } } - header->fColorEffectCnt = colorStages->count(); header->fCoverageEffectCnt = coverageStages->count(); diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h index e91dbe0950..b1f54b7e29 100644 --- a/src/gpu/gl/GrGLProgramDesc.h +++ b/src/gpu/gl/GrGLProgramDesc.h @@ -55,13 +55,15 @@ public: int currAttribIndex); /** - * Builds a program descriptor from a GrOptDrawState. Whether the primitive type is points, and - * the caps of the GrGpuGL are also inputs. It also outputs the color and coverage stages - * referenced by the generated descriptor. Coverage stages from the drawState may be treated as - * color stages in the output. + * Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the + * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also + * outputs the color and coverage stages referenced by the generated descriptor. This may + * not contain all stages from the draw state and coverage stages from the drawState may + * be treated as color stages in the output. */ - static bool Build(const GrOptDrawState&, + static bool Build(const GrDrawState&, GrGpu::DrawType drawType, + GrDrawState::BlendOptFlags, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff, const GrGpuGL* gpu, diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 5ff868ccaf..c335e128c7 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -8,7 +8,6 @@ #include "GrGpuGL.h" #include "GrGLStencilBuffer.h" -#include "GrOptDrawState.h" #include "GrTemplates.h" #include "GrTypes.h" #include "SkStrokeRec.h" diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 476f174cdc..be21abf3e9 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -9,9 +9,8 @@ #include "GrEffect.h" #include "GrGLEffect.h" -#include "GrGLPathRendering.h" -#include "GrOptDrawState.h" #include "SkRTConf.h" +#include "GrGLPathRendering.h" #include "SkTSearch.h" #ifdef PROGRAM_CACHE_STATS @@ -205,25 +204,23 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc, #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) { - SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState()); + const GrDrawState& drawState = this->getDrawState(); // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true. - SkASSERT(optState->getRenderTarget()); + SkASSERT(drawState.getRenderTarget()); if (kStencilPath_DrawType == type) { - const GrRenderTarget* rt = optState->getRenderTarget(); + const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); - this->glPathRendering()->setProjectionMatrix(optState->getViewMatrix(), size, rt->origin()); + this->glPathRendering()->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin()); } else { this->flushMiscFixedFunctionState(); - GrBlendCoeff srcCoeff = optState->getSrcBlendCoeff(); - GrBlendCoeff dstCoeff = optState->getDstBlendCoeff(); - - // In these blend coeff's we end up drawing nothing so we can skip draw all together - if (kZero_GrBlendCoeff == srcCoeff && kOne_GrBlendCoeff == dstCoeff && - !optState->getStencil().doesWrite()) { + GrBlendCoeff srcCoeff; + GrBlendCoeff dstCoeff; + GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff); + if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) { return false; } @@ -231,8 +228,9 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC SkSTArray<8, const GrEffectStage*, true> colorStages; SkSTArray<8, const GrEffectStage*, true> coverageStages; GrGLProgramDesc desc; - if (!GrGLProgramDesc::Build(*optState.get(), + if (!GrGLProgramDesc::Build(this->getDrawState(), type, + blendOpts, srcCoeff, dstCoeff, this, @@ -265,8 +263,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff); this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff); - fCurrentProgram->setData(*optState.get(), - type, + fCurrentProgram->setData(type, + blendOpts, geometryProcessor, colorStages.begin(), coverageStages.begin(), @@ -274,15 +272,15 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC &fSharedGLProgramState); } - GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget()); + GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(drawState.getRenderTarget()); this->flushStencil(type); this->flushScissor(glRT->getViewport(), glRT->origin()); this->flushAAState(type); SkIRect* devRect = NULL; SkIRect devClipBounds; - if (optState->isClipState()) { - this->getClip()->getConservativeBounds(optState->getRenderTarget(), &devClipBounds); + if (drawState.isClipState()) { + this->getClip()->getConservativeBounds(drawState.getRenderTarget(), &devClipBounds); devRect = &devClipBounds; } // This must come after textures are flushed because a texture may need @@ -293,9 +291,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC } void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { - SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState()); - GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride()); + GrGLsizei stride = static_cast<GrGLsizei>(this->getDrawState().getVertexStride()); size_t vertexOffsetInBytes = stride * info.startVertex(); @@ -349,12 +346,16 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); if (fCurrentProgram->hasVertexShader()) { - int vertexAttribCount = optState->getVertexAttribCount(); + int vertexAttribCount = this->getDrawState().getVertexAttribCount(); uint32_t usedAttribArraysMask = 0; - const GrVertexAttrib* vertexAttrib = optState->getVertexAttribs(); + const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs(); + + bool canIgnoreColorAttrib = this->getDrawState().canIgnoreColorAttribute(); for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount; ++vertexAttribIndex, ++vertexAttrib) { + + if (kColor_GrVertexAttribBinding != vertexAttrib->fBinding || !canIgnoreColorAttrib) { usedAttribArraysMask |= (1 << vertexAttribIndex); GrVertexAttribType attribType = vertexAttrib->fType; attribState->set(this, @@ -366,6 +367,7 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { stride, reinterpret_cast<GrGLvoid*>( vertexOffsetInBytes + vertexAttrib->fOffset)); + } } attribState->disableUnusedArrays(this, usedAttribArraysMask); } diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp index 5c074a2901..f06c6468cc 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp @@ -9,7 +9,6 @@ #include "GrGLProgramBuilder.h" #include "GrGLShaderStringBuilder.h" #include "../GrGpuGL.h" -#include "../../GrOptDrawState.h" #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X) #define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X) @@ -84,12 +83,10 @@ void GrGLVertexShaderBuilder::bindProgramLocations(GrGLuint programId) { coverage_attribute_name())); } - // We pull the current state of attributes off of drawstate's optimized state and bind them in - // order. This assumes that the drawState has not changed since we called flushGraphicsState() - // higher up in the stack. - SkAutoTUnref<GrOptDrawState> optState(fProgramBuilder->gpu()->drawState()->createOptState()); - const GrVertexAttrib* vaPtr = optState->getVertexAttribs(); - const int vaCount = optState->getVertexAttribCount(); + // We pull the current state of attributes off of drawstate and bind them in order + const GrRODrawState* ds = fProgramBuilder->gpu()->drawState(); + const GrVertexAttrib* vaPtr = ds->getVertexAttribs(); + const int vaCount = ds->getVertexAttribCount(); int i = fEffectAttribOffset; for (int index = 0; index < vaCount; index++) { |