aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/GrDrawState.cpp10
-rw-r--r--src/gpu/GrDrawState.h4
-rw-r--r--src/gpu/GrOptDrawState.cpp53
-rw-r--r--src/gpu/GrOptDrawState.h51
-rw-r--r--src/gpu/gl/GrGLProgram.cpp22
-rw-r--r--src/gpu/gl/GrGLProgram.h5
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp43
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h45
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp5
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp44
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp4
-rw-r--r--tests/GLProgramsTest.cpp30
12 files changed, 174 insertions, 142 deletions
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index f639744665..8726965818 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -7,24 +7,24 @@
#include "GrDrawState.h"
-#include "GrDrawTargetCaps.h"
#include "GrOptDrawState.h"
#include "GrPaint.h"
//////////////////////////////////////////////////////////////////////////////s
-GrOptDrawState* GrDrawState::createOptState() const {
- if (NULL == fCachedOptState) {
+GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps& caps) const {
+ if (NULL == fCachedOptState || caps.getUniqueID() != fCachedCapsID) {
GrBlendCoeff srcCoeff;
GrBlendCoeff dstCoeff;
BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
- fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoeff, dstCoeff));
+ fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoeff, dstCoeff, caps));
+ fCachedCapsID = caps.getUniqueID();
} else {
#ifdef SK_DEBUG
GrBlendCoeff srcCoeff;
GrBlendCoeff dstCoeff;
BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
- SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff) == *fCachedOptState);
+ SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff, caps) == *fCachedOptState);
#endif
}
fCachedOptState->ref();
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 458fb958e6..5e4ed9b4c0 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -9,6 +9,7 @@
#define GrDrawState_DEFINED
#include "GrBlend.h"
+#include "GrDrawTargetCaps.h"
#include "GrGpuResourceRef.h"
#include "GrRODrawState.h"
#include "effects/GrSimpleTextureEffect.h"
@@ -547,7 +548,7 @@ public:
* GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
* caller.
*/
- GrOptDrawState* createOptState() const;
+ GrOptDrawState* createOptState(const GrDrawTargetCaps&) const;
private:
void invalidateOptState() const;
@@ -561,6 +562,7 @@ private:
void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
mutable GrOptDrawState* fCachedOptState;
+ mutable uint32_t fCachedCapsID;
typedef GrRODrawState INHERITED;
};
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index cb03d2d683..ac30311455 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -8,11 +8,14 @@
#include "GrOptDrawState.h"
#include "GrDrawState.h"
+#include "GrDrawTargetCaps.h"
+#include "GrGpu.h"
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
BlendOptFlags blendOptFlags,
GrBlendCoeff optSrcCoeff,
- GrBlendCoeff optDstCoeff) : INHERITED(drawState) {
+ GrBlendCoeff optDstCoeff,
+ const GrDrawTargetCaps& caps) : INHERITED(drawState) {
fColor = drawState.getColor();
fCoverage = drawState.getCoverage();
fViewMatrix = drawState.getViewMatrix();
@@ -45,8 +48,56 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
this->copyEffectiveCoverageStages(drawState);
this->adjustFromBlendOpts();
this->getStageStats();
+ this->setOutputStateInfo(caps);
};
+void GrOptDrawState::setOutputStateInfo(const GrDrawTargetCaps& caps) {
+ // Set this default and then possibly change our mind if there is coverage.
+ fPrimaryOutputType = kModulate_PrimaryOutputType;
+ fSecondaryOutputType = kNone_SecondaryOutputType;
+
+ // If we do have coverage determine whether it matters.
+ bool separateCoverageFromColor = this->hasGeometryProcessor();
+ if (!this->isCoverageDrawing() &&
+ (this->numCoverageStages() > 0 ||
+ this->hasGeometryProcessor() ||
+ this->hasCoverageVertexAttribute())) {
+
+ if (caps.dualSourceBlendingSupport()) {
+ if (kZero_GrBlendCoeff == fDstBlend) {
+ // write the coverage value to second color
+ fSecondaryOutputType = kCoverage_SecondaryOutputType;
+ separateCoverageFromColor = true;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ } else if (kSA_GrBlendCoeff == fDstBlend) {
+ // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+ fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
+ separateCoverageFromColor = true;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ } else if (kSC_GrBlendCoeff == fDstBlend) {
+ // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+ fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
+ separateCoverageFromColor = true;
+ fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+ }
+ } else if (fReadsDst &&
+ kOne_GrBlendCoeff == fSrcBlend &&
+ kZero_GrBlendCoeff == fDstBlend) {
+ fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
+ separateCoverageFromColor = true;
+ }
+ }
+
+ // TODO: Once we have flag to know if we only multiply on stages, only push coverage into color
+ // stages if everything is multipy
+ if (!separateCoverageFromColor) {
+ for (int s = 0; s < this->numCoverageStages(); ++s) {
+ fColorStages.push_back(this->getCoverageStage(s));
+ }
+ fCoverageStages.reset();
+ }
+}
+
void GrOptDrawState::adjustFromBlendOpts() {
switch (fBlendOptFlags) {
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index 9c9bf94597..9445d334a2 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -28,12 +28,48 @@ public:
bool requiresVertexShader() const { return fRequiresVertexShader; }
bool requiresLocalCoordAttrib() const { return fRequiresLocalCoordAttrib; }
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Stage Output Types
+ ////
+
+ enum PrimaryOutputType {
+ // Modulate color and coverage, write result as the color output.
+ kModulate_PrimaryOutputType,
+ // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
+ // can only be set if fDstReadKey is non-zero.
+ kCombineWithDst_PrimaryOutputType,
+
+ kPrimaryOutputTypeCnt,
+ };
+
+ enum SecondaryOutputType {
+ // There is no secondary output
+ kNone_SecondaryOutputType,
+ // Writes coverage as the secondary output. Only set if dual source blending is supported
+ // and primary output is kModulate.
+ kCoverage_SecondaryOutputType,
+ // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
+ // is supported and primary output is kModulate.
+ kCoverageISA_SecondaryOutputType,
+ // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
+ // blending is supported and primary output is kModulate.
+ kCoverageISC_SecondaryOutputType,
+
+ kSecondaryOutputTypeCnt,
+ };
+
+ PrimaryOutputType getPrimaryOutputType() const { return fPrimaryOutputType; }
+ SecondaryOutputType getSecondaryOutputType() const { return fSecondaryOutputType; }
+
+ /// @}
+
private:
/**
* Constructs and optimized drawState out of a GrRODrawState.
*/
GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
- GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff);
+ GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff,
+ const GrDrawTargetCaps& caps);
/**
* Loops through all the color stage effects to check if the stage will ignore color input or
@@ -72,6 +108,13 @@ private:
*/
void getStageStats();
+ /**
+ * Calculates the primary and secondary output types of the shader. For certain output types
+ * the function may adjust the blend coefficients. After this function is called the src and dst
+ * blend coeffs will represent those used by backend API.
+ */
+ void setOutputStateInfo(const GrDrawTargetCaps&);
+
// These flags are needed to protect the code from creating an unused uniform color/coverage
// which will cause shader compiler errors.
bool fInputColorIsUsed;
@@ -87,7 +130,11 @@ private:
BlendOptFlags fBlendOptFlags;
- friend GrOptDrawState* GrDrawState::createOptState() const;
+ // Fragment shader color outputs
+ PrimaryOutputType fPrimaryOutputType : 8;
+ SecondaryOutputType fSecondaryOutputType : 8;
+
+ friend GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps&) const;
typedef GrRODrawState INHERITED;
};
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index a695173f4c..1639a842b7 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -74,28 +74,6 @@ void GrGLProgram::abandon() {
fProgramID = 0;
}
-void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
- GrBlendCoeff* dstCoeff) const {
- switch (fDesc.getHeader().fCoverageOutput) {
- case GrGLProgramDesc::kModulate_CoverageOutput:
- break;
- // The prog will write a coverage value to the secondary
- // output and the dst is blended by one minus that value.
- case GrGLProgramDesc::kSecondaryCoverage_CoverageOutput:
- case GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput:
- case GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput:
- *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
- break;
- case GrGLProgramDesc::kCombineWithDst_CoverageOutput:
- // We should only have set this if the blend was specified as (1, 0)
- SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *dstCoeff);
- break;
- default:
- SkFAIL("Unexpected coverage output");
- break;
- }
-}
-
void GrGLProgram::initSamplerUniforms() {
GL_CALL(UseProgram(fProgramID));
GrGLint texUnitIdx = 0;
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index a520bc20de..3238a75fe4 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -52,11 +52,6 @@ public:
*/
void abandon();
- /**
- * The shader may modify the blend coefficients. Params are in/out.
- */
- void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
-
const GrGLProgramDesc& getDesc() { return fDesc; }
/**
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index c0a9e13ed1..5339937c1a 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -343,51 +343,14 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
header->fCoverageAttributeIndex = -1;
}
- // Here we deal with whether/how we handle color and coverage separately.
-
- // Set this default and then possibly change our mind if there is coverage.
- 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() ||
- requiresCoverageAttrib)) {
-
- if (gpu->caps()->dualSourceBlendingSupport()) {
- if (kZero_GrBlendCoeff == dstCoeff) {
- // write the coverage value to second color
- header->fCoverageOutput = kSecondaryCoverage_CoverageOutput;
- separateCoverageFromColor = true;
- } else if (kSA_GrBlendCoeff == dstCoeff) {
- // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
- header->fCoverageOutput = kSecondaryCoverageISA_CoverageOutput;
- separateCoverageFromColor = true;
- } else if (kSC_GrBlendCoeff == dstCoeff) {
- // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
- header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput;
- separateCoverageFromColor = true;
- }
- } else if (optState.readsDst() &&
- kOne_GrBlendCoeff == srcCoeff &&
- kZero_GrBlendCoeff == dstCoeff) {
- header->fCoverageOutput = kCombineWithDst_CoverageOutput;
- separateCoverageFromColor = true;
- }
- }
+ header->fPrimaryOutputType = optState.getPrimaryOutputType();
+ header->fSecondaryOutputType = optState.getSecondaryOutputType();
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;
- }
for (int s = 0; s < optState.numCoverageStages(); ++s) {
- array->push_back(&optState.getCoverageStage(s));
+ coverageStages->push_back(&optState.getCoverageStage(s));
}
header->fColorEffectCnt = colorStages->count();
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index c9bdac54ee..172a202b42 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -11,6 +11,7 @@
#include "GrGLEffect.h"
#include "GrDrawState.h"
#include "GrGpu.h"
+#include "GrOptDrawState.h"
class GrGpuGL;
@@ -111,50 +112,24 @@ private:
kColorInputCnt
};
- enum CoverageOutput {
- // modulate color and coverage, write result as the color output.
- kModulate_CoverageOutput,
- // Writes color*coverage as the primary color output and also writes coverage as the
- // secondary output. Only set if dual source blending is supported.
- kSecondaryCoverage_CoverageOutput,
- // Writes color*coverage as the primary color output and also writes coverage * (1 - colorA)
- // as the secondary output. Only set if dual source blending is supported.
- kSecondaryCoverageISA_CoverageOutput,
- // Writes color*coverage as the primary color output and also writes coverage *
- // (1 - colorRGB) as the secondary output. Only set if dual source blending is supported.
- kSecondaryCoverageISC_CoverageOutput,
- // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
- // can only be set if fDstReadKey is non-zero.
- kCombineWithDst_CoverageOutput,
-
- kCoverageOutputCnt
- };
-
- static bool CoverageOutputUsesSecondaryOutput(CoverageOutput co) {
- switch (co) {
- case kSecondaryCoverage_CoverageOutput: // fallthru
- case kSecondaryCoverageISA_CoverageOutput:
- case kSecondaryCoverageISC_CoverageOutput:
- return true;
- default:
- return false;
- }
- }
-
struct KeyHeader {
- uint8_t fDstReadKey; // set by GrGLShaderBuilder if there
+ uint8_t fDstReadKey; // set by GrGLShaderBuilder if there
// are effects that must read the dst.
// Otherwise, 0.
- uint8_t fFragPosKey; // set by GrGLShaderBuilder if there are
+ uint8_t fFragPosKey; // set by GrGLShaderBuilder if there are
// effects that read the fragment position.
// Otherwise, 0.
- ColorInput fColorInput : 8;
- ColorInput fCoverageInput : 8;
- CoverageOutput fCoverageOutput : 8;
SkBool8 fUseFragShaderOnly;
SkBool8 fEmitsPointSize;
+ ColorInput fColorInput : 8;
+ ColorInput fCoverageInput : 8;
+
+ GrOptDrawState::PrimaryOutputType fPrimaryOutputType : 8;
+ GrOptDrawState::SecondaryOutputType fSecondaryOutputType : 8;
+
+
// To enable experimental geometry shader code (not for use in
// production)
#if GR_GL_EXPERIMENTAL_GS
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 476f174cdc..387741be6f 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -205,7 +205,7 @@ 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());
+ SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState(*this->caps()));
// GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
SkASSERT(optState->getRenderTarget());
@@ -262,7 +262,6 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
fHWProgramID = programID;
}
- fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
fCurrentProgram->setData(*optState.get(),
@@ -293,7 +292,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
}
void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
- SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState());
+ SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState(*this->caps()));
GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride());
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
index 730ce04b3e..7279f1c393 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -304,18 +304,22 @@ void GrGLFragmentShaderBuilder::emitCodeAfterEffects(const GrGLSLExpr4& inputCol
///////////////////////////////////////////////////////////////////////////
// write the secondary color output if necessary
- if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) {
+ if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
const char* secondaryOutputName = this->enableSecondaryOutput();
-
- // default coeff to ones for kCoverage_DualSrcOutput
GrGLSLExpr4 coeff(1);
- if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) {
- // Get (1-A) into coeff
- coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
- } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput ==
- header.fCoverageOutput){
- // Get (1-RGBA) into coeff
- coeff = GrGLSLExpr4(1) - inputColor;
+ switch (header.fSecondaryOutputType) {
+ case GrOptDrawState::kCoverage_SecondaryOutputType:
+ break;
+ case GrOptDrawState::kCoverageISA_SecondaryOutputType:
+ // Get (1-A) into coeff
+ coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
+ break;
+ case GrOptDrawState::kCoverageISC_SecondaryOutputType:
+ // Get (1-RGBA) into coeff
+ coeff = GrGLSLExpr4(1) - inputColor;
+ break;
+ default:
+ SkFAIL("Unexpected Secondary Output");
}
// Get coeff * coverage into modulate and then write that to the dual source output.
codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
@@ -326,13 +330,19 @@ void GrGLFragmentShaderBuilder::emitCodeAfterEffects(const GrGLSLExpr4& inputCol
// Get "color * coverage" into fragColor
GrGLSLExpr4 fragColor = inputColor * inputCoverage;
- // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so.
- if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) {
- GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
-
- GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(dstColor());
-
- fragColor = fragColor + dstContribution;
+ switch (header.fPrimaryOutputType) {
+ case GrOptDrawState::kModulate_PrimaryOutputType:
+ break;
+ case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
+ {
+ // Tack on "+(1-coverage)dst onto the frag color.
+ GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
+ GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(dstColor());
+ fragColor = fragColor + dstContribution;
+ }
+ break;
+ default:
+ SkFAIL("Unknown Primary Output");
}
codeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());
}
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
index ad61465941..f99791e24e 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -87,7 +87,9 @@ void GrGLVertexShaderBuilder::bindProgramLocations(GrGLuint programId) {
// 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 GrDrawTargetCaps* caps = fProgramBuilder->gpu()->caps();
+ const GrDrawState& drawState = *fProgramBuilder->gpu()->drawState();
+ SkAutoTUnref<GrOptDrawState> optState(drawState.createOptState(*caps));
const GrVertexAttrib* vaPtr = optState->getVertexAttribs();
const int vaCount = optState->getVertexAttribCount();
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 0574bfc937..e4d9675bff 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -14,6 +14,7 @@
#include "GrBackendEffectFactory.h"
#include "GrContextFactory.h"
+#include "GrOptDrawState.h"
#include "effects/GrConfigConversionEffect.h"
#include "gl/GrGLPathRendering.h"
#include "gl/GrGpuGL.h"
@@ -159,16 +160,25 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
GrGLPathRendering::FixedFunction_TexturingMode;
header->fHasGeometryProcessor = vertexShader;
- CoverageOutput coverageOutput;
- bool illegalCoverageOutput;
- do {
- coverageOutput = static_cast<CoverageOutput>(random->nextULessThan(kCoverageOutputCnt));
- illegalCoverageOutput = (!gpu->caps()->dualSourceBlendingSupport() &&
- CoverageOutputUsesSecondaryOutput(coverageOutput)) ||
- (!dstRead && kCombineWithDst_CoverageOutput == coverageOutput);
- } while (illegalCoverageOutput);
+ GrOptDrawState::PrimaryOutputType primaryOutput;
+ GrOptDrawState::SecondaryOutputType secondaryOutput;
+ if (!dstRead) {
+ primaryOutput = GrOptDrawState::kModulate_PrimaryOutputType;
+ } else {
+ primaryOutput = static_cast<GrOptDrawState::PrimaryOutputType>(
+ random->nextULessThan(GrOptDrawState::kPrimaryOutputTypeCnt));
+ }
- header->fCoverageOutput = coverageOutput;
+ if (GrOptDrawState::kCombineWithDst_PrimaryOutputType == primaryOutput ||
+ !gpu->caps()->dualSourceBlendingSupport()) {
+ secondaryOutput = GrOptDrawState::kNone_SecondaryOutputType;
+ } else {
+ secondaryOutput = static_cast<GrOptDrawState::SecondaryOutputType>(
+ random->nextULessThan(GrOptDrawState::kSecondaryOutputTypeCnt));
+ }
+
+ header->fPrimaryOutputType = primaryOutput;
+ header->fSecondaryOutputType = secondaryOutput;
this->finalize();
return true;
@@ -249,7 +259,7 @@ bool GrGpuGL::programUnitTest(int maxStages) {
SkAutoSTMalloc<8, const GrEffectStage*> stages(numStages);
bool usePathRendering = this->glCaps().pathRenderingSupport() && random.nextBool();
-
+
GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType :
GrGpu::kDrawPoints_DrawType;