Revert of Use dst copies in porter duffer XP to correctly render certain blends. (patchset #4 id:60001 of https://codereview.chromium.org/914003003/)
Reason for revert: Failing GLProgramTest passing in stupid coeffs Original issue's description: > Use dst copies in porter duffer XP to correctly render certain blends. > > BUG=skia: > > Committed: https://skia.googlesource.com/skia/+/997c6358d94e188b1a7b89a4f86e24cbe0f5a164 TBR=bsalomon@google.com,joshualitt@google.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/923153003
This commit is contained in:
parent
997c6358d9
commit
2b816bacc0
@ -261,16 +261,14 @@ protected:
|
||||
uint32_t fClassID;
|
||||
|
||||
private:
|
||||
virtual GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
virtual GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const = 0;
|
||||
/**
|
||||
* Returns true if the XP generated by this factory will explicitly read dst in the fragment
|
||||
* shader.
|
||||
*/
|
||||
virtual bool willReadDstColor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
virtual bool willReadDstColor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const = 0;
|
||||
|
||||
virtual bool onIsEqual(const GrXPFactory&) const = 0;
|
||||
|
@ -28,10 +28,8 @@ public:
|
||||
|
||||
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE;
|
||||
|
||||
bool canApplyCoverage(const GrProcOptInfo& /*colorPOI*/,
|
||||
const GrProcOptInfo& /*coveragePOI*/) const SK_OVERRIDE {
|
||||
return true;
|
||||
}
|
||||
bool canApplyCoverage(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
|
||||
|
||||
bool canTweakAlphaForCoverage() const SK_OVERRIDE;
|
||||
|
||||
@ -41,13 +39,11 @@ public:
|
||||
private:
|
||||
GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
|
||||
|
||||
bool willReadDstColor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
bool willReadDstColor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
|
||||
|
||||
bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
|
||||
|
@ -304,12 +304,11 @@ GrArithmeticXPFactory::GrArithmeticXPFactory(float k1, float k2, float k3, float
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrArithmeticXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrArithmeticXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const {
|
||||
return ArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor, dstCopy,
|
||||
this->willReadDstColor(caps, colorPOI, coveragePOI));
|
||||
this->willReadDstColor(colorPOI, coveragePOI));
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,13 +96,11 @@ public:
|
||||
private:
|
||||
GrArithmeticXPFactory(float k1, float k2, float k3, float k4, bool enforcePMColor);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
|
||||
|
||||
bool willReadDstColor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
bool willReadDstColor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
|
||||
return true;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrDeviceCoordTexture* dstCopy,
|
||||
const GrDrawTargetCaps& caps) const {
|
||||
#ifdef SK_DEBUG
|
||||
if (this->willReadDstColor(caps, colorPOI, coveragePOI)) {
|
||||
if (this->willReadDstColor(colorPOI, coveragePOI)) {
|
||||
if (!caps.dstReadInShaderSupport()) {
|
||||
SkASSERT(dstCopy && dstCopy->texture());
|
||||
} else {
|
||||
@ -46,13 +46,14 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
}
|
||||
} else {
|
||||
SkASSERT(!dstCopy || !dstCopy->texture());
|
||||
|
||||
}
|
||||
#endif
|
||||
return this->onCreateXferProcessor(caps, colorPOI, coveragePOI, dstCopy);
|
||||
return this->onCreateXferProcessor(colorPOI, coveragePOI, dstCopy);
|
||||
}
|
||||
|
||||
bool GrXPFactory::willNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const {
|
||||
return (this->willReadDstColor(caps, colorPOI, coveragePOI) && !caps.dstReadInShaderSupport());
|
||||
return (this->willReadDstColor(colorPOI, coveragePOI) && !caps.dstReadInShaderSupport());
|
||||
}
|
||||
|
||||
|
@ -228,8 +228,7 @@ GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invert
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& covPOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const {
|
||||
return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
|
||||
|
@ -35,13 +35,11 @@ public:
|
||||
private:
|
||||
GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
|
||||
|
||||
bool willReadDstColor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
bool willReadDstColor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
|
||||
return false;
|
||||
}
|
||||
|
@ -608,11 +608,10 @@ GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode)
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrCustomXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrCustomXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const {
|
||||
return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(caps, colorPOI, coveragePOI));
|
||||
return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(colorPOI, coveragePOI));
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,13 +77,11 @@ public:
|
||||
GrXPFactory::InvariantOutput*) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
|
||||
|
||||
bool willReadDstColor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
bool willReadDstColor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
|
||||
return true;
|
||||
}
|
||||
|
@ -100,8 +100,7 @@ GrDisableColorXPFactory::GrDisableColorXPFactory() {
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrDisableColorXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrDisableColorXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& covPOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const {
|
||||
return DisableColorXP::Create();
|
||||
|
@ -39,13 +39,11 @@ public:
|
||||
private:
|
||||
GrDisableColorXPFactory();
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE;
|
||||
|
||||
bool willReadDstColor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
bool willReadDstColor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
|
||||
return false;
|
||||
}
|
||||
|
@ -59,10 +59,6 @@ public:
|
||||
kCoverage_PrimaryOutputType,
|
||||
// Modulate color and coverage, write result as the color output.
|
||||
kModulate_PrimaryOutputType,
|
||||
// Custom Porter-Duff output, used for when we explictly are reading the dst and blending
|
||||
// in the shader. Secondary Output must be none if you use this. The custom blend uses the
|
||||
// equation: cov * (coeffS * S + coeffD * D) + (1 - cov) * D
|
||||
kCustom_PrimaryOutputType
|
||||
};
|
||||
|
||||
enum SecondaryOutputType {
|
||||
@ -91,19 +87,11 @@ public:
|
||||
const GrDrawTargetCaps& caps) SK_OVERRIDE;
|
||||
|
||||
void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
|
||||
if (!this->willReadDstColor()) {
|
||||
blendInfo->fSrcBlend = fSrcBlend;
|
||||
blendInfo->fDstBlend = fDstBlend;
|
||||
} else {
|
||||
blendInfo->fSrcBlend = kOne_GrBlendCoeff;
|
||||
blendInfo->fDstBlend = kZero_GrBlendCoeff;
|
||||
}
|
||||
blendInfo->fSrcBlend = fSrcBlend;
|
||||
blendInfo->fDstBlend = fDstBlend;
|
||||
blendInfo->fBlendConstant = fBlendConstant;
|
||||
}
|
||||
|
||||
GrBlendCoeff getSrcBlend() const { return fSrcBlend; }
|
||||
GrBlendCoeff getDstBlend() const { return fDstBlend; }
|
||||
|
||||
private:
|
||||
PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant,
|
||||
const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
|
||||
@ -140,50 +128,6 @@ private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool append_porterduff_term(GrGLFPFragmentBuilder* fsBuilder, GrBlendCoeff coeff,
|
||||
const char* colorName, const char* srcColorName,
|
||||
const char* dstColorName, bool hasPrevious) {
|
||||
if (kZero_GrBlendCoeff == coeff) {
|
||||
return hasPrevious;
|
||||
} else {
|
||||
if (hasPrevious) {
|
||||
fsBuilder->codeAppend(" + ");
|
||||
}
|
||||
fsBuilder->codeAppendf("%s", colorName);
|
||||
switch (coeff) {
|
||||
case kOne_GrBlendCoeff:
|
||||
break;
|
||||
case kSC_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * %s", srcColorName);
|
||||
break;
|
||||
case kISC_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * (vec4(1.0) - %s)", srcColorName);
|
||||
break;
|
||||
case kDC_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * %s", dstColorName);
|
||||
break;
|
||||
case kIDC_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * (vec4(1.0) - %s)", dstColorName);
|
||||
break;
|
||||
case kSA_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * %s.a", srcColorName);
|
||||
break;
|
||||
case kISA_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * (1.0 - %s.a)", srcColorName);
|
||||
break;
|
||||
case kDA_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * %s.a", dstColorName);
|
||||
break;
|
||||
case kIDA_GrBlendCoeff:
|
||||
fsBuilder->codeAppendf(" * (1.0 - %s.a)", dstColorName);
|
||||
break;
|
||||
default:
|
||||
SkFAIL("Unsupported Blend Coeff");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class GLPorterDuffXferProcessor : public GrGLXferProcessor {
|
||||
public:
|
||||
GLPorterDuffXferProcessor(const GrProcessor&) {}
|
||||
@ -195,24 +139,16 @@ public:
|
||||
const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcessor>();
|
||||
b->add32(xp.primaryOutputType());
|
||||
b->add32(xp.secondaryOutputType());
|
||||
if (xp.willReadDstColor()) {
|
||||
b->add32(xp.getSrcBlend());
|
||||
b->add32(xp.getDstBlend());
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
|
||||
const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcessor>();
|
||||
GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
if (PorterDuffXferProcessor::kCustom_PrimaryOutputType != xp.primaryOutputType()) {
|
||||
SkASSERT(!xp.willReadDstColor());
|
||||
if (xp.hasSecondaryOutput()) {
|
||||
switch(xp.secondaryOutputType()) {
|
||||
case PorterDuffXferProcessor::kNone_SecondaryOutputType:
|
||||
break;
|
||||
case PorterDuffXferProcessor::kCoverage_SecondaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary,
|
||||
args.fInputCoverage);
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
|
||||
break;
|
||||
case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
|
||||
@ -227,43 +163,24 @@ private:
|
||||
default:
|
||||
SkFAIL("Unexpected Secondary Output");
|
||||
}
|
||||
|
||||
switch (xp.primaryOutputType()) {
|
||||
case PorterDuffXferProcessor::kNone_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary);
|
||||
break;
|
||||
case PorterDuffXferProcessor::kColor_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputColor);
|
||||
break;
|
||||
case PorterDuffXferProcessor::kCoverage_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
break;
|
||||
case PorterDuffXferProcessor::kModulate_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
|
||||
args.fInputCoverage);
|
||||
break;
|
||||
default:
|
||||
SkFAIL("Unexpected Primary Output");
|
||||
}
|
||||
} else {
|
||||
SkASSERT(xp.willReadDstColor());
|
||||
|
||||
const char* dstColor = fsBuilder->dstColor();
|
||||
|
||||
fsBuilder->codeAppend("vec4 colorBlend =");
|
||||
// append src blend
|
||||
bool didAppend = append_porterduff_term(fsBuilder, xp.getSrcBlend(),
|
||||
args.fInputColor, args.fInputColor,
|
||||
dstColor, false);
|
||||
// append dst blend
|
||||
SkAssertResult(append_porterduff_term(fsBuilder, xp.getDstBlend(),
|
||||
dstColor, args.fInputColor,
|
||||
dstColor, didAppend));
|
||||
fsBuilder->codeAppend(";");
|
||||
|
||||
fsBuilder->codeAppendf("%s = %s * colorBlend + (vec4(1.0) - %s) * %s;",
|
||||
args.fOutputPrimary, args.fInputCoverage, args.fInputCoverage,
|
||||
dstColor);
|
||||
}
|
||||
|
||||
switch (xp.primaryOutputType()) {
|
||||
case PorterDuffXferProcessor::kNone_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary);
|
||||
break;
|
||||
case PorterDuffXferProcessor::kColor_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputColor);
|
||||
break;
|
||||
case PorterDuffXferProcessor::kCoverage_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
break;
|
||||
case PorterDuffXferProcessor::kModulate_PrimaryOutputType:
|
||||
fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
|
||||
args.fInputCoverage);
|
||||
break;
|
||||
default:
|
||||
SkFAIL("Unexpected Primary Output");
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,8 +196,7 @@ PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend,
|
||||
GrColor constant,
|
||||
const GrDeviceCoordTexture* dstCopy,
|
||||
bool willReadDstColor)
|
||||
: INHERITED(dstCopy, willReadDstColor)
|
||||
, fSrcBlend(srcBlend)
|
||||
: fSrcBlend(srcBlend)
|
||||
, fDstBlend(dstBlend)
|
||||
, fBlendConstant(constant)
|
||||
, fPrimaryOutputType(kModulate_PrimaryOutputType)
|
||||
@ -328,11 +244,6 @@ PorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
|
||||
void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags,
|
||||
const GrDrawTargetCaps& caps,
|
||||
bool hasSolidCoverage) {
|
||||
if (this->willReadDstColor()) {
|
||||
fPrimaryOutputType = kCustom_PrimaryOutputType;
|
||||
return;
|
||||
}
|
||||
|
||||
if (optFlags & kIgnoreColor_OptFlag) {
|
||||
if (optFlags & kIgnoreCoverage_OptFlag) {
|
||||
fPrimaryOutputType = kNone_PrimaryOutputType;
|
||||
@ -373,12 +284,11 @@ GrXferProcessor::OptFlags
|
||||
PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI,
|
||||
bool doesStencilWrite) {
|
||||
if (this->willReadDstColor()) {
|
||||
return GrXferProcessor::kNone_Opt;
|
||||
}
|
||||
bool srcAIsOne;
|
||||
bool hasCoverage;
|
||||
|
||||
bool srcAIsOne = colorPOI.isOpaque();
|
||||
bool hasCoverage = !coveragePOI.isSolidWhite();
|
||||
srcAIsOne = colorPOI.isOpaque();
|
||||
hasCoverage = !coveragePOI.isSolidWhite();
|
||||
|
||||
bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend ||
|
||||
(kSA_GrBlendCoeff == fDstBlend && srcAIsOne);
|
||||
@ -543,20 +453,19 @@ GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) {
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& covPOI,
|
||||
const GrDeviceCoordTexture* dstCopy) const {
|
||||
if (!covPOI.isFourChannelOutput()) {
|
||||
return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy,
|
||||
this->willReadDstColor(caps, colorPOI, covPOI));
|
||||
this->willReadDstColor(colorPOI, covPOI));
|
||||
} else {
|
||||
if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) {
|
||||
SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags());
|
||||
GrColor blendConstant = GrUnPreMulColor(colorPOI.color());
|
||||
return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff,
|
||||
blendConstant, dstCopy,
|
||||
this->willReadDstColor(caps, colorPOI, covPOI));
|
||||
this->willReadDstColor(colorPOI, covPOI));
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -572,6 +481,39 @@ bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrPorterDuffXPFactory::canApplyCoverage(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const {
|
||||
bool srcAIsOne = colorPOI.isOpaque();
|
||||
|
||||
bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstCoeff ||
|
||||
(kSA_GrBlendCoeff == fDstCoeff && srcAIsOne);
|
||||
bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstCoeff ||
|
||||
(kISA_GrBlendCoeff == fDstCoeff && srcAIsOne);
|
||||
|
||||
if ((kZero_GrBlendCoeff == fSrcCoeff && dstCoeffIsOne)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if we don't have coverage we can check whether the dst
|
||||
// has to read at all.
|
||||
// check whether coverage can be safely rolled into alpha
|
||||
// of if we can skip color computation and just emit coverage
|
||||
if (this->canTweakAlphaForCoverage()) {
|
||||
return true;
|
||||
}
|
||||
if (dstCoeffIsZero) {
|
||||
if (kZero_GrBlendCoeff == fSrcCoeff) {
|
||||
return true;
|
||||
} else if (srcAIsOne) {
|
||||
return true;
|
||||
}
|
||||
} else if (dstCoeffIsOne) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const {
|
||||
return can_tweak_alpha_for_coverage(fDstCoeff);
|
||||
}
|
||||
@ -645,37 +587,9 @@ void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
|
||||
output->fWillBlendWithDst = false;
|
||||
}
|
||||
|
||||
bool GrPorterDuffXPFactory::willReadDstColor(const GrDrawTargetCaps& caps,
|
||||
const GrProcOptInfo& colorPOI,
|
||||
bool GrPorterDuffXPFactory::willReadDstColor(const GrProcOptInfo& colorPOI,
|
||||
const GrProcOptInfo& coveragePOI) const {
|
||||
// We can always blend correctly if we have dual source blending.
|
||||
if (caps.dualSourceBlendingSupport()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->canTweakAlphaForCoverage()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool srcAIsOne = colorPOI.isOpaque();
|
||||
|
||||
if (kZero_GrBlendCoeff == fDstCoeff) {
|
||||
if (kZero_GrBlendCoeff == fSrcCoeff || srcAIsOne) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Reduces to: coeffS * (Cov*S) + D
|
||||
if (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can always blend correctly if we have solid coverage.
|
||||
if (coveragePOI.isSolidWhite()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
|
||||
|
Loading…
Reference in New Issue
Block a user