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 +}