Calculate Primary and Secondary output types in the GrOptDrawState

Follow up CL to https://codereview.chromium.org/545693004/

BUG=skia:
R=bsalomon@google.com

Author: egdaniel@google.com

Review URL: https://codereview.chromium.org/554833002
This commit is contained in:
egdaniel 2014-09-22 13:17:02 -07:00 committed by Commit bot
parent ae444965c4
commit c06482494d
12 changed files with 174 additions and 142 deletions

View File

@ -7,24 +7,24 @@
#include "GrDrawState.h" #include "GrDrawState.h"
#include "GrDrawTargetCaps.h"
#include "GrOptDrawState.h" #include "GrOptDrawState.h"
#include "GrPaint.h" #include "GrPaint.h"
//////////////////////////////////////////////////////////////////////////////s //////////////////////////////////////////////////////////////////////////////s
GrOptDrawState* GrDrawState::createOptState() const { GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps& caps) const {
if (NULL == fCachedOptState) { if (NULL == fCachedOptState || caps.getUniqueID() != fCachedCapsID) {
GrBlendCoeff srcCoeff; GrBlendCoeff srcCoeff;
GrBlendCoeff dstCoeff; GrBlendCoeff dstCoeff;
BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &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 { } else {
#ifdef SK_DEBUG #ifdef SK_DEBUG
GrBlendCoeff srcCoeff; GrBlendCoeff srcCoeff;
GrBlendCoeff dstCoeff; GrBlendCoeff dstCoeff;
BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff); BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff) == *fCachedOptState); SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff, caps) == *fCachedOptState);
#endif #endif
} }
fCachedOptState->ref(); fCachedOptState->ref();

View File

@ -9,6 +9,7 @@
#define GrDrawState_DEFINED #define GrDrawState_DEFINED
#include "GrBlend.h" #include "GrBlend.h"
#include "GrDrawTargetCaps.h"
#include "GrGpuResourceRef.h" #include "GrGpuResourceRef.h"
#include "GrRODrawState.h" #include "GrRODrawState.h"
#include "effects/GrSimpleTextureEffect.h" #include "effects/GrSimpleTextureEffect.h"
@ -547,7 +548,7 @@ public:
* GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
* caller. * caller.
*/ */
GrOptDrawState* createOptState() const; GrOptDrawState* createOptState(const GrDrawTargetCaps&) const;
private: private:
void invalidateOptState() const; void invalidateOptState() const;
@ -561,6 +562,7 @@ private:
void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride); void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
mutable GrOptDrawState* fCachedOptState; mutable GrOptDrawState* fCachedOptState;
mutable uint32_t fCachedCapsID;
typedef GrRODrawState INHERITED; typedef GrRODrawState INHERITED;
}; };

View File

