| Index: src/gpu/GrBlend.cpp
|
| diff --git a/src/gpu/GrBlend.cpp b/src/gpu/GrBlend.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..72a89d838ddb29d9bc0a096f439b8edcab5cdba3
|
| --- /dev/null
|
| +++ b/src/gpu/GrBlend.cpp
|
| @@ -0,0 +1,124 @@
|
| +/*
|
| +* Copyright 2015 Google Inc.
|
| +*
|
| +* Use of this source code is governed by a BSD-style license that can be
|
| +* found in the LICENSE file.
|
| +*/
|
| +
|
| +#include "GrBlend.h"
|
| +
|
| +/**
|
| + * MaskedColor is used to evaluate the color and valid color component flags through the
|
| + * blending equation. Could possibly extend this to be used more broadly.
|
| + */
|
| +class MaskedColor {
|
| +public:
|
| + MaskedColor(GrColor color, GrColorComponentFlags flags)
|
| + : fColor(color)
|
| + , fFlags(flags) {}
|
| +
|
| + MaskedColor() {}
|
| +
|
| + void set(GrColor color, GrColorComponentFlags flags) {
|
| + fColor = color;
|
| + fFlags = flags;
|
| + }
|
| +
|
| + static MaskedColor Invert(const MaskedColor& in) {
|
| + return MaskedColor(GrInvertColor(in.fColor), in.fFlags);
|
| + }
|
| +
|
| + static MaskedColor ExtractAlpha(const MaskedColor& in) {
|
| + GrColorComponentFlags flags = (in.fFlags & kA_GrColorComponentFlag) ?
|
| + kRGBA_GrColorComponentFlags : kNone_GrColorComponentFlags;
|
| + return MaskedColor(GrColorPackA4(GrColorUnpackA(in.fColor)), flags);
|
| + }
|
| +
|
| + static MaskedColor ExtractInverseAlpha(const MaskedColor& in) {
|
| + GrColorComponentFlags flags = (in.fFlags & kA_GrColorComponentFlag) ?
|
| + kRGBA_GrColorComponentFlags : kNone_GrColorComponentFlags;
|
| + return MaskedColor(GrColorPackA4(0xFF - GrColorUnpackA(in.fColor)), flags);
|
| + }
|
| +
|
| + static MaskedColor Mul(const MaskedColor& a, const MaskedColor& b) {
|
| + GrColorComponentFlags outFlags = (a.fFlags & b.fFlags) | a.componentsWithValue(0) |
|
| + b.componentsWithValue(0);
|
| + return MaskedColor(GrColorMul(a.fColor, b.fColor), outFlags);
|
| + }
|
| +
|
| + static MaskedColor SatAdd(const MaskedColor& a, const MaskedColor& b) {
|
| + GrColorComponentFlags outFlags = (a.fFlags & b.fFlags) | a.componentsWithValue(0xFF) |
|
| + b.componentsWithValue(0xFF);
|
| + return MaskedColor(GrColorSatAdd(a.fColor, b.fColor), outFlags);
|
| + }
|
| +
|
| + GrColor color() const { return fColor; }
|
| +
|
| + GrColorComponentFlags validFlags () const { return fFlags; }
|
| +
|
| +private:
|
| + GrColorComponentFlags componentsWithValue(unsigned value) const {
|
| + GrColorComponentFlags flags = kNone_GrColorComponentFlags;
|
| + if ((kR_GrColorComponentFlag & fFlags) && value == GrColorUnpackR(fColor)) {
|
| + flags |= kR_GrColorComponentFlag;
|
| + }
|
| + if ((kG_GrColorComponentFlag & fFlags) && value == GrColorUnpackG(fColor)) {
|
| + flags |= kG_GrColorComponentFlag;
|
| + }
|
| + if ((kB_GrColorComponentFlag & fFlags) && value == GrColorUnpackB(fColor)) {
|
| + flags |= kB_GrColorComponentFlag;
|
| + }
|
| + if ((kA_GrColorComponentFlag & fFlags) && value == GrColorUnpackA(fColor)) {
|
| + flags |= kA_GrColorComponentFlag;
|
| + }
|
| + return flags;
|
| + }
|
| +
|
| + GrColor fColor;
|
| + GrColorComponentFlags fFlags;
|
| +};
|
| +
|
| +static MaskedColor get_term(GrBlendCoeff coeff, const MaskedColor& src, const MaskedColor& dst,
|
| + const MaskedColor& value) {
|
| + switch (coeff) {
|
| + case kZero_GrBlendCoeff:
|
| + return MaskedColor(0, kRGBA_GrColorComponentFlags);
|
| + case kOne_GrBlendCoeff:
|
| + return value;
|
| + case kDC_GrBlendCoeff:
|
| + return MaskedColor::Mul(dst, value);
|
| + case kIDC_GrBlendCoeff:
|
| + return MaskedColor::Mul(MaskedColor::Invert(dst), value);
|
| + case kDA_GrBlendCoeff:
|
| + return MaskedColor::Mul(MaskedColor::ExtractAlpha(dst), value);
|
| + case kIDA_GrBlendCoeff:
|
| + return MaskedColor::Mul(MaskedColor::ExtractInverseAlpha(dst), value);
|
| + case kSC_GrBlendCoeff:
|
| + return MaskedColor::Mul(src, value);
|
| + case kISC_GrBlendCoeff:
|
| + return MaskedColor::Mul(MaskedColor::Invert(src), value);
|
| + case kSA_GrBlendCoeff:
|
| + return MaskedColor::Mul(MaskedColor::ExtractAlpha(src), value);
|
| + case kISA_GrBlendCoeff:
|
| + return MaskedColor::Mul(MaskedColor::ExtractInverseAlpha(src), value);
|
| + default:
|
| + SkFAIL("Illegal coefficient");
|
| + return MaskedColor();
|
| + }
|
| +}
|
| +
|
| +void GrGetCoeffBlendKnownComponents(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff,
|
| + GrColor srcColor, GrColorComponentFlags srcColorFlags,
|
| + GrColor dstColor, GrColorComponentFlags dstColorFlags,
|
| + GrColor* outColor,
|
| + GrColorComponentFlags* outFlags) {
|
| + MaskedColor src(srcColor, srcColorFlags);
|
| + MaskedColor dst(dstColor, dstColorFlags);
|
| +
|
| + MaskedColor srcTerm = get_term(srcCoeff, src, dst, src);
|
| + MaskedColor dstTerm = get_term(dstCoeff, src, dst, dst);
|
| +
|
| + MaskedColor output = MaskedColor::SatAdd(srcTerm, dstTerm);
|
| + *outColor = output.color();
|
| + *outFlags = output.validFlags();
|
| +}
|
|
|