constexprify GrBlend.h and GrPorterDuffXferProcessor.cpp
Also remove some unused functions from GrBlend.h and related unit test.
Bug: skia:
Change-Id: Id8ad0057a02f65a9e19dc75e4b88709a762f4139
Reviewed-on: https://skia-review.googlesource.com/12623
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/gn/tests.gni b/gn/tests.gni
index 196c86d..be99a9e 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -89,7 +89,6 @@
"$_tests/GrContextAbandonTest.cpp",
"$_tests/GrContextFactoryTest.cpp",
"$_tests/GrDrawTargetTest.cpp",
- "$_tests/GrGetCoeffBlendKnownComponentsTest.cpp",
"$_tests/GrGLSLPrettyPrintTest.cpp",
"$_tests/GrMemoryPoolTest.cpp",
"$_tests/GrPorterDuffTest.cpp",
diff --git a/include/gpu/GrBlend.h b/include/gpu/GrBlend.h
index 97a5166..30b0b9b 100644
--- a/include/gpu/GrBlend.h
+++ b/include/gpu/GrBlend.h
@@ -73,121 +73,38 @@
static const int kGrBlendCoeffCnt = kLast_GrBlendCoeff + 1;
-/**
- * Given a known blend equation in the form of srcCoeff * srcColor + dstCoeff * dstColor where
- * there may be partial knowledge of the srcColor and dstColor component values, determine what
- * components of the blended output color are known. Coeffs must not refer to the constant or
- * secondary src color.
- */
-void GrGetCoeffBlendKnownComponents(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff,
- GrColor srcColor,
- GrColorComponentFlags srcColorFlags,
- GrColor dstColor,
- GrColorComponentFlags dstColorFlags,
- GrColor* outColor,
- GrColorComponentFlags* outFlags);
-
-template<GrBlendCoeff Coeff>
-struct GrTBlendCoeffRefsSrc : skstd::bool_constant<kSC_GrBlendCoeff == Coeff ||
- kISC_GrBlendCoeff == Coeff ||
- kSA_GrBlendCoeff == Coeff ||
- kISA_GrBlendCoeff == Coeff> {};
-
-#define GR_BLEND_COEFF_REFS_SRC(COEFF) \
- GrTBlendCoeffRefsSrc<COEFF>::value
-
-inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) {
- switch (coeff) {
- case kSC_GrBlendCoeff:
- case kISC_GrBlendCoeff:
- case kSA_GrBlendCoeff:
- case kISA_GrBlendCoeff:
- return true;
- default:
- return false;
- }
+static constexpr bool GrBlendCoeffRefsSrc(const GrBlendCoeff coeff) {
+ return kSC_GrBlendCoeff == coeff || kISC_GrBlendCoeff == coeff || kSA_GrBlendCoeff == coeff ||
+ kISA_GrBlendCoeff == coeff;
}
-template<GrBlendCoeff Coeff>
-struct GrTBlendCoeffRefsDst : skstd::bool_constant<kDC_GrBlendCoeff == Coeff ||
- kIDC_GrBlendCoeff == Coeff ||
- kDA_GrBlendCoeff == Coeff ||
- kIDA_GrBlendCoeff == Coeff> {};
-
-#define GR_BLEND_COEFF_REFS_DST(COEFF) \
- GrTBlendCoeffRefsDst<COEFF>::value
-
-inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) {
- switch (coeff) {
- case kDC_GrBlendCoeff:
- case kIDC_GrBlendCoeff:
- case kDA_GrBlendCoeff:
- case kIDA_GrBlendCoeff:
- return true;
- default:
- return false;
- }
+static constexpr bool GrBlendCoeffRefsDst(const GrBlendCoeff coeff) {
+ return kDC_GrBlendCoeff == coeff || kIDC_GrBlendCoeff == coeff || kDA_GrBlendCoeff == coeff ||
+ kIDA_GrBlendCoeff == coeff;
}
-
-template<GrBlendCoeff Coeff>
-struct GrTBlendCoeffRefsSrc2 : skstd::bool_constant<kS2C_GrBlendCoeff == Coeff ||
- kIS2C_GrBlendCoeff == Coeff ||
- kS2A_GrBlendCoeff == Coeff ||
- kIS2A_GrBlendCoeff == Coeff> {};
-
-#define GR_BLEND_COEFF_REFS_SRC2(COEFF) \
- GrTBlendCoeffRefsSrc2<COEFF>::value
-
-inline bool GrBlendCoeffRefsSrc2(GrBlendCoeff coeff) {
- switch (coeff) {
- case kS2C_GrBlendCoeff:
- case kIS2C_GrBlendCoeff:
- case kS2A_GrBlendCoeff:
- case kIS2A_GrBlendCoeff:
- return true;
- default:
- return false;
- }
+static constexpr bool GrBlendCoeffRefsSrc2(const GrBlendCoeff coeff) {
+ return kS2C_GrBlendCoeff == coeff || kIS2C_GrBlendCoeff == coeff ||
+ kS2A_GrBlendCoeff == coeff || kIS2A_GrBlendCoeff == coeff;
}
+static constexpr bool GrBlendCoeffsUseSrcColor(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ return kZero_GrBlendCoeff != srcCoeff || GrBlendCoeffRefsSrc(dstCoeff);
+}
-template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
-struct GrTBlendCoeffsUseSrcColor : skstd::bool_constant<kZero_GrBlendCoeff != SrcCoeff ||
- GR_BLEND_COEFF_REFS_SRC(DstCoeff)> {};
+static constexpr bool GrBlendCoeffsUseDstColor(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ return GrBlendCoeffRefsDst(srcCoeff) || kZero_GrBlendCoeff != dstCoeff;
+}
-#define GR_BLEND_COEFFS_USE_SRC_COLOR(SRC_COEFF, DST_COEFF) \
- GrTBlendCoeffsUseSrcColor<SRC_COEFF, DST_COEFF>::value
-
-
-template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
-struct GrTBlendCoeffsUseDstColor : skstd::bool_constant<GR_BLEND_COEFF_REFS_DST(SrcCoeff) ||
- kZero_GrBlendCoeff != DstCoeff> {};
-
-#define GR_BLEND_COEFFS_USE_DST_COLOR(SRC_COEFF, DST_COEFF) \
- GrTBlendCoeffsUseDstColor<SRC_COEFF, DST_COEFF>::value
-
-
-template<GrBlendEquation Equation>
-struct GrTBlendEquationIsAdvanced : skstd::bool_constant<Equation >= kFirstAdvancedGrBlendEquation> {};
-
-#define GR_BLEND_EQUATION_IS_ADVANCED(EQUATION) \
- GrTBlendEquationIsAdvanced<EQUATION>::value
-
-inline bool GrBlendEquationIsAdvanced(GrBlendEquation equation) {
+static constexpr bool GrBlendEquationIsAdvanced(GrBlendEquation equation) {
return equation >= kFirstAdvancedGrBlendEquation;
}
-
-template<GrBlendEquation BlendEquation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
-struct GrTBlendModifiesDst : skstd::bool_constant<
- (kAdd_GrBlendEquation != BlendEquation && kReverseSubtract_GrBlendEquation != BlendEquation) ||
- kZero_GrBlendCoeff != SrcCoeff ||
- kOne_GrBlendCoeff != DstCoeff> {};
-
-#define GR_BLEND_MODIFIES_DST(EQUATION, SRC_COEFF, DST_COEFF) \
- GrTBlendModifiesDst<EQUATION, SRC_COEFF, DST_COEFF>::value
-
+static constexpr bool GrBlendModifiesDst(GrBlendEquation equation, GrBlendCoeff srcCoeff,
+ GrBlendCoeff dstCoeff) {
+ return (kAdd_GrBlendEquation != equation && kReverseSubtract_GrBlendEquation != equation) ||
+ kZero_GrBlendCoeff != srcCoeff || kOne_GrBlendCoeff != dstCoeff;
+}
/**
* Advanced blend equations can always tweak alpha for coverage. (See GrCustomXfermode.cpp)
@@ -216,17 +133,15 @@
* Moreover, if the blend doesn't modify the dst at all then it is ok to arbitrarily modify the src
* color so folding in coverage is allowed.
*/
-template<GrBlendEquation Equation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
-struct GrTBlendCanTweakAlphaForCoverage : skstd::bool_constant<
- GR_BLEND_EQUATION_IS_ADVANCED(Equation) ||
- ((kAdd_GrBlendEquation == Equation || kReverseSubtract_GrBlendEquation == Equation) &&
- !GR_BLEND_COEFF_REFS_SRC(SrcCoeff) &&
- (kOne_GrBlendCoeff == DstCoeff ||
- kISC_GrBlendCoeff == DstCoeff ||
- kISA_GrBlendCoeff == DstCoeff)) ||
- !GrTBlendModifiesDst<Equation, SrcCoeff, DstCoeff>::value> {};
-
-#define GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(EQUATION, SRC_COEFF, DST_COEFF) \
- GrTBlendCanTweakAlphaForCoverage<EQUATION, SRC_COEFF, DST_COEFF>::value
+static constexpr bool GrBlendAllowsCoverageAsAlpha(GrBlendEquation equation,
+ GrBlendCoeff srcCoeff,
+ GrBlendCoeff dstCoeff) {
+ return GrBlendEquationIsAdvanced(equation) ||
+ !GrBlendModifiesDst(equation, srcCoeff, dstCoeff) ||
+ ((kAdd_GrBlendEquation == equation || kReverseSubtract_GrBlendEquation == equation) &&
+ !GrBlendCoeffRefsSrc(srcCoeff) &&
+ (kOne_GrBlendCoeff == dstCoeff || kISC_GrBlendCoeff == dstCoeff ||
+ kISA_GrBlendCoeff == dstCoeff));
+}
#endif
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index b4d917a..e3548ad 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -23,7 +23,7 @@
/**
* Wraps the shader outputs and HW blend state that comprise a Porter Duff blend mode with coverage.
*/
-struct BlendFormula {
+class BlendFormula {
public:
/**
* Values the shader can write to primary and secondary outputs. These must all be modulated by
@@ -40,6 +40,76 @@
kLast_OutputType = kISCModulate_OutputType
};
+ BlendFormula() = default;
+
+ constexpr BlendFormula(OutputType primaryOut, OutputType secondaryOut, GrBlendEquation equation,
+ GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff)
+ : fPrimaryOutputType(primaryOut)
+ , fSecondaryOutputType(secondaryOut)
+ , fBlendEquation(equation)
+ , fSrcCoeff(srcCoeff)
+ , fDstCoeff(dstCoeff)
+ , fProps(GetProperties(primaryOut, secondaryOut, equation, srcCoeff, dstCoeff)) {}
+
+ BlendFormula& operator=(const BlendFormula& other) {
+ SkDEBUGCODE(other.validatePreoptimized());
+ fData = other.fData;
+ return *this;
+ }
+
+ bool operator==(const BlendFormula& other) const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ SkDEBUGCODE(other.validatePreoptimized());
+ return fData == other.fData;
+ }
+
+ bool hasSecondaryOutput() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return kNone_OutputType != fSecondaryOutputType;
+ }
+ bool modifiesDst() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return SkToBool(fProps & kModifiesDst_Property);
+ }
+ bool usesDstColor() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return SkToBool(fProps & kUsesDstColor_Property);
+ }
+ bool usesInputColor() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return SkToBool(fProps & kUsesInputColor_Property);
+ }
+ bool canTweakAlphaForCoverage() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return SkToBool(fProps & kCanTweakAlphaForCoverage_Property);
+ }
+
+ GrBlendEquation equation() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return fBlendEquation;
+ }
+
+ GrBlendCoeff srcCoeff() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return fSrcCoeff;
+ }
+
+ GrBlendCoeff dstCoeff() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return fDstCoeff;
+ }
+
+ OutputType primaryOutput() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return fPrimaryOutputType;
+ }
+
+ OutputType secondaryOutput() const {
+ SkDEBUGCODE(this->validatePreoptimized());
+ return fSecondaryOutputType;
+ }
+
+private:
enum Properties {
kModifiesDst_Property = 1,
kUsesDstColor_Property = 1 << 1,
@@ -48,55 +118,30 @@
kLast_Property = kCanTweakAlphaForCoverage_Property
};
+ GR_DECL_BITFIELD_OPS_FRIENDS(Properties)
- BlendFormula& operator =(const BlendFormula& other) {
- fData = other.fData;
- return *this;
+#ifdef SK_DEBUG
+ void validatePreoptimized() const {
+ // The provided formula should already be optimized before a BlendFormula is constructed.
+ // Preferably these asserts would be done statically in the constexpr constructor, but this
+ // is not allowed in C++11.
+ SkASSERT((kNone_OutputType == fPrimaryOutputType) ==
+ !GrBlendCoeffsUseSrcColor(fSrcCoeff, fDstCoeff));
+ SkASSERT(!GrBlendCoeffRefsSrc2(fSrcCoeff));
+ SkASSERT((kNone_OutputType == fSecondaryOutputType) == !GrBlendCoeffRefsSrc2(fDstCoeff));
+ SkASSERT(fPrimaryOutputType != fSecondaryOutputType ||
+ kNone_OutputType == fPrimaryOutputType);
+ SkASSERT(kNone_OutputType != fPrimaryOutputType ||
+ kNone_OutputType == fSecondaryOutputType);
}
-
- bool operator ==(const BlendFormula& other) const {
- return fData == other.fData;
- }
-
- bool hasSecondaryOutput() const { return kNone_OutputType != fSecondaryOutputType; }
- bool modifiesDst() const { return SkToBool(fProps & kModifiesDst_Property); }
- bool usesDstColor() const { return SkToBool(fProps & kUsesDstColor_Property); }
- bool usesInputColor() const { return SkToBool(fProps & kUsesInputColor_Property); }
- bool canTweakAlphaForCoverage() const {
- return SkToBool(fProps & kCanTweakAlphaForCoverage_Property);
- }
+#endif
/**
- * Deduce the properties of a compile-time constant BlendFormula.
+ * Deduce the properties of a BlendFormula.
*/
- template<OutputType PrimaryOut, OutputType SecondaryOut,
- GrBlendEquation BlendEquation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
- struct get_properties : std::integral_constant<Properties, static_cast<Properties>(
-
- (GR_BLEND_MODIFIES_DST(BlendEquation, SrcCoeff, DstCoeff) ?
- kModifiesDst_Property : 0) |
-
- (GR_BLEND_COEFFS_USE_DST_COLOR(SrcCoeff, DstCoeff) ?
- kUsesDstColor_Property : 0) |
-
- ((PrimaryOut >= kModulate_OutputType && GR_BLEND_COEFFS_USE_SRC_COLOR(SrcCoeff,DstCoeff)) ||
- (SecondaryOut >= kModulate_OutputType && GR_BLEND_COEFF_REFS_SRC2(DstCoeff)) ?
- kUsesInputColor_Property : 0) | // We assert later that SrcCoeff doesn't ref src2.
-
- ((kModulate_OutputType == PrimaryOut || kNone_OutputType == PrimaryOut) &&
- kNone_OutputType == SecondaryOut &&
- GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(BlendEquation, SrcCoeff, DstCoeff) ?
- kCanTweakAlphaForCoverage_Property : 0))> {
-
- // The provided formula should already be optimized.
- GR_STATIC_ASSERT((kNone_OutputType == PrimaryOut) ==
- !GR_BLEND_COEFFS_USE_SRC_COLOR(SrcCoeff, DstCoeff));
- GR_STATIC_ASSERT(!GR_BLEND_COEFF_REFS_SRC2(SrcCoeff));
- GR_STATIC_ASSERT((kNone_OutputType == SecondaryOut) ==
- !GR_BLEND_COEFF_REFS_SRC2(DstCoeff));
- GR_STATIC_ASSERT(PrimaryOut != SecondaryOut || kNone_OutputType == PrimaryOut);
- GR_STATIC_ASSERT(kNone_OutputType != PrimaryOut || kNone_OutputType == SecondaryOut);
- };
+ static constexpr Properties GetProperties(OutputType PrimaryOut, OutputType SecondaryOut,
+ GrBlendEquation BlendEquation, GrBlendCoeff SrcCoeff,
+ GrBlendCoeff DstCoeff);
union {
struct {
@@ -122,51 +167,48 @@
GR_MAKE_BITFIELD_OPS(BlendFormula::Properties);
-/**
- * Initialize a compile-time constant BlendFormula and automatically deduce fProps.
- */
-#define INIT_BLEND_FORMULA(PRIMARY_OUT, SECONDARY_OUT, BLEND_EQUATION, SRC_COEFF, DST_COEFF) \
- {{{PRIMARY_OUT, \
- SECONDARY_OUT, \
- BLEND_EQUATION, SRC_COEFF, DST_COEFF, \
- BlendFormula::get_properties<PRIMARY_OUT, SECONDARY_OUT, \
- BLEND_EQUATION, SRC_COEFF, DST_COEFF>::value}}}
+constexpr BlendFormula::Properties BlendFormula::GetProperties(OutputType PrimaryOut,
+ OutputType SecondaryOut,
+ GrBlendEquation BlendEquation,
+ GrBlendCoeff SrcCoeff,
+ GrBlendCoeff DstCoeff) {
+ return static_cast<Properties>(
+ (GrBlendModifiesDst(BlendEquation, SrcCoeff, DstCoeff) ? kModifiesDst_Property : 0) |
+ (GrBlendCoeffsUseDstColor(SrcCoeff, DstCoeff) ? kUsesDstColor_Property : 0) |
+ ((PrimaryOut >= kModulate_OutputType && GrBlendCoeffsUseSrcColor(SrcCoeff, DstCoeff)) ||
+ (SecondaryOut >= kModulate_OutputType &&
+ GrBlendCoeffRefsSrc2(DstCoeff))
+ ? kUsesInputColor_Property
+ : 0) | // We assert later that SrcCoeff doesn't ref src2.
+ ((kModulate_OutputType == PrimaryOut || kNone_OutputType == PrimaryOut) &&
+ kNone_OutputType == SecondaryOut &&
+ GrBlendAllowsCoverageAsAlpha(BlendEquation, SrcCoeff, DstCoeff)
+ ? kCanTweakAlphaForCoverage_Property
+ : 0));
+}
/**
* When there is no coverage, or the blend mode can tweak alpha for coverage, we use the standard
* Porter Duff formula.
*/
-#define COEFF_FORMULA(SRC_COEFF, DST_COEFF) \
- INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \
- BlendFormula::kNone_OutputType, \
- kAdd_GrBlendEquation, SRC_COEFF, DST_COEFF)
+static constexpr BlendFormula MakeCoeffFormula(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ // When the coeffs are (Zero, Zero) or (Zero, One) we set the primary output to none.
+ return (kZero_GrBlendCoeff == srcCoeff &&
+ (kZero_GrBlendCoeff == dstCoeff || kOne_GrBlendCoeff == dstCoeff))
+ ? BlendFormula(BlendFormula::kNone_OutputType, BlendFormula::kNone_OutputType,
+ kAdd_GrBlendEquation, kZero_GrBlendCoeff, dstCoeff)
+ : BlendFormula(BlendFormula::kModulate_OutputType, BlendFormula::kNone_OutputType,
+ kAdd_GrBlendEquation, srcCoeff, dstCoeff);
+}
/**
- * Basic coeff formula similar to COEFF_FORMULA but we will make the src f*Sa. This is used in
+ * Basic coeff formula similar to MakeCoeffFormula 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.
- */
-#define DST_CLEAR_FORMULA \
- INIT_BLEND_FORMULA(BlendFormula::kNone_OutputType, \
- BlendFormula::kNone_OutputType, \
- kAdd_GrBlendEquation, kZero_GrBlendCoeff, kZero_GrBlendCoeff)
-
-/**
- * When the coeffs are (Zero, One), we don't write to the dst at all. This formula has its own macro
- * so we can set the primary output type to none.
- */
-#define NO_DST_WRITE_FORMULA \
- INIT_BLEND_FORMULA(BlendFormula::kNone_OutputType, \
- BlendFormula::kNone_OutputType, \
- kAdd_GrBlendEquation, kZero_GrBlendCoeff, kOne_GrBlendCoeff)
+static constexpr BlendFormula MakeSAModulateFormula(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ return BlendFormula(BlendFormula::kSAModulate_OutputType, BlendFormula::kNone_OutputType,
+ kAdd_GrBlendEquation, srcCoeff, dstCoeff);
+}
/**
* When there is coverage, the equation with f=coverage is:
@@ -182,10 +224,11 @@
*
* Xfer modes: dst-atop (Sa!=1)
*/
-#define COVERAGE_FORMULA(ONE_MINUS_DST_COEFF_MODULATE_OUTPUT, SRC_COEFF) \
- INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \
- ONE_MINUS_DST_COEFF_MODULATE_OUTPUT, \
- kAdd_GrBlendEquation, SRC_COEFF, kIS2C_GrBlendCoeff)
+static constexpr BlendFormula MakeCoverageFormula(
+ BlendFormula::OutputType oneMinusDstCoeffModulateOutput, GrBlendCoeff srcCoeff) {
+ return BlendFormula(BlendFormula::kModulate_OutputType, oneMinusDstCoeffModulateOutput,
+ kAdd_GrBlendEquation, srcCoeff, kIS2C_GrBlendCoeff);
+}
/**
* When there is coverage and the src coeff is Zero, the equation with f=coverage becomes:
@@ -201,10 +244,11 @@
*
* Xfer modes: clear, dst-out (Sa=1), dst-in (Sa!=1), modulate (Sc!=1)
*/
-#define COVERAGE_SRC_COEFF_ZERO_FORMULA(ONE_MINUS_DST_COEFF_MODULATE_OUTPUT) \
- INIT_BLEND_FORMULA(ONE_MINUS_DST_COEFF_MODULATE_OUTPUT, \
- BlendFormula::kNone_OutputType, \
- kReverseSubtract_GrBlendEquation, kDC_GrBlendCoeff, kOne_GrBlendCoeff)
+static constexpr BlendFormula MakeCoverageSrcCoeffZeroFormula(
+ BlendFormula::OutputType oneMinusDstCoeffModulateOutput) {
+ return BlendFormula(oneMinusDstCoeffModulateOutput, BlendFormula::kNone_OutputType,
+ kReverseSubtract_GrBlendEquation, kDC_GrBlendCoeff, kOne_GrBlendCoeff);
+}
/**
* When there is coverage and the dst coeff is Zero, the equation with f=coverage becomes:
@@ -216,109 +260,119 @@
*
* Xfer modes (Sa!=1): src, src-in, src-out
*/
-#define COVERAGE_DST_COEFF_ZERO_FORMULA(SRC_COEFF) \
- INIT_BLEND_FORMULA(BlendFormula::kModulate_OutputType, \
- BlendFormula::kCoverage_OutputType, \
- kAdd_GrBlendEquation, SRC_COEFF, kIS2A_GrBlendCoeff)
+static constexpr BlendFormula MakeCoverageDstCoeffZeroFormula(GrBlendCoeff srcCoeff) {
+ return BlendFormula(BlendFormula::kModulate_OutputType, BlendFormula::kCoverage_OutputType,
+ kAdd_GrBlendEquation, srcCoeff, kIS2A_GrBlendCoeff);
+}
+
+// Older GCC won't like the constexpr arrays because of
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61484.
+// MSVC crashes with an internal compiler error.
+#if !defined(__clang__) && ((defined(__GNUC__) && __GNUC__ < 5) || defined(_MSC_VER))
+# define MAYBE_CONSTEXPR const
+#else
+# define MAYBE_CONSTEXPR constexpr
+#endif
/**
* This table outlines the blend formulas we will use with each xfermode, with and without coverage,
* with and without an opaque input color. Optimization properties are deduced at compile time so we
* can make runtime decisions quickly. RGB coverage is not supported.
*/
-static const BlendFormula gBlendTable[2][2][(int)SkBlendMode::kLastCoeffMode + 1] = {
-
+static MAYBE_CONSTEXPR BlendFormula gBlendTable[2][2][(int)SkBlendMode::kLastCoeffMode + 1] = {
/*>> No coverage, input color unknown <<*/ {{
- /* clear */ DST_CLEAR_FORMULA,
- /* src */ COEFF_FORMULA( kOne_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst */ NO_DST_WRITE_FORMULA,
- /* src-over */ COEFF_FORMULA( kOne_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-over */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
- /* src-in */ COEFF_FORMULA( kDA_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst-in */ COEFF_FORMULA( kZero_GrBlendCoeff, kSA_GrBlendCoeff),
- /* src-out */ COEFF_FORMULA( kIDA_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst-out */ COEFF_FORMULA( kZero_GrBlendCoeff, kISA_GrBlendCoeff),
- /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-atop */ COEFF_FORMULA( kIDA_GrBlendCoeff, kSA_GrBlendCoeff),
- /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff),
- /* modulate */ COEFF_FORMULA( kZero_GrBlendCoeff, kSC_GrBlendCoeff),
- /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
+ /* clear */ MakeCoeffFormula(kZero_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* src */ MakeCoeffFormula(kOne_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst */ MakeCoeffFormula(kZero_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-over */ MakeCoeffFormula(kOne_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-over */ MakeCoeffFormula(kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-in */ MakeCoeffFormula(kDA_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst-in */ MakeCoeffFormula(kZero_GrBlendCoeff, kSA_GrBlendCoeff),
+ /* src-out */ MakeCoeffFormula(kIDA_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst-out */ MakeCoeffFormula(kZero_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* src-atop */ MakeCoeffFormula(kDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-atop */ MakeCoeffFormula(kIDA_GrBlendCoeff, kSA_GrBlendCoeff),
+ /* xor */ MakeCoeffFormula(kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* plus */ MakeCoeffFormula(kOne_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* modulate */ MakeCoeffFormula(kZero_GrBlendCoeff, kSC_GrBlendCoeff),
+ /* screen */ MakeCoeffFormula(kOne_GrBlendCoeff, kISC_GrBlendCoeff),
}, /*>> Has coverage, input color unknown <<*/ {
- /* clear */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
- /* src */ COVERAGE_DST_COEFF_ZERO_FORMULA(kOne_GrBlendCoeff),
- /* dst */ NO_DST_WRITE_FORMULA,
- /* src-over */ COEFF_FORMULA( kOne_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-over */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
- /* src-in */ COVERAGE_DST_COEFF_ZERO_FORMULA(kDA_GrBlendCoeff),
- /* dst-in */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISAModulate_OutputType),
- /* src-out */ COVERAGE_DST_COEFF_ZERO_FORMULA(kIDA_GrBlendCoeff),
- /* dst-out */ COEFF_FORMULA( kZero_GrBlendCoeff, kISA_GrBlendCoeff),
- /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-atop */ COVERAGE_FORMULA(BlendFormula::kISAModulate_OutputType, kIDA_GrBlendCoeff),
- /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff),
- /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_OutputType),
- /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
+ /* clear */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kCoverage_OutputType),
+ /* src */ MakeCoverageDstCoeffZeroFormula(kOne_GrBlendCoeff),
+ /* dst */ MakeCoeffFormula(kZero_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-over */ MakeCoeffFormula(kOne_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-over */ MakeCoeffFormula(kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-in */ MakeCoverageDstCoeffZeroFormula(kDA_GrBlendCoeff),
+ /* dst-in */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kISAModulate_OutputType),
+ /* src-out */ MakeCoverageDstCoeffZeroFormula(kIDA_GrBlendCoeff),
+ /* dst-out */ MakeCoeffFormula(kZero_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* src-atop */ MakeCoeffFormula(kDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-atop */ MakeCoverageFormula(BlendFormula::kISAModulate_OutputType, kIDA_GrBlendCoeff),
+ /* xor */ MakeCoeffFormula(kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* plus */ MakeCoeffFormula(kOne_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* modulate */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kISCModulate_OutputType),
+ /* screen */ MakeCoeffFormula(kOne_GrBlendCoeff, kISC_GrBlendCoeff),
}}, /*>> No coverage, input color opaque <<*/ {{
- /* clear */ DST_CLEAR_FORMULA,
- /* src */ COEFF_FORMULA( kOne_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst */ NO_DST_WRITE_FORMULA,
- /* src-over */ COEFF_FORMULA( kOne_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst-over */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
- /* src-in */ COEFF_FORMULA( kDA_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst-in */ NO_DST_WRITE_FORMULA,
- /* src-out */ COEFF_FORMULA( kIDA_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst-out */ DST_CLEAR_FORMULA,
- /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kZero_GrBlendCoeff),
- /* dst-atop */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
- /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kZero_GrBlendCoeff),
- /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff),
- /* modulate */ COEFF_FORMULA( kZero_GrBlendCoeff, kSC_GrBlendCoeff),
- /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
+ /* clear */ MakeCoeffFormula(kZero_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* src */ MakeCoeffFormula(kOne_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst */ MakeCoeffFormula(kZero_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-over */ MakeCoeffFormula(kOne_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst-over */ MakeCoeffFormula(kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-in */ MakeCoeffFormula(kDA_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst-in */ MakeCoeffFormula(kZero_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-out */ MakeCoeffFormula(kIDA_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst-out */ MakeCoeffFormula(kZero_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* src-atop */ MakeCoeffFormula(kDA_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* dst-atop */ MakeCoeffFormula(kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* xor */ MakeCoeffFormula(kIDA_GrBlendCoeff, kZero_GrBlendCoeff),
+ /* plus */ MakeCoeffFormula(kOne_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* modulate */ MakeCoeffFormula(kZero_GrBlendCoeff, kSC_GrBlendCoeff),
+ /* screen */ MakeCoeffFormula(kOne_GrBlendCoeff, kISC_GrBlendCoeff),
}, /*>> Has coverage, input color opaque <<*/ {
- /* clear */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
- /* src */ COEFF_FORMULA( kOne_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst */ NO_DST_WRITE_FORMULA,
- /* src-over */ COEFF_FORMULA( kOne_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-over */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
- /* src-in */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-in */ NO_DST_WRITE_FORMULA,
- /* src-out */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-out */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kCoverage_OutputType),
- /* src-atop */ COEFF_FORMULA( kDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* dst-atop */ COEFF_FORMULA( kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
- /* xor */ COEFF_FORMULA( kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
- /* plus */ COEFF_FORMULA( kOne_GrBlendCoeff, kOne_GrBlendCoeff),
- /* modulate */ COVERAGE_SRC_COEFF_ZERO_FORMULA(BlendFormula::kISCModulate_OutputType),
- /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
+ /* clear */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kCoverage_OutputType),
+ /* src */ MakeCoeffFormula(kOne_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst */ MakeCoeffFormula(kZero_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-over */ MakeCoeffFormula(kOne_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-over */ MakeCoeffFormula(kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-in */ MakeCoeffFormula(kDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-in */ MakeCoeffFormula(kZero_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-out */ MakeCoeffFormula(kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-out */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kCoverage_OutputType),
+ /* src-atop */ MakeCoeffFormula(kDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* dst-atop */ MakeCoeffFormula(kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* xor */ MakeCoeffFormula(kIDA_GrBlendCoeff, kISA_GrBlendCoeff),
+ /* plus */ MakeCoeffFormula(kOne_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* modulate */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kISCModulate_OutputType),
+ /* screen */ MakeCoeffFormula(kOne_GrBlendCoeff, kISC_GrBlendCoeff),
}}};
-static const BlendFormula gLCDBlendTable[(int)SkBlendMode::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 MAYBE_CONSTEXPR BlendFormula gLCDBlendTable[(int)SkBlendMode::kLastCoeffMode + 1] = {
+ /* clear */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kCoverage_OutputType),
+ /* src */ MakeCoverageFormula(BlendFormula::kCoverage_OutputType, kOne_GrBlendCoeff),
+ /* dst */ MakeCoeffFormula(kZero_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-over */ MakeCoverageFormula(BlendFormula::kSAModulate_OutputType, kOne_GrBlendCoeff),
+ /* dst-over */ MakeCoeffFormula(kIDA_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* src-in */ MakeCoverageFormula(BlendFormula::kCoverage_OutputType, kDA_GrBlendCoeff),
+ /* dst-in */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kISAModulate_OutputType),
+ /* src-out */ MakeCoverageFormula(BlendFormula::kCoverage_OutputType, kIDA_GrBlendCoeff),
+ /* dst-out */ MakeSAModulateFormula(kZero_GrBlendCoeff, kISC_GrBlendCoeff),
+ /* src-atop */ MakeCoverageFormula(BlendFormula::kSAModulate_OutputType, kDA_GrBlendCoeff),
+ /* dst-atop */ MakeCoverageFormula(BlendFormula::kISAModulate_OutputType, kIDA_GrBlendCoeff),
+ /* xor */ MakeCoverageFormula(BlendFormula::kSAModulate_OutputType, kIDA_GrBlendCoeff),
+ /* plus */ MakeCoeffFormula(kOne_GrBlendCoeff, kOne_GrBlendCoeff),
+ /* modulate */ MakeCoverageSrcCoeffZeroFormula(BlendFormula::kISCModulate_OutputType),
+ /* screen */ MakeCoeffFormula(kOne_GrBlendCoeff, kISC_GrBlendCoeff),
};
+#undef MAYBE_CONSTEXPR
+
static BlendFormula get_blend_formula(bool isOpaque,
bool hasCoverage,
bool hasMixedSamples,
@@ -354,9 +408,9 @@
bool onHasSecondaryOutput() const override { return fBlendFormula.hasSecondaryOutput(); }
void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
- blendInfo->fEquation = fBlendFormula.fBlendEquation;
- blendInfo->fSrcBlend = fBlendFormula.fSrcCoeff;
- blendInfo->fDstBlend = fBlendFormula.fDstCoeff;
+ blendInfo->fEquation = fBlendFormula.equation();
+ blendInfo->fSrcBlend = fBlendFormula.srcCoeff();
+ blendInfo->fDstBlend = fBlendFormula.dstCoeff();
blendInfo->fWriteColor = fBlendFormula.modifiesDst();
}
@@ -408,8 +462,8 @@
public:
static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) {
const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcessor>();
- b->add32(xp.getBlendFormula().fPrimaryOutputType |
- (xp.getBlendFormula().fSecondaryOutputType << 3));
+ b->add32(xp.getBlendFormula().primaryOutput() |
+ (xp.getBlendFormula().secondaryOutput() << 3));
GR_STATIC_ASSERT(BlendFormula::kLast_OutputType < 8);
}
@@ -420,11 +474,11 @@
BlendFormula blendFormula = xp.getBlendFormula();
if (blendFormula.hasSecondaryOutput()) {
- append_color_output(xp, fragBuilder, blendFormula.fSecondaryOutputType,
+ append_color_output(xp, fragBuilder, blendFormula.secondaryOutput(),
args.fOutputSecondary, args.fInputColor, args.fInputCoverage);
}
- append_color_output(xp, fragBuilder, blendFormula.fPrimaryOutputType,
- args.fOutputPrimary, args.fInputColor, args.fInputCoverage);
+ append_color_output(xp, fragBuilder, blendFormula.primaryOutput(), args.fOutputPrimary,
+ args.fInputColor, args.fInputCoverage);
}
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
@@ -756,7 +810,7 @@
}
// Ignore the effect of coverage here for overlap stencil and cover property
auto colorFormula = gBlendTable[color.isOpaque()][0][(int)mode];
- SkASSERT(kAdd_GrBlendEquation == colorFormula.fBlendEquation);
+ SkASSERT(kAdd_GrBlendEquation == colorFormula.equation());
if (!colorFormula.usesDstColor()) {
props |= AnalysisProperties::kCanCombineOverlappedStencilAndCover;
}
@@ -787,16 +841,16 @@
return;
}
BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)->getBlendFormula();
- *outPrimary = blendFormula.fPrimaryOutputType;
- *outSecondary = blendFormula.fSecondaryOutputType;
+ *outPrimary = blendFormula.primaryOutput();
+ *outSecondary = blendFormula.secondaryOutput();
}
////////////////////////////////////////////////////////////////////////////////////////////////
// SrcOver Global functions
////////////////////////////////////////////////////////////////////////////////////////////////
const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() {
- static BlendFormula gSrcOverBlendFormula = COEFF_FORMULA(kOne_GrBlendCoeff,
- kISA_GrBlendCoeff);
+ static BlendFormula gSrcOverBlendFormula =
+ MakeCoeffFormula(kOne_GrBlendCoeff, kISA_GrBlendCoeff);
static PorterDuffXferProcessor gSrcOverXP(gSrcOverBlendFormula);
return gSrcOverXP;
}
diff --git a/tests/GrGetCoeffBlendKnownComponentsTest.cpp b/tests/GrGetCoeffBlendKnownComponentsTest.cpp
deleted file mode 100644
index 53bd09e..0000000
--- a/tests/GrGetCoeffBlendKnownComponentsTest.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "Test.h"
-
-#if SK_SUPPORT_GPU
-
-#include "GrBlend.h"
-#include "SkGr.h"
-#include "SkRandom.h"
-
-static inline SkPMColor GrColorToSkPMColor(GrColor c) {
- GrColorIsPMAssert(c);
- return SkPackARGB32(GrColorUnpackA(c), GrColorUnpackR(c), GrColorUnpackG(c), GrColorUnpackB(c));
-}
-
-static inline GrColor SkPMColorToGrColor(SkPMColor c) {
- return GrColorPackRGBA(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c),
- SkGetPackedA32(c));
-}
-
-static GrColor make_baseline_color(GrColor src, GrColor dst, const SkXfermode* xm) {
- SkPMColor skSrc = GrColorToSkPMColor(src);
- SkPMColor skDst = GrColorToSkPMColor(dst);
- if (xm) {
- xm->xfer32(&skDst, &skSrc, 1, nullptr);
- } else {
- // null means src-over
- skDst = SkPMSrcOver(skSrc, skDst);
- }
- return SkPMColorToGrColor(skDst);
-}
-
-DEF_TEST(GrGetCoeffBlendKnownComponents, reporter) {
- SkRandom random;
- for (int i = 0; i < SkXfermode::kLastCoeffMode; ++i) {
- SkXfermode::Mode mode = (SkXfermode::Mode)i;
- auto xm(SkXfermode::Make(mode));
- SkXfermode::Coeff srcCoeff, dstCoeff;
- SkAssertResult(SkXfermode::ModeAsCoeff(mode, &srcCoeff, &dstCoeff));
- for (int j = 0; j < 1000; ++j) {
- GrColor src = GrPremulColor(random.nextU());
- GrColor dst = GrPremulColor(random.nextU());
- GrColor outColor;
- GrColorComponentFlags outFlags;
- GrGetCoeffBlendKnownComponents(SkXfermodeCoeffToGrBlendCoeff(srcCoeff),
- SkXfermodeCoeffToGrBlendCoeff(dstCoeff),
- src, kRGBA_GrColorComponentFlags,
- dst, kRGBA_GrColorComponentFlags,
- &outColor, &outFlags);
- GrColor baselineColor = make_baseline_color(src, dst, xm.get());
- if (SkAbs32(GrColorUnpackA(baselineColor) - GrColorUnpackA(outColor)) > 1 ||
- SkAbs32(GrColorUnpackR(baselineColor) - GrColorUnpackR(outColor)) > 1 ||
- SkAbs32(GrColorUnpackG(baselineColor) - GrColorUnpackG(outColor)) > 1 ||
- SkAbs32(GrColorUnpackB(baselineColor) - GrColorUnpackB(outColor)) > 1) {
- ERRORF(reporter, "Blended color is 0x%08x, expected 0x%08x", outColor,
- baselineColor);
- }
- GrColorIsPMAssert(outColor);
- }
- }
- GrColor outColor;
- GrColorComponentFlags outFlags;
- GrGetCoeffBlendKnownComponents(kZero_GrBlendCoeff, kZero_GrBlendCoeff,
- 0xFFFFFFFF, kNone_GrColorComponentFlags,
- 0xFFFFFFFF, kNone_GrColorComponentFlags,
- &outColor, &outFlags);
- REPORTER_ASSERT(reporter, GrColor_TRANSPARENT_BLACK == outColor &&
- kRGBA_GrColorComponentFlags == outFlags);
- GrGetCoeffBlendKnownComponents(
- kOne_GrBlendCoeff, kOne_GrBlendCoeff,
- 0x80FF0100, (kG_GrColorComponentFlag | kB_GrColorComponentFlag | kA_GrColorComponentFlag),
- 0x7F00FFFF, (kR_GrColorComponentFlag | kG_GrColorComponentFlag | kA_GrColorComponentFlag),
- &outColor, &outFlags);
- REPORTER_ASSERT(reporter, GrColor_WHITE == outColor && kRGBA_GrColorComponentFlags == outFlags);
-
- GrGetCoeffBlendKnownComponents(
- kOne_GrBlendCoeff, kISA_GrBlendCoeff,
- 0x0000000, kRGBA_GrColorComponentFlags,
- 0x80010203, kRGBA_GrColorComponentFlags,
- &outColor, &outFlags);
- REPORTER_ASSERT(reporter, 0x80010203 == outColor && kRGBA_GrColorComponentFlags == outFlags);
-
- GrGetCoeffBlendKnownComponents(kZero_GrBlendCoeff, kISA_GrBlendCoeff,
- 0x0000000, kA_GrColorComponentFlag,
- 0x80010203, kRGBA_GrColorComponentFlags,
- &outColor, &outFlags);
- REPORTER_ASSERT(reporter, 0x80010203 == outColor && kRGBA_GrColorComponentFlags == outFlags);
-
- GrGetCoeffBlendKnownComponents(
- kIDC_GrBlendCoeff, kSC_GrBlendCoeff,
- 0x0, kNone_GrColorComponentFlags,
- 0x0, kRGBA_GrColorComponentFlags,
- &outColor, &outFlags);
- REPORTER_ASSERT(reporter, kNone_GrColorComponentFlags == outFlags);
-
- GrGetCoeffBlendKnownComponents(
- kOne_GrBlendCoeff, kISA_GrBlendCoeff,
- 0xFF808080, (kG_GrColorComponentFlag | kB_GrColorComponentFlag | kA_GrColorComponentFlag),
- 0xFF606060, kRGBA_GrColorComponentFlags,
- &outColor, &outFlags);
- REPORTER_ASSERT(reporter,
- (kG_GrColorComponentFlag | kB_GrColorComponentFlag | kA_GrColorComponentFlag) == outFlags &&
- (outColor & 0xFFFFFF00) == 0xFF808000);
-}
-
-#endif