@ -8,11 +8,14 @@
#include "GrOptDrawState.h" #include "GrOptDrawState.h"
#include "GrDrawState.h" #include "GrDrawState.h"
#include "GrDrawTargetCaps.h"
#include "GrGpu.h"
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
BlendOptFlags blendOptFlags, BlendOptFlags blendOptFlags,
GrBlendCoeff optSrcCoeff, GrBlendCoeff optSrcCoeff,
GrBlendCoeff optDstCoeff) : INHERITED(drawState) { GrBlendCoeff optDstCoeff,
const GrDrawTargetCaps& caps) : INHERITED(drawState) {
fColor = drawState.getColor(); fColor = drawState.getColor();
fCoverage = drawState.getCoverage(); fCoverage = drawState.getCoverage();
fViewMatrix = drawState.getViewMatrix(); fViewMatrix = drawState.getViewMatrix();
@ -45,8 +48,56 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
this->copyEffectiveCoverageStages(drawState); this->copyEffectiveCoverageStages(drawState);
this->adjustFromBlendOpts(); this->adjustFromBlendOpts();
this->getStageStats(); 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() { void GrOptDrawState::adjustFromBlendOpts() {
switch (fBlendOptFlags) { switch (fBlendOptFlags) {

View File

@ -28,12 +28,48 @@ public:
bool requiresVertexShader() const { return fRequiresVertexShader; } bool requiresVertexShader() const { return fRequiresVertexShader; }
bool requiresLocalCoordAttrib() const { return fRequiresLocalCoordAttrib; } 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: private:
/** /**
* Constructs and optimized drawState out of a GrRODrawState. * Constructs and optimized drawState out of a GrRODrawState.
*/ */
GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags, 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 * Loops through all the color stage effects to check if the stage will ignore color input or
@ -72,6 +108,13 @@ private:
*/ */
void getStageStats(); 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 // These flags are needed to protect the code from creating an unused uniform color/coverage
// which will cause shader compiler errors. // which will cause shader compiler errors.
bool fInputColorIsUsed; bool fInputColorIsUsed;
@ -87,7 +130,11 @@ private:
BlendOptFlags fBlendOptFlags; 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; typedef GrRODrawState INHERITED;
}; };

View File

@ -74,28 +74,6 @@ void GrGLProgram::abandon() {
fProgramID = 0; 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() { void GrGLProgram::initSamplerUniforms() {
GL_CALL(UseProgram(fProgramID)); GL_CALL(UseProgram(fProgramID));
GrGLint texUnitIdx = 0; GrGLint texUnitIdx = 0;

View File

@ -52,11 +52,6 @@ public:
*/ */
void abandon(); 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; } const GrGLProgramDesc& getDesc() { return fDesc; }
/** /**

View File

@ -343,51 +343,14 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
header->fCoverageAttributeIndex = -1; header->fCoverageAttributeIndex = -1;
} }
// Here we deal with whether/how we handle color and coverage separately. header->fPrimaryOutputType = optState.getPrimaryOutputType();
header->fSecondaryOutputType = optState.getSecondaryOutputType();
// 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;
}
}
for (int s = 0; s < optState.numColorStages(); ++s) { for (int s = 0; s < optState.numColorStages(); ++s) {
colorStages->push_back(&optState.getColorStage(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) { for (int s = 0; s < optState.numCoverageStages(); ++s) {
array->push_back(&optState.getCoverageStage(s)); coverageStages->push_back(&optState.getCoverageStage(s));
} }
header->fColorEffectCnt = colorStages->count(); header->fColorEffectCnt = colorStages->count();

View File

@ -11,6 +11,7 @@
#include "GrGLEffect.h" #include "GrGLEffect.h"
#include "GrDrawState.h" #include "GrDrawState.h"
#include "GrGpu.h" #include "GrGpu.h"
#include "GrOptDrawState.h"
class GrGpuGL; class GrGpuGL;
@ -111,50 +112,24 @@ private:
kColorInputCnt 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 { 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. // are effects that must read the dst.
// Otherwise, 0. // 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. // effects that read the fragment position.
// Otherwise, 0. // Otherwise, 0.
ColorInput fColorInput : 8;
ColorInput fCoverageInput : 8;
CoverageOutput fCoverageOutput : 8;
SkBool8 fUseFragShaderOnly; SkBool8 fUseFragShaderOnly;
SkBool8 fEmitsPointSize; 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 // To enable experimental geometry shader code (not for use in
// production) // production)
#if GR_GL_EXPERIMENTAL_GS #if GR_GL_EXPERIMENTAL_GS

View File

@ -205,7 +205,7 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) { 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. // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
SkASSERT(optState->getRenderTarget()); SkASSERT(optState->getRenderTarget());
@ -262,7 +262,6 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
fHWProgramID = programID; fHWProgramID = programID;
} }
fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff); this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
fCurrentProgram->setData(*optState.get(), 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) { 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()); GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride());

View File

@ -304,18 +304,22 @@ void GrGLFragmentShaderBuilder::emitCodeAfterEffects(const GrGLSLExpr4& inputCol
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// write the secondary color output if necessary // write the secondary color output if necessary
if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) { if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
const char* secondaryOutputName = this->enableSecondaryOutput(); const char* secondaryOutputName = this->enableSecondaryOutput();
// default coeff to ones for kCoverage_DualSrcOutput
GrGLSLExpr4 coeff(1); GrGLSLExpr4 coeff(1);
if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) { switch (header.fSecondaryOutputType) {
// Get (1-A) into coeff case GrOptDrawState::kCoverage_SecondaryOutputType:
coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a()); break;
} else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == case GrOptDrawState::kCoverageISA_SecondaryOutputType:
header.fCoverageOutput){ // Get (1-A) into coeff
// Get (1-RGBA) into coeff coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
coeff = GrGLSLExpr4(1) - inputColor; 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. // Get coeff * coverage into modulate and then write that to the dual source output.
codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str()); 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 // Get "color * coverage" into fragColor
GrGLSLExpr4 fragColor = inputColor * inputCoverage; GrGLSLExpr4 fragColor = inputColor * inputCoverage;
// Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so. switch (header.fPrimaryOutputType) {
if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) { case GrOptDrawState::kModulate_PrimaryOutputType:
GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage; break;
case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(dstColor()); {
// Tack on "+(1-coverage)dst onto the frag color.
fragColor = fragColor + dstContribution; 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()); codeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());
} }

View File

@ -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 // 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() // order. This assumes that the drawState has not changed since we called flushGraphicsState()
// higher up in the stack. // 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 GrVertexAttrib* vaPtr = optState->getVertexAttribs();
const int vaCount = optState->getVertexAttribCount(); const int vaCount = optState->getVertexAttribCount();

View File

@ -14,6 +14,7 @@
#include "GrBackendEffectFactory.h" #include "GrBackendEffectFactory.h"
#include "GrContextFactory.h" #include "GrContextFactory.h"
#include "GrOptDrawState.h"
#include "effects/GrConfigConversionEffect.h" #include "effects/GrConfigConversionEffect.h"
#include "gl/GrGLPathRendering.h" #include "gl/GrGLPathRendering.h"
#include "gl/GrGpuGL.h" #include "gl/GrGpuGL.h"
@ -159,16 +160,25 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
GrGLPathRendering::FixedFunction_TexturingMode; GrGLPathRendering::FixedFunction_TexturingMode;
header->fHasGeometryProcessor = vertexShader; header->fHasGeometryProcessor = vertexShader;
CoverageOutput coverageOutput; GrOptDrawState::PrimaryOutputType primaryOutput;
bool illegalCoverageOutput; GrOptDrawState::SecondaryOutputType secondaryOutput;
do { if (!dstRead) {
coverageOutput = static_cast<CoverageOutput>(random->nextULessThan(kCoverageOutputCnt)); primaryOutput = GrOptDrawState::kModulate_PrimaryOutputType;
illegalCoverageOutput = (!gpu->caps()->dualSourceBlendingSupport() && } else {
CoverageOutputUsesSecondaryOutput(coverageOutput)) || primaryOutput = static_cast<GrOptDrawState::PrimaryOutputType>(
(!dstRead && kCombineWithDst_CoverageOutput == coverageOutput); random->nextULessThan(GrOptDrawState::kPrimaryOutputTypeCnt));
} while (illegalCoverageOutput); }
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(); this->finalize();
return true; return true;
@ -249,7 +259,7 @@ bool GrGpuGL::programUnitTest(int maxStages) {
SkAutoSTMalloc<8, const GrEffectStage*> stages(numStages); SkAutoSTMalloc<8, const GrEffectStage*> stages(numStages);
bool usePathRendering = this->glCaps().pathRenderingSupport() && random.nextBool(); bool usePathRendering = this->glCaps().pathRenderingSupport() && random.nextBool();
GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType : GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType :
GrGpu::kDrawPoints_DrawType; GrGpu::kDrawPoints_DrawType;