aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2014-09-16 07:18:54 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-16 07:18:54 -0700
commit8a4c1030ff4b8336b5ac5b0712691e2f65383440 (patch)
tree99a0918368070a16c004719881503de8c927f878 /src/gpu
parent08da4f22d790cfc51bbeb10b4b84dab49cf0eaec (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.cpp30
-rw-r--r--src/gpu/GrDrawState.h17
-rw-r--r--src/gpu/GrOptDrawState.cpp46
-rw-r--r--src/gpu/GrOptDrawState.h30
-rw-r--r--src/gpu/GrRODrawState.cpp30
-rw-r--r--src/gpu/GrRODrawState.h113
-rw-r--r--src/gpu/gl/GrGLProgram.cpp46
-rw-r--r--src/gpu/gl/GrGLProgram.h10
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp205
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h12
-rw-r--r--src/gpu/gl/GrGpuGL.cpp1
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp46
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp11
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++) {