Use shader based blending to clamp kPlus mode w/F16
Bug: skia:6173
Change-Id: I21042d484d9a7b3eee04aa3301d9793d00ad6908
Reviewed-on: https://skia-review.googlesource.com/48183
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index 267f43d..0e7dcf7 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -211,7 +211,8 @@
const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
bool hasMixedSamples,
- const GrCaps& caps) const {
+ const GrCaps& caps,
+ GrPixelConfigIsClamped dstIsClamped) const {
// We don't support inverting coverage with mixed samples. We don't expect to ever want this in
// the future, however we could at some point make this work using an inverted coverage
// modulation table. Note that an inverted table still won't work if there are coverage procs.
diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h
index 062d9dd..72d1b01 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -33,11 +33,13 @@
sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
bool hasMixedSamples,
- const GrCaps&) const override;
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
- const GrCaps&) const override {
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override {
return AnalysisProperties::kIgnoresInputColor;
}
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index 9891ee6..94d8ce2 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -215,11 +215,13 @@
sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
bool hasMixedSamples,
- const GrCaps&) const override;
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
- const GrCaps&) const override;
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override;
GR_DECLARE_XP_FACTORY_TEST
@@ -236,7 +238,8 @@
const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage coverage,
bool hasMixedSamples,
- const GrCaps& caps) const {
+ const GrCaps& caps,
+ GrPixelConfigIsClamped dstIsClamped) const {
SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
return sk_sp<GrXferProcessor>(new CustomXP(fMode, fHWBlendEquation));
@@ -246,7 +249,7 @@
GrXPFactory::AnalysisProperties CustomXPFactory::analysisProperties(
const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage& coverage,
- const GrCaps& caps) const {
+ const GrCaps& caps, GrPixelConfigIsClamped dstIsClamped) const {
/*
The general SVG blend equation is defined in the spec as follows:
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index ab0d835..a0beecd 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -78,7 +78,8 @@
const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
bool hasMixedSamples,
- const GrCaps& caps) const {
+ const GrCaps& caps,
+ GrPixelConfigIsClamped dstIsClamped) const {
return sk_sp<const GrXferProcessor>(new DisableColorXP);
}
diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h
index 5b4ebcf..f1ac32b 100644
--- a/src/gpu/effects/GrDisableColorXP.h
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -26,7 +26,8 @@
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
- const GrCaps&) const override {
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override {
return AnalysisProperties::kCompatibleWithAlphaAsCoverage |
AnalysisProperties::kIgnoresInputColor;
}
@@ -34,7 +35,8 @@
sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
bool hasMixedSamples,
- const GrCaps&) const override;
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override;
GR_DECLARE_XP_FACTORY_TEST
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index e6c7bf9..4f23bdc 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -760,7 +760,7 @@
sk_sp<const GrXferProcessor> GrPorterDuffXPFactory::makeXferProcessor(
const GrProcessorAnalysisColor& color, GrProcessorAnalysisCoverage coverage,
- bool hasMixedSamples, const GrCaps& caps) const {
+ bool hasMixedSamples, const GrCaps& caps, GrPixelConfigIsClamped dstIsClamped) const {
BlendFormula blendFormula;
bool isLCD = coverage == GrProcessorAnalysisCoverage::kLCD;
if (isLCD) {
@@ -779,8 +779,10 @@
hasMixedSamples, fBlendMode);
}
+ bool needsClamp = SkBlendMode::kPlus == fBlendMode;
if ((blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) ||
- (isLCD && (SkBlendMode::kSrcOver != fBlendMode /*|| !color.isOpaque()*/))) {
+ (isLCD && (SkBlendMode::kSrcOver != fBlendMode /*|| !color.isOpaque()*/)) ||
+ (needsClamp && (GrPixelConfigIsClamped::kNo == dstIsClamped))) {
return sk_sp<const GrXferProcessor>(new ShaderPDXferProcessor(hasMixedSamples, fBlendMode,
coverage));
}
@@ -789,7 +791,7 @@
static inline GrXPFactory::AnalysisProperties analysis_properties(
const GrProcessorAnalysisColor& color, const GrProcessorAnalysisCoverage& coverage,
- const GrCaps& caps, SkBlendMode mode) {
+ const GrCaps& caps, GrPixelConfigIsClamped dstIsClamped, SkBlendMode mode) {
using AnalysisProperties = GrXPFactory::AnalysisProperties;
AnalysisProperties props = AnalysisProperties::kNone;
bool hasCoverage = GrProcessorAnalysisCoverage::kNone != coverage;
@@ -836,6 +838,11 @@
}
}
+ bool needsClamp = SkBlendMode::kPlus == mode;
+ if (needsClamp && (GrPixelConfigIsClamped::kNo == dstIsClamped)) {
+ props |= AnalysisProperties::kReadsDstInShader;
+ }
+
if (!formula.modifiesDst() || !formula.usesInputColor()) {
props |= AnalysisProperties::kIgnoresInputColor;
}
@@ -851,8 +858,9 @@
GrXPFactory::AnalysisProperties GrPorterDuffXPFactory::analysisProperties(
const GrProcessorAnalysisColor& color,
const GrProcessorAnalysisCoverage& coverage,
- const GrCaps& caps) const {
- return analysis_properties(color, coverage, caps, fBlendMode);
+ const GrCaps& caps,
+ GrPixelConfigIsClamped dstIsClamped) const {
+ return analysis_properties(color, coverage, caps, dstIsClamped, fBlendMode);
}
GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
@@ -939,6 +947,7 @@
GrXPFactory::AnalysisProperties GrPorterDuffXPFactory::SrcOverAnalysisProperties(
const GrProcessorAnalysisColor& color,
const GrProcessorAnalysisCoverage& coverage,
- const GrCaps& caps) {
- return analysis_properties(color, coverage, caps, SkBlendMode::kSrcOver);
+ const GrCaps& caps,
+ GrPixelConfigIsClamped dstIsClamped) {
+ return analysis_properties(color, coverage, caps, dstIsClamped, SkBlendMode::kSrcOver);
}
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h
index 3599aef..37cd689 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -37,7 +37,8 @@
static AnalysisProperties SrcOverAnalysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
- const GrCaps&);
+ const GrCaps&,
+ GrPixelConfigIsClamped);
private:
constexpr GrPorterDuffXPFactory(SkBlendMode);
@@ -45,11 +46,13 @@
sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
bool hasMixedSamples,
- const GrCaps&) const override;
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
- const GrCaps&) const override;
+ const GrCaps&,
+ GrPixelConfigIsClamped) const override;
GR_DECLARE_XP_FACTORY_TEST
static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary);