/* * 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 "include/core/SkTypes.h" /** * Equations for alpha-blending. */ enum GrBlendEquation { // Basic blend equations. kAdd_GrBlendEquation, //= kFirstAdvancedGrBlendEquation && equation != kIllegal_GrBlendEquation; } static constexpr bool GrBlendModifiesDst(GrBlendEquation equation, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { return (kAdd_GrBlendEquation != equation && kReverseSubtract_GrBlendEquation != equation) || kZero_GrBlendCoeff != srcCoeff || kOne_GrBlendCoeff != dstCoeff; } static constexpr bool GrBlendCoeffRefsConstant(const GrBlendCoeff coeff) { return coeff == kConstC_GrBlendCoeff || coeff == kIConstC_GrBlendCoeff; } static constexpr bool GrBlendShouldDisable(GrBlendEquation equation, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { return (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; } /** * 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. */ 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