/* * Copyright 2023 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/gpu/BlendFormula.h" #include "include/core/SkBlendMode.h" namespace { BlendFormula; /** * When there is no coverage, or the blend mode can tweak alpha for coverage, we use the standard * Porter Duff formula. */ constexpr BlendFormula MakeCoeffFormula(skgpu::BlendCoeff srcCoeff, skgpu::BlendCoeff dstCoeff) { … } /** * Basic coeff formula similar to MakeCoeffFormula but we will make the src f*Sa. This is used in * LCD dst-out. */ constexpr BlendFormula MakeSAModulateFormula(skgpu::BlendCoeff srcCoeff, skgpu::BlendCoeff dstCoeff) { … } /** * When there is coverage, the equation with f=coverage is: * * D' = f * (S * srcCoeff + D * dstCoeff) + (1-f) * D * * This can be rewritten as: * * D' = f * S * srcCoeff + D * (1 - [f * (1 - dstCoeff)]) * * To implement this formula, we output [f * (1 - dstCoeff)] for the secondary color and replace the * HW dst coeff with IS2C. * * Xfer modes: dst-atop (Sa!=1) */ constexpr BlendFormula MakeCoverageFormula(BlendFormula::OutputType oneMinusDstCoeffModulateOutput, skgpu::BlendCoeff srcCoeff) { … } /** * When there is coverage and the src coeff is Zero, the equation with f=coverage becomes: * * D' = f * D * dstCoeff + (1-f) * D * * This can be rewritten as: * * D' = D - D * [f * (1 - dstCoeff)] * * To implement this formula, we output [f * (1 - dstCoeff)] for the primary color and use a reverse * subtract HW blend equation with coeffs of (DC, One). * * Xfer modes: clear, dst-out (Sa=1), dst-in (Sa!=1), modulate (Sc!=1) */ constexpr BlendFormula MakeCoverageSrcCoeffZeroFormula( BlendFormula::OutputType oneMinusDstCoeffModulateOutput) { … } /** * When there is coverage and the dst coeff is Zero, the equation with f=coverage becomes: * * D' = f * S * srcCoeff + (1-f) * D * * To implement this formula, we output [f] for the secondary color and replace the HW dst coeff * with IS2A. (Note that we can avoid dual source blending when Sa=1 by using ISA.) * * Xfer modes (Sa!=1): src, src-in, src-out */ constexpr BlendFormula MakeCoverageDstCoeffZeroFormula(skgpu::BlendCoeff srcCoeff) { … } /** * 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. */ constexpr BlendFormula gBlendTable[2][2][(int)SkBlendMode::kLastCoeffMode + 1] = …; // In the above table src-over is not optimized to src mode when the color is opaque because we // found no advantage to doing so. Also, we are using a global src-over blend in most cases which is // not specialized for opaque input. For GPUs where dropping to src (and thus able to disable // blending) is an advantage we change the blend mode to src before getting the blend formula from // this table. constexpr BlendFormula gLCDBlendTable[(int)SkBlendMode::kLastCoeffMode + 1] = …; } // anonymous namespace namespace skgpu { BlendFormula GetBlendFormula(bool isOpaque, bool hasCoverage, SkBlendMode xfermode) { … } BlendFormula GetLCDBlendFormula(SkBlendMode xfermode) { … } } // namespace skgpu