skia2/include/gpu/GrBlend.h

233 lines
8.3 KiB
C
Raw Normal View History

/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrBlend_DEFINED
#define GrBlend_DEFINED
#include "GrColor.h"
#include "../private/SkTLogic.h"
/**
* Equations for alpha-blending.
*/
enum GrBlendEquation {
// Basic blend equations.
kAdd_GrBlendEquation, //<! Cs*S + Cd*D
kSubtract_GrBlendEquation, //<! Cs*S - Cd*D
kReverseSubtract_GrBlendEquation, //<! Cd*D - Cs*S
// Advanced blend equations. These are described in the SVG and PDF specs.
kScreen_GrBlendEquation,
kOverlay_GrBlendEquation,
kDarken_GrBlendEquation,
kLighten_GrBlendEquation,
kColorDodge_GrBlendEquation,
kColorBurn_GrBlendEquation,
kHardLight_GrBlendEquation,
kSoftLight_GrBlendEquation,
kDifference_GrBlendEquation,
kExclusion_GrBlendEquation,
kMultiply_GrBlendEquation,
kHSLHue_GrBlendEquation,
kHSLSaturation_GrBlendEquation,
kHSLColor_GrBlendEquation,
kHSLLuminosity_GrBlendEquation,
kFirstAdvancedGrBlendEquation = kScreen_GrBlendEquation,
kLast_GrBlendEquation = kHSLLuminosity_GrBlendEquation
};
static const int kGrBlendEquationCnt = kLast_GrBlendEquation + 1;
/**
* Coefficients for alpha-blending.
*/
enum GrBlendCoeff {
kZero_GrBlendCoeff, //<! 0
kOne_GrBlendCoeff, //<! 1
kSC_GrBlendCoeff, //<! src color
kISC_GrBlendCoeff, //<! one minus src color
kDC_GrBlendCoeff, //<! dst color
kIDC_GrBlendCoeff, //<! one minus dst color
kSA_GrBlendCoeff, //<! src alpha
kISA_GrBlendCoeff, //<! one minus src alpha
kDA_GrBlendCoeff, //<! dst alpha
kIDA_GrBlendCoeff, //<! one minus dst alpha
kConstC_GrBlendCoeff, //<! constant color
kIConstC_GrBlendCoeff, //<! one minus constant color
kConstA_GrBlendCoeff, //<! constant color alpha
kIConstA_GrBlendCoeff, //<! one minus constant color alpha
kS2C_GrBlendCoeff,
kIS2C_GrBlendCoeff,
kS2A_GrBlendCoeff,
kIS2A_GrBlendCoeff,
kLast_GrBlendCoeff = kIS2A_GrBlendCoeff
};
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);
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
template<GrBlendCoeff Coeff>
struct GrTBlendCoeffRefsSrc : skstd::bool_constant<kSC_GrBlendCoeff == Coeff ||
kISC_GrBlendCoeff == Coeff ||
kSA_GrBlendCoeff == Coeff ||
kISA_GrBlendCoeff == Coeff> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#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;
}
}
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
template<GrBlendCoeff Coeff>
struct GrTBlendCoeffRefsDst : skstd::bool_constant<kDC_GrBlendCoeff == Coeff ||
kIDC_GrBlendCoeff == Coeff ||
kDA_GrBlendCoeff == Coeff ||
kIDA_GrBlendCoeff == Coeff> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#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;
}
}
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
template<GrBlendCoeff Coeff>
struct GrTBlendCoeffRefsSrc2 : skstd::bool_constant<kS2C_GrBlendCoeff == Coeff ||
kIS2C_GrBlendCoeff == Coeff ||
kS2A_GrBlendCoeff == Coeff ||
kIS2A_GrBlendCoeff == Coeff> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#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;
}
}
template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff>
struct GrTBlendCoeffsUseSrcColor : skstd::bool_constant<kZero_GrBlendCoeff != SrcCoeff ||
GR_BLEND_COEFF_REFS_SRC(DstCoeff)> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#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> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#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> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#define GR_BLEND_EQUATION_IS_ADVANCED(EQUATION) \
GrTBlendEquationIsAdvanced<EQUATION>::value
inline 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> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#define GR_BLEND_MODIFIES_DST(EQUATION, SRC_COEFF, DST_COEFF) \
GrTBlendModifiesDst<EQUATION, SRC_COEFF, DST_COEFF>::value
/**
* Advanced blend equations can always tweak alpha for coverage. (See GrCustomXfermode.cpp)
*
* For "add" and "reverse subtract" the blend equation 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, this will work as long as the following is true:
*|
* dstCoeff' == f * dstCoeff + (1 - f)
* dstCoeff' == 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.
*
* 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.
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
*/
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> {};
Implement Porter Duff XP with a blend table Removes the runtime logic used by PorterDuffXferProcessor to decide blend coeffs and shader outputs, and instead uses a compile-time constant table of pre-selected blend formulas. Separates out the dst read fallback into its own XP. Introduces a new blend strategy for srcCoeff=0 that can apply coverage with a reverse subtract blend equation instead of dual source blending. Adds new macros in GrBlend.h to analyze blend formulas both runtime. Removes kSetCoverageDrawing_OptFlag and GrSimplifyBlend as they are no longer used. Adds a GM that verifies all xfermodes, including arithmetic, with the color/coverage invariants used by Porter Duff. Adds a unit test that verifies each Porter Duff formula with every color/coverage invariant. Major changes: * Uses a reverse subtract blend equation for coverage when srcCoeff=0 (clear, dst-out [Sa=1], dst-in, modulate). Platforms that don't support dual source blending no longer require a dst copy for dst-in and modulate. * Sets BlendInfo::fWriteColor to false when the blend does not modify the dst. GrGLGpu will now use glColorMask instead of blending for these modes (dst, dst-in [Sa=1], modulate ignored for [Sc=1]). * Converts all SA blend coeffs to One for opaque inputs, and ISA to Zero if there is also no coverage. (We keep ISA around when there is coverage because we use it to tweak alpha for coverage.) * Abandons solid white optimizations for the sake of simplicity (screen was the only mode that previous had solid white opts). Minor differences: * Inconsequential differences in opt flags (e.g. we now return kCanTweakAlphaForCoverage_OptFlag even when there is no coverage). * Src coeffs when the shader outputs 0. * IS2C vs IS2A when the secondary output is scalar. BUG=skia: Committed: https://skia.googlesource.com/skia/+/9a70920db22b6309c671f8e5d519bb95570e4414 Review URL: https://codereview.chromium.org/1124373002
2015-05-27 22:08:33 +00:00
#define GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(EQUATION, SRC_COEFF, DST_COEFF) \
GrTBlendCanTweakAlphaForCoverage<EQUATION, SRC_COEFF, DST_COEFF>::value
#endif