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:
parent
ae444965c4
commit
c06482494d
@ -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();
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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();
|
||||||
|
@ -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,36 +112,6 @@ 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.
|
||||||
@ -148,13 +119,17 @@ private:
|
|||||||
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
|
||||||
|
@ -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());
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
case GrOptDrawState::kCoverage_SecondaryOutputType:
|
||||||
|
break;
|
||||||
|
case GrOptDrawState::kCoverageISA_SecondaryOutputType:
|
||||||
// Get (1-A) into coeff
|
// Get (1-A) into coeff
|
||||||
coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
|
coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
|
||||||
} else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput ==
|
break;
|
||||||
header.fCoverageOutput){
|
case GrOptDrawState::kCoverageISC_SecondaryOutputType:
|
||||||
// Get (1-RGBA) into coeff
|
// Get (1-RGBA) into coeff
|
||||||
coeff = GrGLSLExpr4(1) - inputColor;
|
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,14 +330,20 @@ 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:
|
||||||
|
break;
|
||||||
|
case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
|
||||||
|
{
|
||||||
|
// Tack on "+(1-coverage)dst onto the frag color.
|
||||||
GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
|
GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
|
||||||
|
|
||||||
GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(dstColor());
|
GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(dstColor());
|
||||||
|
|
||||||
fragColor = fragColor + dstContribution;
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user