gfx/skia/trunk/src/gpu/GrBlend.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/GrBlend.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,154 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2013 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +#include "GrBlend.h"
    1.13 +
    1.14 +static inline GrBlendCoeff swap_coeff_src_dst(GrBlendCoeff coeff) {
    1.15 +    switch (coeff) {
    1.16 +        case kDC_GrBlendCoeff:
    1.17 +            return kSC_GrBlendCoeff;
    1.18 +        case kIDC_GrBlendCoeff:
    1.19 +            return kISC_GrBlendCoeff;
    1.20 +        case kDA_GrBlendCoeff:
    1.21 +            return kSA_GrBlendCoeff;
    1.22 +        case kIDA_GrBlendCoeff:
    1.23 +            return kISA_GrBlendCoeff;
    1.24 +        case kSC_GrBlendCoeff:
    1.25 +            return kDC_GrBlendCoeff;
    1.26 +        case kISC_GrBlendCoeff:
    1.27 +            return kIDC_GrBlendCoeff;
    1.28 +        case kSA_GrBlendCoeff:
    1.29 +            return kDA_GrBlendCoeff;
    1.30 +        case kISA_GrBlendCoeff:
    1.31 +            return kIDA_GrBlendCoeff;
    1.32 +        default:
    1.33 +            return coeff;
    1.34 +    }
    1.35 +}
    1.36 +
    1.37 +static inline unsigned saturated_add(unsigned a, unsigned b) {
    1.38 +    SkASSERT(a <= 255);
    1.39 +    SkASSERT(b <= 255);
    1.40 +    unsigned sum = a + b;
    1.41 +    if (sum > 255) {
    1.42 +        sum = 255;
    1.43 +    }
    1.44 +    return sum;
    1.45 +}
    1.46 +
    1.47 +static GrColor add_colors(GrColor src, GrColor dst) {
    1.48 +    unsigned r = saturated_add(GrColorUnpackR(src), GrColorUnpackR(dst));
    1.49 +    unsigned g = saturated_add(GrColorUnpackG(src), GrColorUnpackG(dst));
    1.50 +    unsigned b = saturated_add(GrColorUnpackB(src), GrColorUnpackB(dst));
    1.51 +    unsigned a = saturated_add(GrColorUnpackA(src), GrColorUnpackA(dst));
    1.52 +    return GrColorPackRGBA(r, g, b, a);
    1.53 +}
    1.54 +
    1.55 +static inline bool valid_color(uint32_t compFlags) {
    1.56 +     return (kRGBA_GrColorComponentFlags & compFlags) == kRGBA_GrColorComponentFlags;
    1.57 +}
    1.58 +
    1.59 +static GrColor simplify_blend_term(GrBlendCoeff* srcCoeff,
    1.60 +                                   GrColor srcColor, uint32_t srcCompFlags,
    1.61 +                                   GrColor dstColor, uint32_t dstCompFlags,
    1.62 +                                   GrColor constantColor) {
    1.63 +
    1.64 +    SkASSERT(!GrBlendCoeffRefsSrc(*srcCoeff));
    1.65 +    SkASSERT(NULL != srcCoeff);
    1.66 +
    1.67 +    // Check whether srcCoeff can be reduced to kOne or kZero based on known color inputs.
    1.68 +    // We could pick out the coeff r,g,b,a values here and use them to compute the blend term color,
    1.69 +    // if possible, below but that is not implemented now.
    1.70 +    switch (*srcCoeff) {
    1.71 +        case kIDC_GrBlendCoeff:
    1.72 +            dstColor = ~dstColor; // fallthrough
    1.73 +        case kDC_GrBlendCoeff:
    1.74 +            if (valid_color(dstCompFlags)) {
    1.75 +                if (0xffffffff == dstColor) {
    1.76 +                    *srcCoeff = kOne_GrBlendCoeff;
    1.77 +                } else if (0 == dstColor) {
    1.78 +                    *srcCoeff = kZero_GrBlendCoeff;
    1.79 +                }
    1.80 +            }
    1.81 +            break;
    1.82 +
    1.83 +        case kIDA_GrBlendCoeff:
    1.84 +            dstColor = ~dstColor; // fallthrough
    1.85 +        case kDA_GrBlendCoeff:
    1.86 +            if (kA_GrColorComponentFlag & dstCompFlags) {
    1.87 +                if (0xff == GrColorUnpackA(dstColor)) {
    1.88 +                    *srcCoeff = kOne_GrBlendCoeff;
    1.89 +                } else if (0 == GrColorUnpackA(dstColor)) {
    1.90 +                    *srcCoeff = kZero_GrBlendCoeff;
    1.91 +                }
    1.92 +            }
    1.93 +            break;
    1.94 +
    1.95 +        case kIConstC_GrBlendCoeff:
    1.96 +            constantColor = ~constantColor; // fallthrough
    1.97 +        case kConstC_GrBlendCoeff:
    1.98 +            if (0xffffffff == constantColor) {
    1.99 +                *srcCoeff = kOne_GrBlendCoeff;
   1.100 +            } else if (0 == constantColor) {
   1.101 +                *srcCoeff = kZero_GrBlendCoeff;
   1.102 +            }
   1.103 +            break;
   1.104 +
   1.105 +        case kIConstA_GrBlendCoeff:
   1.106 +            constantColor = ~constantColor; // fallthrough
   1.107 +        case kConstA_GrBlendCoeff:
   1.108 +            if (0xff == GrColorUnpackA(constantColor)) {
   1.109 +                *srcCoeff = kOne_GrBlendCoeff;
   1.110 +            } else if (0 == GrColorUnpackA(constantColor)) {
   1.111 +                *srcCoeff = kZero_GrBlendCoeff;
   1.112 +            }
   1.113 +            break;
   1.114 +
   1.115 +        default:
   1.116 +            break;
   1.117 +    }
   1.118 +    // We may have invalidated these above and shouldn't read them again.
   1.119 +    SkDEBUGCODE(dstColor = constantColor = GrColor_ILLEGAL;)
   1.120 +
   1.121 +    if (kZero_GrBlendCoeff == *srcCoeff || (valid_color(srcCompFlags) && 0 == srcColor)) {
   1.122 +        *srcCoeff = kZero_GrBlendCoeff;
   1.123 +        return 0;
   1.124 +    }
   1.125 +
   1.126 +    if (kOne_GrBlendCoeff == *srcCoeff && valid_color(srcCompFlags)) {
   1.127 +        return srcColor;
   1.128 +    } else {
   1.129 +        return GrColor_ILLEGAL;
   1.130 +    }
   1.131 +}
   1.132 +
   1.133 +GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff,
   1.134 +                        GrBlendCoeff* dstCoeff,
   1.135 +                        GrColor srcColor, uint32_t srcCompFlags,
   1.136 +                        GrColor dstColor, uint32_t dstCompFlags,
   1.137 +                        GrColor constantColor) {
   1.138 +    GrColor srcTermColor = simplify_blend_term(srcCoeff,
   1.139 +                                               srcColor, srcCompFlags,
   1.140 +                                               dstColor, dstCompFlags,
   1.141 +                                               constantColor);
   1.142 +
   1.143 +    // We call the same function to simplify the dst blend coeff. We trick it out by swapping the
   1.144 +    // src and dst.
   1.145 +    GrBlendCoeff spoofedCoeff = swap_coeff_src_dst(*dstCoeff);
   1.146 +    GrColor dstTermColor = simplify_blend_term(&spoofedCoeff,
   1.147 +                                               dstColor, dstCompFlags,
   1.148 +                                               srcColor, srcCompFlags,
   1.149 +                                               constantColor);
   1.150 +    *dstCoeff = swap_coeff_src_dst(spoofedCoeff);
   1.151 +
   1.152 +    if (GrColor_ILLEGAL != srcTermColor && GrColor_ILLEGAL != dstTermColor) {
   1.153 +        return add_colors(srcTermColor, dstTermColor);
   1.154 +    } else {
   1.155 +        return GrColor_ILLEGAL;
   1.156 +    }
   1.157 +}

mercurial