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

Unified Diff: src/gpu/GrBlend.h

Issue 1124373002: Implement Porter Duff XP with a blend table (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: var names Created 5 years, 7 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
Index: src/gpu/GrBlend.h
diff --git a/src/gpu/GrBlend.h b/src/gpu/GrBlend.h
index e5b8993377a4ae5baba5c61ad8bb373424d42f19..b8be824c02a6d90cccbaa710185b495b7b91abd2 100644
--- a/src/gpu/GrBlend.h
+++ b/src/gpu/GrBlend.h
@@ -7,13 +7,13 @@
*/
#include "GrTypes.h"
-#include "GrColor.h"
+#include "SkTLogic.h"
#include "GrXferProcessor.h"
#ifndef GrBlend_DEFINED
#define GrBlend_DEFINED
-static inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) {
+inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) {
switch (coeff) {
case kSC_GrBlendCoeff:
case kISC_GrBlendCoeff:
@@ -25,7 +25,17 @@ static inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) {
}
}
-static inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) {
+template<GrBlendCoeff Coeff>
+struct GrTBlendCoeffRefsSrc : SkTBool<kSC_GrBlendCoeff == Coeff ||
+ kISC_GrBlendCoeff == Coeff ||
+ kSA_GrBlendCoeff == Coeff ||
+ kISA_GrBlendCoeff == Coeff> {};
+
+#define GR_BLEND_COEFF_REFS_SRC(COEFF) \
+ GrTBlendCoeffRefsSrc<COEFF>::value
+
+
+inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) {
switch (coeff) {
case kDC_GrBlendCoeff:
case kIDC_GrBlendCoeff:
@@ -37,10 +47,170 @@ static inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) {
}
}
-GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff,
- GrBlendCoeff* dstCoeff,
- GrColor srcColor, uint32_t srcCompFlags,
- GrColor dstColor, uint32_t dstCompFlags,
- GrColor constantColor);
+template<GrBlendCoeff Coeff>
+struct GrTBlendCoeffRefsDst : SkTBool<kDC_GrBlendCoeff == Coeff ||
+ kIDC_GrBlendCoeff == Coeff ||
+ kDA_GrBlendCoeff == Coeff ||
+ kIDA_GrBlendCoeff == Coeff> {};
+
+#define GR_BLEND_COEFF_REFS_DST(COEFF) \
+ GrTBlendCoeffRefsDst<COEFF>::value
+
+
+inline bool GrBlendCoeffRefsBlendColor(GrBlendCoeff coeff) {
+ switch (coeff) {
+ case kConstC_GrBlendCoeff:
+ case kIConstC_GrBlendCoeff:
+ case kConstA_GrBlendCoeff:
+ case kIConstA_GrBlendCoeff:
+ return true;
+ default:
+ return false;
+ }
+}
+
+template<GrBlendCoeff Coeff>
+struct GrTBlendCoeffRefsBlendColor : SkTBool<kConstC_GrBlendCoeff == Coeff ||
+ kIConstC_GrBlendCoeff == Coeff ||
+ kConstA_GrBlendCoeff == Coeff ||
+ kIConstA_GrBlendCoeff == Coeff> {};
+
+#define GR_BLEND_COEFF_REFS_BLEND_COLOR(COEFF) \
+ GrTBlendCoeffRefsBlendColor<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;
+ }
+}
+
+template<GrBlendCoeff Coeff>
+struct GrTBlendCoeffRefsSrc2 : SkTBool<kS2C_GrBlendCoeff == Coeff ||
+ kIS2C_GrBlendCoeff == Coeff ||
+ kS2A_GrBlendCoeff == Coeff ||
+ kIS2A_GrBlendCoeff == Coeff> {};
+
+#define GR_BLEND_COEFF_REFS_SRC2(COEFF) \
+ GrTBlendCoeffRefsSrc2<COEFF>::value
+
+
+inline bool GrBlendCoeffsUseSrcColor(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ return kZero_GrBlendCoeff != srcCoeff || GrBlendCoeffRefsSrc(dstCoeff);
+}
+
+template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
+struct GrTBlendCoeffsUseSrcColor : SkTBool<kZero_GrBlendCoeff != SrcCoeff ||
+ GR_BLEND_COEFF_REFS_SRC(DstCoeff)> {};
+
+#define GR_BLEND_COEFFS_USE_SRC_COLOR(SRC_COEFF, DST_COEFF) \
+ GrTBlendCoeffsUseSrcColor<SRC_COEFF, DST_COEFF>::value
+
+
+inline bool GrBlendCoeffsUseDstColor(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ return GrBlendCoeffRefsDst(srcCoeff) || kZero_GrBlendCoeff != dstCoeff;
+}
+
+template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
+struct GrTBlendCoeffsUseDstColor : SkTBool<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
+
+
+inline bool GrBlendEquationIsAdvanced(GrBlendEquation equation) {
+ return equation >= kFirstAdvancedGrBlendEquation;
+}
+
+template<GrBlendEquation Equation>
+struct GrTBlendEquationIsAdvanced : SkTBool<Equation >= kFirstAdvancedGrBlendEquation> {};
+
+#define GR_BLEND_EQUATION_IS_ADVANCED(EQUATION) \
+ GrTBlendEquationIsAdvanced<EQUATION>::value
+
+
+inline bool GrBlendModifiesDst(GrBlendEquation equation,
+ GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ if (kAdd_GrBlendEquation != equation && kReverseSubtract_GrBlendEquation != equation) {
+ return true;
+ }
+ return kZero_GrBlendCoeff != srcCoeff || kOne_GrBlendCoeff != dstCoeff;
+}
+
+template<GrBlendEquation BlendEquation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
+struct GrTBlendModifiesDst : SkTBool<(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
+
+
+inline bool GrBlendCanTweakAlphaForCoverage(GrBlendEquation equation,
+ GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ if (GrBlendEquationIsAdvanced(equation)) {
+ return true; // See GrCustomXfermode.cpp for an explanation on why this works.
+ }
+ if (kSubtract_GrBlendEquation == equation) {
+ return false;
+ }
+
+ SkASSERT(kAdd_GrBlendEquation == equation || kReverseSubtract_GrBlendEquation == equation);
+
+ /*
+ The blend equation at this point with f=coverage is:
+
+ D' = f * (S * srcCoeff + D * dstCoeff) + (1-f) * D
+ = f * S * srcCoeff + D * (f * dstCoeff + (1 - f))
+
+ (Let srcCoeff be negative for reverse subtract.) We can tweak alpha for coverage when the
+ following relationship holds:
+
+ (f*S) * srcCoeff' + D * dstCoeff' == f * S * srcCoeff + D * (f * dstCoeff + (1 - f))
+
+ (Where srcCoeff' and dstCoeff' have any reference to S pre-multiplied by f.)
+
+ It's easy to see this works for the src term as long as srcCoeff' == srcCoeff (meaning srcCoeff
+ does not reference S). For the dst term, the test can be rewritten as follows:
+
+ D * dstCoeff' == D * (1 - f * (1 - dstCoeff))
+
+ By inspection we can see this will work as long as dstCoeff has a 1, and any other term in
+ dstCoeff references S.
+ */
+
+ if (GrBlendCoeffRefsSrc(srcCoeff)) {
+ return false;
+ }
+
+ switch (dstCoeff) {
+ case kOne_GrBlendCoeff:
+ case kISC_GrBlendCoeff:
+ case kISA_GrBlendCoeff:
+ return true;
+ default:
+ return false;
+ }
+}
+
+template<GrBlendEquation Equation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
+struct GrTBlendCanTweakAlphaForCoverage : SkTBool<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))> {};
+
+#define GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(EQUATION, SRC_COEFF, DST_COEFF) \
+ GrTBlendCanTweakAlphaForCoverage<EQUATION, SRC_COEFF, DST_COEFF>::value
#endif

Powered by Google App Engine
This is Rietveld 408576698