| Index: src/gpu/GrBlend.cpp
|
| diff --git a/src/gpu/GrBlend.cpp b/src/gpu/GrBlend.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c0621a9b3f81f8f05223430b200ea8710792e02d
|
| --- /dev/null
|
| +++ b/src/gpu/GrBlend.cpp
|
| @@ -0,0 +1,154 @@
|
| +
|
| +/*
|
| + * Copyright 2013 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"
|
| +
|
| +static inline GrBlendCoeff swap_coeff_src_dst(GrBlendCoeff coeff) {
|
| + switch (coeff) {
|
| + case kDC_GrBlendCoeff:
|
| + return kSC_GrBlendCoeff;
|
| + case kIDC_GrBlendCoeff:
|
| + return kISC_GrBlendCoeff;
|
| + case kDA_GrBlendCoeff:
|
| + return kSA_GrBlendCoeff;
|
| + case kIDA_GrBlendCoeff:
|
| + return kISA_GrBlendCoeff;
|
| + case kSC_GrBlendCoeff:
|
| + return kDC_GrBlendCoeff;
|
| + case kISC_GrBlendCoeff:
|
| + return kIDC_GrBlendCoeff;
|
| + case kSA_GrBlendCoeff:
|
| + return kDA_GrBlendCoeff;
|
| + case kISA_GrBlendCoeff:
|
| + return kIDA_GrBlendCoeff;
|
| + default:
|
| + return coeff;
|
| + }
|
| +}
|
| +
|
| +static inline unsigned saturated_add(unsigned a, unsigned b) {
|
| + SkASSERT(a <= 255);
|
| + SkASSERT(b <= 255);
|
| + unsigned sum = a + b;
|
| + if (sum > 255) {
|
| + sum = 255;
|
| + }
|
| + return sum;
|
| +}
|
| +
|
| +static GrColor add_colors(GrColor src, GrColor dst) {
|
| + unsigned r = saturated_add(GrColorUnpackR(src), GrColorUnpackR(dst));
|
| + unsigned g = saturated_add(GrColorUnpackG(src), GrColorUnpackG(dst));
|
| + unsigned b = saturated_add(GrColorUnpackB(src), GrColorUnpackB(dst));
|
| + unsigned a = saturated_add(GrColorUnpackA(src), GrColorUnpackA(dst));
|
| + return GrColorPackRGBA(r, g, b, a);
|
| +}
|
| +
|
| +static inline bool valid_color(uint32_t compFlags) {
|
| + return (kRGBA_GrColorComponentFlags & compFlags) == kRGBA_GrColorComponentFlags;
|
| +}
|
| +
|
| +static GrColor simplify_blend_term(GrBlendCoeff* srcCoeff,
|
| + GrColor srcColor, uint32_t srcCompFlags,
|
| + GrColor dstColor, uint32_t dstCompFlags,
|
| + GrColor constantColor) {
|
| +
|
| + GrAssert(!GrBlendCoeffRefsSrc(*srcCoeff));
|
| + GrAssert(NULL != srcCoeff);
|
| +
|
| + // Check whether srcCoeff can be reduced to kOne or kZero based on known color inputs.
|
| + // We could pick out the coeff r,g,b,a values here and use them to compute the blend term color,
|
| + // if possible, below but that is not implemented now.
|
| + switch (*srcCoeff) {
|
| + case kIDC_GrBlendCoeff:
|
| + dstColor = ~dstColor; // fallthrough
|
| + case kDC_GrBlendCoeff:
|
| + if (valid_color(dstCompFlags)) {
|
| + if (0xffffffff == dstColor) {
|
| + *srcCoeff = kOne_GrBlendCoeff;
|
| + } else if (0 == dstColor) {
|
| + *srcCoeff = kZero_GrBlendCoeff;
|
| + }
|
| + }
|
| + break;
|
| +
|
| + case kIDA_GrBlendCoeff:
|
| + dstColor = ~dstColor; // fallthrough
|
| + case kDA_GrBlendCoeff:
|
| + if (kA_GrColorComponentFlag & dstCompFlags) {
|
| + if (0xff == GrColorUnpackA(dstColor)) {
|
| + *srcCoeff = kOne_GrBlendCoeff;
|
| + } else if (0 == GrColorUnpackA(dstColor)) {
|
| + *srcCoeff = kZero_GrBlendCoeff;
|
| + }
|
| + }
|
| + break;
|
| +
|
| + case kIConstC_GrBlendCoeff:
|
| + constantColor = ~constantColor; // fallthrough
|
| + case kConstC_GrBlendCoeff:
|
| + if (0xffffffff == constantColor) {
|
| + *srcCoeff = kOne_GrBlendCoeff;
|
| + } else if (0 == constantColor) {
|
| + *srcCoeff = kZero_GrBlendCoeff;
|
| + }
|
| + break;
|
| +
|
| + case kIConstA_GrBlendCoeff:
|
| + constantColor = ~constantColor; // fallthrough
|
| + case kConstA_GrBlendCoeff:
|
| + if (0xff == GrColorUnpackA(constantColor)) {
|
| + *srcCoeff = kOne_GrBlendCoeff;
|
| + } else if (0 == GrColorUnpackA(constantColor)) {
|
| + *srcCoeff = kZero_GrBlendCoeff;
|
| + }
|
| + break;
|
| +
|
| + default:
|
| + break;
|
| + }
|
| + // We may have invalidated these above and shouldn't read them again.
|
| + GR_DEBUGCODE(dstColor = constantColor = GrColor_ILLEGAL;)
|
| +
|
| + if (kZero_GrBlendCoeff == *srcCoeff || (valid_color(srcCompFlags) && 0 == srcColor)) {
|
| + *srcCoeff = kZero_GrBlendCoeff;
|
| + return 0;
|
| + }
|
| +
|
| + if (kOne_GrBlendCoeff == *srcCoeff && valid_color(srcCompFlags)) {
|
| + return srcColor;
|
| + } else {
|
| + return GrColor_ILLEGAL;
|
| + }
|
| +}
|
| +
|
| +GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff,
|
| + GrBlendCoeff* dstCoeff,
|
| + GrColor srcColor, uint32_t srcCompFlags,
|
| + GrColor dstColor, uint32_t dstCompFlags,
|
| + GrColor constantColor) {
|
| + GrColor srcTermColor = simplify_blend_term(srcCoeff,
|
| + srcColor, srcCompFlags,
|
| + dstColor, dstCompFlags,
|
| + constantColor);
|
| +
|
| + // We call the same function to simplify the dst blend coeff. We trick it out by swapping the
|
| + // src and dst.
|
| + GrBlendCoeff spoofedCoeff = swap_coeff_src_dst(*dstCoeff);
|
| + GrColor dstTermColor = simplify_blend_term(&spoofedCoeff,
|
| + dstColor, dstCompFlags,
|
| + srcColor, srcCompFlags,
|
| + constantColor);
|
| + *dstCoeff = swap_coeff_src_dst(spoofedCoeff);
|
| +
|
| + if (GrColor_ILLEGAL != srcTermColor && GrColor_ILLEGAL != dstTermColor) {
|
| + return add_colors(srcTermColor, dstTermColor);
|
| + } else {
|
| + return GrColor_ILLEGAL;
|
| + }
|
| +}
|
|
|