Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3228)

Unified Diff: src/gpu/effects/GrPorterDuffXferProcessor.cpp

Issue 1313623002: Add support for blending of LCD for all blend modes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrTextContext.cpp ('k') | tests/GrPorterDuffTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/effects/GrPorterDuffXferProcessor.cpp
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 5f34f75854838a6d419eedcabf366b0dde7586c5..4c50e47ab9ae1d3845fb603a4f8d42c639a7cbff 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -31,6 +31,7 @@ public:
kNone_OutputType, //<! 0
kCoverage_OutputType, //<! inputCoverage
kModulate_OutputType, //<! inputColor * inputCoverage
+ kSAModulate_OutputType, //<! inputColor.a * inputCoverage
kISAModulate_OutputType, //<! (1 - inputColor.a) * inputCoverage
kISCModulate_OutputType, //<! (1 - inputColor) * inputCoverage
@@ -139,6 +140,15 @@ GR_MAKE_BITFIELD_OPS(BlendFormula::Properties);
kAdd_GrBlendEquation, SRC_COEFF, DST_COEFF)
/**
+ * Basic coeff formula similar to COEFF_FORMULA but we will make the src f*Sa. This is used in
+ * LCD dst-out.
+ */
+#define COEFF_FORMULA_SA_MODULATE(SRC_COEFF, DST_COEFF) \
+ INIT_BLEND_FORMULA(BlendFormula::kSAModulate_OutputType, \
+ BlendFormula::kNone_OutputType, \
+ kAdd_GrBlendEquation, SRC_COEFF, DST_COEFF)
+
+/**
* When the coeffs are (Zero, Zero), we clear the dst. This formula has its own macro so we can set
* the primary output type to none.
*/
@@ -289,6 +299,24 @@ static const BlendFormula gBlendTable[2][2][SkXfermode::kLastCoeffMode + 1] = {
/* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
}}};
+static const BlendFormula gLCDBlendTable[SkXfermode::kLastCoeffMode + 1] = {
+ /* clear */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
+ /* src */ COVERAGE_FORMULA(BlendFormula::kCoverage_OutputType, kOne_GrBlendCoeff),
+ /* dst */ NO_DST_WRITE_FORMULA,
+ /* src-over */ COVERAGE_FORMULA(BlendFormula::kSAModulate_OutputType, kOne_GrBlendCoeff),
+ /* dst-over */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-in */ COVERAGE_FORMULA(BlendFormula::kCoverage_OutputType, kDA_GrBlendCoeff),
+ /* dst-in */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISAModulate_OutputType),
+ /* src-out */ COVERAGE_FORMULA(BlendFormula::kCoverage_OutputType, kIDA_GrBlendCoeff),
+ /* dst-out */ COEFF_FORMULA_SA_MODULATE( kZero_GrBlendCoeff, kISC_GrBlendCoeff),
+ /* src-atop */ COVERAGE_FORMULA(BlendFormula::kSAModulate_OutputType, kDA_GrBlendCoeff),
+ /* dst-atop */ COVERAGE_FORMULA(BlendFormula::kISAModulate_OutputType, kIDA_GrBlendCoeff),
+ /* xor */ COVERAGE_FORMULA(BlendFormula::kSAModulate_OutputType, kIDA_GrBlendCoeff),
+ /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_OutputType),
+ /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
+};
+
static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
bool hasMixedSamples,
@@ -300,6 +328,14 @@ static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI,
return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][xfermode];
}
+static BlendFormula get_lcd_blend_formula(const GrProcOptInfo& coveragePOI,
+ SkXfermode::Mode xfermode) {
+ SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode);
+ SkASSERT(coveragePOI.isFourChannelOutput());
+
+ return gLCDBlendTable[xfermode];
+}
+
///////////////////////////////////////////////////////////////////////////////
class PorterDuffXferProcessor : public GrXferProcessor {
@@ -363,6 +399,13 @@ static void append_color_output(const PorterDuffXferProcessor& xp, GrGLXPFragmen
fsBuilder->codeAppendf("%s = %s;", output, inColor);
}
break;
+ case BlendFormula::kSAModulate_OutputType:
+ if (xp.readsCoverage()) {
+ fsBuilder->codeAppendf("%s = %s.a * %s;", output, inColor, inCoverage);
+ } else {
+ fsBuilder->codeAppendf("%s = %s;", output, inColor);
+ }
+ break;
case BlendFormula::kISAModulate_OutputType:
if (xp.readsCoverage()) {
fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColor, inCoverage);
@@ -444,7 +487,9 @@ PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI,
if (coveragePOI.isSolidWhite()) {
optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag;
}
- if (colorPOI.allStagesMultiplyInput() && fBlendFormula.canTweakAlphaForCoverage()) {
+ if (colorPOI.allStagesMultiplyInput() &&
+ fBlendFormula.canTweakAlphaForCoverage() &&
+ !coveragePOI.isFourChannelOutput()) {
optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag;
}
}
@@ -579,7 +624,6 @@ public:
private:
void emitOutputsForBlendState(const EmitArgs& args) override {
GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
-
fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
args.fInputCoverage);
}
@@ -684,12 +728,18 @@ GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& covPOI,
bool hasMixedSamples,
const DstTexture* dstTexture) const {
+ BlendFormula blendFormula;
if (covPOI.isFourChannelOutput()) {
- SkASSERT(!dstTexture || !dstTexture->texture());
- return PDLCDXferProcessor::Create(fXfermode, colorPOI);
+ if (SkXfermode::kSrcOver_Mode == fXfermode &&
+ kRGBA_GrColorComponentFlags == colorPOI.validFlags()) {
+ SkASSERT(!dstTexture || !dstTexture->texture());
+ return PDLCDXferProcessor::Create(fXfermode, colorPOI);
+ }
+ blendFormula = get_lcd_blend_formula(covPOI, fXfermode);
+ } else {
+ blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode);
}
- BlendFormula blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode);
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode);
}
@@ -698,15 +748,6 @@ GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
return new PorterDuffXferProcessor(blendFormula);
}
-bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
- uint32_t knownColorFlags) const {
- if (SkXfermode::kSrcOver_Mode == fXfermode &&
- kRGBA_GrColorComponentFlags == knownColorFlags) {
- return true;
- }
- return false;
-}
-
void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
InvariantBlendedColor* blendedColor) const {
// Find the blended color info based on the formula that does not have coverage.
@@ -745,8 +786,16 @@ bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps,
if (caps.shaderCaps()->dualSourceBlendingSupport()) {
return false;
}
+
+ // When we have four channel coverage we always need to read the dst in order to correctly
+ // blend. The one exception is when we are using srcover mode and we know the input color into
+ // the XP.
if (covPOI.isFourChannelOutput()) {
- return false; // The LCD XP will abort rather than doing a dst read.
+ if (SkXfermode::kSrcOver_Mode == fXfermode &&
+ kRGBA_GrColorComponentFlags == colorPOI.validFlags()) {
+ return false;
+ }
+ return get_lcd_blend_formula(covPOI, fXfermode).hasSecondaryOutput();
}
// We fallback on the shader XP when the blend formula would use dual source blending but we
// don't have support for it.
« no previous file with comments | « src/gpu/GrTextContext.cpp ('k') | tests/GrPorterDuffTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698