blob: 436829ce63af300b8d458304e801dac1ad2de7af [file] [log] [blame]
bsalomonae4738f2015-09-15 15:33:27 -07001/*
2* Copyright 2015 Google Inc.
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
8#include "GrBlend.h"
Mike Reede602f392018-02-06 10:17:08 -05009#include "../private/GrColor.h"
bsalomonae4738f2015-09-15 15:33:27 -070010
11/**
12 * MaskedColor is used to evaluate the color and valid color component flags through the
13 * blending equation. Could possibly extend this to be used more broadly.
14 */
15class MaskedColor {
16public:
17 MaskedColor(GrColor color, GrColorComponentFlags flags)
18 : fColor(color)
19 , fFlags(flags) {}
20
21 MaskedColor() {}
22
23 void set(GrColor color, GrColorComponentFlags flags) {
24 fColor = color;
25 fFlags = flags;
26 }
27
28 static MaskedColor Invert(const MaskedColor& in) {
29 return MaskedColor(GrInvertColor(in.fColor), in.fFlags);
30 }
31
32 static MaskedColor ExtractAlpha(const MaskedColor& in) {
33 GrColorComponentFlags flags = (in.fFlags & kA_GrColorComponentFlag) ?
34 kRGBA_GrColorComponentFlags : kNone_GrColorComponentFlags;
35 return MaskedColor(GrColorPackA4(GrColorUnpackA(in.fColor)), flags);
36 }
37
38 static MaskedColor ExtractInverseAlpha(const MaskedColor& in) {
39 GrColorComponentFlags flags = (in.fFlags & kA_GrColorComponentFlag) ?
40 kRGBA_GrColorComponentFlags : kNone_GrColorComponentFlags;
41 return MaskedColor(GrColorPackA4(0xFF - GrColorUnpackA(in.fColor)), flags);
42 }
43
44 static MaskedColor Mul(const MaskedColor& a, const MaskedColor& b) {
45 GrColorComponentFlags outFlags = (a.fFlags & b.fFlags) | a.componentsWithValue(0) |
46 b.componentsWithValue(0);
47 return MaskedColor(GrColorMul(a.fColor, b.fColor), outFlags);
48 }
49
50 static MaskedColor SatAdd(const MaskedColor& a, const MaskedColor& b) {
51 GrColorComponentFlags outFlags = (a.fFlags & b.fFlags) | a.componentsWithValue(0xFF) |
52 b.componentsWithValue(0xFF);
53 return MaskedColor(GrColorSatAdd(a.fColor, b.fColor), outFlags);
54 }
55
56 GrColor color() const { return fColor; }
57
58 GrColorComponentFlags validFlags () const { return fFlags; }
59
60private:
61 GrColorComponentFlags componentsWithValue(unsigned value) const {
62 GrColorComponentFlags flags = kNone_GrColorComponentFlags;
63 if ((kR_GrColorComponentFlag & fFlags) && value == GrColorUnpackR(fColor)) {
64 flags |= kR_GrColorComponentFlag;
65 }
66 if ((kG_GrColorComponentFlag & fFlags) && value == GrColorUnpackG(fColor)) {
67 flags |= kG_GrColorComponentFlag;
68 }
69 if ((kB_GrColorComponentFlag & fFlags) && value == GrColorUnpackB(fColor)) {
70 flags |= kB_GrColorComponentFlag;
71 }
72 if ((kA_GrColorComponentFlag & fFlags) && value == GrColorUnpackA(fColor)) {
73 flags |= kA_GrColorComponentFlag;
74 }
75 return flags;
76 }
77
78 GrColor fColor;
79 GrColorComponentFlags fFlags;
80};
81
82static MaskedColor get_term(GrBlendCoeff coeff, const MaskedColor& src, const MaskedColor& dst,
83 const MaskedColor& value) {
84 switch (coeff) {
85 case kZero_GrBlendCoeff:
86 return MaskedColor(0, kRGBA_GrColorComponentFlags);
87 case kOne_GrBlendCoeff:
88 return value;
89 case kDC_GrBlendCoeff:
90 return MaskedColor::Mul(dst, value);
91 case kIDC_GrBlendCoeff:
92 return MaskedColor::Mul(MaskedColor::Invert(dst), value);
93 case kDA_GrBlendCoeff:
94 return MaskedColor::Mul(MaskedColor::ExtractAlpha(dst), value);
95 case kIDA_GrBlendCoeff:
96 return MaskedColor::Mul(MaskedColor::ExtractInverseAlpha(dst), value);
97 case kSC_GrBlendCoeff:
98 return MaskedColor::Mul(src, value);
99 case kISC_GrBlendCoeff:
100 return MaskedColor::Mul(MaskedColor::Invert(src), value);
101 case kSA_GrBlendCoeff:
102 return MaskedColor::Mul(MaskedColor::ExtractAlpha(src), value);
103 case kISA_GrBlendCoeff:
104 return MaskedColor::Mul(MaskedColor::ExtractInverseAlpha(src), value);
105 default:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400106 SK_ABORT("Illegal coefficient");
bsalomonae4738f2015-09-15 15:33:27 -0700107 return MaskedColor();
108 }
109}
110
111void GrGetCoeffBlendKnownComponents(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff,
112 GrColor srcColor, GrColorComponentFlags srcColorFlags,
113 GrColor dstColor, GrColorComponentFlags dstColorFlags,
114 GrColor* outColor,
115 GrColorComponentFlags* outFlags) {
116 MaskedColor src(srcColor, srcColorFlags);
117 MaskedColor dst(dstColor, dstColorFlags);
118
119 MaskedColor srcTerm = get_term(srcCoeff, src, dst, src);
120 MaskedColor dstTerm = get_term(dstCoeff, src, dst, dst);
121
122 MaskedColor output = MaskedColor::SatAdd(srcTerm, dstTerm);
123 *outColor = output.color();
124 *outFlags = output.validFlags();
125}