1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "SkXfermode.h" 11 #include "SkXfermode_opts_SSE2.h" 12 #include "SkXfermode_proccoeff.h" 13 #include "SkColorPriv.h" 14 #include "SkLazyPtr.h" 15 #include "SkMathPriv.h" 16 #include "SkReadBuffer.h" 17 #include "SkString.h" 18 #include "SkUtilsArm.h" 19 #include "SkWriteBuffer.h" 20 21 #if !SK_ARM_NEON_IS_NONE 22 #include "SkXfermode_opts_arm_neon.h" 23 #endif 24 25 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 26 27 #if 0 28 // idea for higher precision blends in xfer procs (and slightly faster) 29 // see DstATop as a probable caller 30 static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { 31 SkASSERT(a <= 255); 32 SkASSERT(b <= 255); 33 SkASSERT(c <= 255); 34 SkASSERT(d <= 255); 35 unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128; 36 unsigned result = (prod + (prod >> 8)) >> 8; 37 SkASSERT(result <= 255); 38 return result; 39 } 40 #endif 41 42 static inline unsigned saturated_add(unsigned a, unsigned b) { 43 SkASSERT(a <= 255); 44 SkASSERT(b <= 255); 45 unsigned sum = a + b; 46 if (sum > 255) { 47 sum = 255; 48 } 49 return sum; 50 } 51 52 static inline int clamp_signed_byte(int n) { 53 if (n < 0) { 54 n = 0; 55 } else if (n > 255) { 56 n = 255; 57 } 58 return n; 59 } 60 61 static inline int clamp_div255round(int prod) { 62 if (prod <= 0) { 63 return 0; 64 } else if (prod >= 255*255) { 65 return 255; 66 } else { 67 return SkDiv255Round(prod); 68 } 69 } 70 71 /////////////////////////////////////////////////////////////////////////////// 72 73 // kClear_Mode, //!< [0, 0] 74 static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 75 return 0; 76 } 77 78 // kSrc_Mode, //!< [Sa, Sc] 79 static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 80 return src; 81 } 82 83 // kDst_Mode, //!< [Da, Dc] 84 static SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 85 return dst; 86 } 87 88 // kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 89 static SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 90 #if 0 91 // this is the old, more-correct way, but it doesn't guarantee that dst==255 92 // will always stay opaque 93 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 94 #else 95 // this is slightly faster, but more importantly guarantees that dst==255 96 // will always stay opaque 97 return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 98 #endif 99 } 100 101 // kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 102 static SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 103 // this is the reverse of srcover, just flipping src and dst 104 // see srcover's comment about the 256 for opaqueness guarantees 105 return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 106 } 107 108 // kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 109 static SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 110 return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 111 } 112 113 // kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 114 static SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 115 return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 116 } 117 118 // kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 119 static SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 120 return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 121 } 122 123 // kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 124 static SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 125 return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 126 } 127 128 // kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 129 static SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 130 unsigned sa = SkGetPackedA32(src); 131 unsigned da = SkGetPackedA32(dst); 132 unsigned isa = 255 - sa; 133 134 return SkPackARGB32(da, 135 SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 136 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 137 SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 138 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 139 SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 140 SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 141 } 142 143 // kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 144 static SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 145 unsigned sa = SkGetPackedA32(src); 146 unsigned da = SkGetPackedA32(dst); 147 unsigned ida = 255 - da; 148 149 return SkPackARGB32(sa, 150 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 151 SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 152 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 153 SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 154 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 155 SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 156 } 157 158 // kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 159 static SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 160 unsigned sa = SkGetPackedA32(src); 161 unsigned da = SkGetPackedA32(dst); 162 unsigned isa = 255 - sa; 163 unsigned ida = 255 - da; 164 165 return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 166 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 167 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 168 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 169 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 170 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 171 SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 172 } 173 174 /////////////////////////////////////////////////////////////////////////////// 175 176 // kPlus_Mode 177 static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 178 unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 179 unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 180 unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 181 unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 182 return SkPackARGB32(a, r, g, b); 183 } 184 185 // kModulate_Mode 186 static SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) { 187 int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 188 int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 189 int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 190 int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 191 return SkPackARGB32(a, r, g, b); 192 } 193 194 static inline int srcover_byte(int a, int b) { 195 return a + b - SkAlphaMulAlpha(a, b); 196 } 197 198 // kMultiply_Mode 199 // B(Cb, Cs) = Cb x Cs 200 // multiply uses its own version of blendfunc_byte because sa and da are not needed 201 static int blendfunc_multiply_byte(int sc, int dc, int sa, int da) { 202 return clamp_div255round(sc * (255 - da) + dc * (255 - sa) + sc * dc); 203 } 204 205 static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { 206 int sa = SkGetPackedA32(src); 207 int da = SkGetPackedA32(dst); 208 int a = srcover_byte(sa, da); 209 int r = blendfunc_multiply_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 210 int g = blendfunc_multiply_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 211 int b = blendfunc_multiply_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 212 return SkPackARGB32(a, r, g, b); 213 } 214 215 // kScreen_Mode 216 static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 217 int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 218 int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 219 int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 220 int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 221 return SkPackARGB32(a, r, g, b); 222 } 223 224 // kOverlay_Mode 225 static inline int overlay_byte(int sc, int dc, int sa, int da) { 226 int tmp = sc * (255 - da) + dc * (255 - sa); 227 int rc; 228 if (2 * dc <= da) { 229 rc = 2 * sc * dc; 230 } else { 231 rc = sa * da - 2 * (da - dc) * (sa - sc); 232 } 233 return clamp_div255round(rc + tmp); 234 } 235 static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 236 int sa = SkGetPackedA32(src); 237 int da = SkGetPackedA32(dst); 238 int a = srcover_byte(sa, da); 239 int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 240 int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 241 int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 242 return SkPackARGB32(a, r, g, b); 243 } 244 245 // kDarken_Mode 246 static inline int darken_byte(int sc, int dc, int sa, int da) { 247 int sd = sc * da; 248 int ds = dc * sa; 249 if (sd < ds) { 250 // srcover 251 return sc + dc - SkDiv255Round(ds); 252 } else { 253 // dstover 254 return dc + sc - SkDiv255Round(sd); 255 } 256 } 257 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 258 int sa = SkGetPackedA32(src); 259 int da = SkGetPackedA32(dst); 260 int a = srcover_byte(sa, da); 261 int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 262 int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 263 int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 264 return SkPackARGB32(a, r, g, b); 265 } 266 267 // kLighten_Mode 268 static inline int lighten_byte(int sc, int dc, int sa, int da) { 269 int sd = sc * da; 270 int ds = dc * sa; 271 if (sd > ds) { 272 // srcover 273 return sc + dc - SkDiv255Round(ds); 274 } else { 275 // dstover 276 return dc + sc - SkDiv255Round(sd); 277 } 278 } 279 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 280 int sa = SkGetPackedA32(src); 281 int da = SkGetPackedA32(dst); 282 int a = srcover_byte(sa, da); 283 int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 284 int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 285 int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 286 return SkPackARGB32(a, r, g, b); 287 } 288 289 // kColorDodge_Mode 290 static inline int colordodge_byte(int sc, int dc, int sa, int da) { 291 int diff = sa - sc; 292 int rc; 293 if (0 == dc) { 294 return SkAlphaMulAlpha(sc, 255 - da); 295 } else if (0 == diff) { 296 rc = sa * da + sc * (255 - da) + dc * (255 - sa); 297 } else { 298 diff = dc * sa / diff; 299 rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); 300 } 301 return clamp_div255round(rc); 302 } 303 static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 304 int sa = SkGetPackedA32(src); 305 int da = SkGetPackedA32(dst); 306 int a = srcover_byte(sa, da); 307 int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 308 int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 309 int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 310 return SkPackARGB32(a, r, g, b); 311 } 312 313 // kColorBurn_Mode 314 static inline int colorburn_byte(int sc, int dc, int sa, int da) { 315 int rc; 316 if (dc == da) { 317 rc = sa * da + sc * (255 - da) + dc * (255 - sa); 318 } else if (0 == sc) { 319 return SkAlphaMulAlpha(dc, 255 - sa); 320 } else { 321 int tmp = (da - dc) * sa / sc; 322 rc = sa * (da - ((da < tmp) ? da : tmp)) 323 + sc * (255 - da) + dc * (255 - sa); 324 } 325 return clamp_div255round(rc); 326 } 327 static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 328 int sa = SkGetPackedA32(src); 329 int da = SkGetPackedA32(dst); 330 int a = srcover_byte(sa, da); 331 int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 332 int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 333 int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 334 return SkPackARGB32(a, r, g, b); 335 } 336 337 // kHardLight_Mode 338 static inline int hardlight_byte(int sc, int dc, int sa, int da) { 339 int rc; 340 if (2 * sc <= sa) { 341 rc = 2 * sc * dc; 342 } else { 343 rc = sa * da - 2 * (da - dc) * (sa - sc); 344 } 345 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 346 } 347 static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 348 int sa = SkGetPackedA32(src); 349 int da = SkGetPackedA32(dst); 350 int a = srcover_byte(sa, da); 351 int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 352 int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 353 int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 354 return SkPackARGB32(a, r, g, b); 355 } 356 357 // returns 255 * sqrt(n/255) 358 static U8CPU sqrt_unit_byte(U8CPU n) { 359 return SkSqrtBits(n, 15+4); 360 } 361 362 // kSoftLight_Mode 363 static inline int softlight_byte(int sc, int dc, int sa, int da) { 364 int m = da ? dc * 256 / da : 0; 365 int rc; 366 if (2 * sc <= sa) { 367 rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 368 } else if (4 * dc <= da) { 369 int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 370 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 371 } else { 372 int tmp = sqrt_unit_byte(m) - m; 373 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 374 } 375 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 376 } 377 static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 378 int sa = SkGetPackedA32(src); 379 int da = SkGetPackedA32(dst); 380 int a = srcover_byte(sa, da); 381 int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 382 int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 383 int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 384 return SkPackARGB32(a, r, g, b); 385 } 386 387 // kDifference_Mode 388 static inline int difference_byte(int sc, int dc, int sa, int da) { 389 int tmp = SkMin32(sc * da, dc * sa); 390 return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 391 } 392 static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 393 int sa = SkGetPackedA32(src); 394 int da = SkGetPackedA32(dst); 395 int a = srcover_byte(sa, da); 396 int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 397 int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 398 int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 399 return SkPackARGB32(a, r, g, b); 400 } 401 402 // kExclusion_Mode 403 static inline int exclusion_byte(int sc, int dc, int, int) { 404 // this equations is wacky, wait for SVG to confirm it 405 //int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 406 407 // The above equation can be simplified as follows 408 int r = 255*(sc + dc) - 2 * sc * dc; 409 return clamp_div255round(r); 410 } 411 static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 412 int sa = SkGetPackedA32(src); 413 int da = SkGetPackedA32(dst); 414 int a = srcover_byte(sa, da); 415 int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 416 int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 417 int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 418 return SkPackARGB32(a, r, g, b); 419 } 420 421 // The CSS compositing spec introduces the following formulas: 422 // (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable) 423 // SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709 424 // while PDF and CG uses the one from Rec. Rec. 601 425 // See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm 426 static inline int Lum(int r, int g, int b) 427 { 428 return SkDiv255Round(r * 77 + g * 150 + b * 28); 429 } 430 431 static inline int min2(int a, int b) { return a < b ? a : b; } 432 static inline int max2(int a, int b) { return a > b ? a : b; } 433 #define minimum(a, b, c) min2(min2(a, b), c) 434 #define maximum(a, b, c) max2(max2(a, b), c) 435 436 static inline int Sat(int r, int g, int b) { 437 return maximum(r, g, b) - minimum(r, g, b); 438 } 439 440 static inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) { 441 if(*Cmax > *Cmin) { 442 *Cmid = SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin); 443 *Cmax = s; 444 } else { 445 *Cmax = 0; 446 *Cmid = 0; 447 } 448 449 *Cmin = 0; 450 } 451 452 static inline void SetSat(int* r, int* g, int* b, int s) { 453 if(*r <= *g) { 454 if(*g <= *b) { 455 setSaturationComponents(r, g, b, s); 456 } else if(*r <= *b) { 457 setSaturationComponents(r, b, g, s); 458 } else { 459 setSaturationComponents(b, r, g, s); 460 } 461 } else if(*r <= *b) { 462 setSaturationComponents(g, r, b, s); 463 } else if(*g <= *b) { 464 setSaturationComponents(g, b, r, s); 465 } else { 466 setSaturationComponents(b, g, r, s); 467 } 468 } 469 470 static inline void clipColor(int* r, int* g, int* b, int a) { 471 int L = Lum(*r, *g, *b); 472 int n = minimum(*r, *g, *b); 473 int x = maximum(*r, *g, *b); 474 int denom; 475 if ((n < 0) && (denom = L - n)) { // Compute denom and make sure it's non zero 476 *r = L + SkMulDiv(*r - L, L, denom); 477 *g = L + SkMulDiv(*g - L, L, denom); 478 *b = L + SkMulDiv(*b - L, L, denom); 479 } 480 481 if ((x > a) && (denom = x - L)) { // Compute denom and make sure it's non zero 482 int numer = a - L; 483 *r = L + SkMulDiv(*r - L, numer, denom); 484 *g = L + SkMulDiv(*g - L, numer, denom); 485 *b = L + SkMulDiv(*b - L, numer, denom); 486 } 487 } 488 489 static inline void SetLum(int* r, int* g, int* b, int a, int l) { 490 int d = l - Lum(*r, *g, *b); 491 *r += d; 492 *g += d; 493 *b += d; 494 495 clipColor(r, g, b, a); 496 } 497 498 // non-separable blend modes are done in non-premultiplied alpha 499 #define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \ 500 clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval) 501 502 // kHue_Mode 503 // B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)) 504 // Create a color with the hue of the source color and the saturation and luminosity of the backdrop color. 505 static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) { 506 int sr = SkGetPackedR32(src); 507 int sg = SkGetPackedG32(src); 508 int sb = SkGetPackedB32(src); 509 int sa = SkGetPackedA32(src); 510 511 int dr = SkGetPackedR32(dst); 512 int dg = SkGetPackedG32(dst); 513 int db = SkGetPackedB32(dst); 514 int da = SkGetPackedA32(dst); 515 int Sr, Sg, Sb; 516 517 if(sa && da) { 518 Sr = sr * sa; 519 Sg = sg * sa; 520 Sb = sb * sa; 521 SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); 522 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 523 } else { 524 Sr = 0; 525 Sg = 0; 526 Sb = 0; 527 } 528 529 int a = srcover_byte(sa, da); 530 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 531 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 532 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 533 return SkPackARGB32(a, r, g, b); 534 } 535 536 // kSaturation_Mode 537 // B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) 538 // Create a color with the saturation of the source color and the hue and luminosity of the backdrop color. 539 static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { 540 int sr = SkGetPackedR32(src); 541 int sg = SkGetPackedG32(src); 542 int sb = SkGetPackedB32(src); 543 int sa = SkGetPackedA32(src); 544 545 int dr = SkGetPackedR32(dst); 546 int dg = SkGetPackedG32(dst); 547 int db = SkGetPackedB32(dst); 548 int da = SkGetPackedA32(dst); 549 int Dr, Dg, Db; 550 551 if(sa && da) { 552 Dr = dr * sa; 553 Dg = dg * sa; 554 Db = db * sa; 555 SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); 556 SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); 557 } else { 558 Dr = 0; 559 Dg = 0; 560 Db = 0; 561 } 562 563 int a = srcover_byte(sa, da); 564 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 565 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 566 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 567 return SkPackARGB32(a, r, g, b); 568 } 569 570 // kColor_Mode 571 // B(Cb, Cs) = SetLum(Cs, Lum(Cb)) 572 // Create a color with the hue and saturation of the source color and the luminosity of the backdrop color. 573 static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { 574 int sr = SkGetPackedR32(src); 575 int sg = SkGetPackedG32(src); 576 int sb = SkGetPackedB32(src); 577 int sa = SkGetPackedA32(src); 578 579 int dr = SkGetPackedR32(dst); 580 int dg = SkGetPackedG32(dst); 581 int db = SkGetPackedB32(dst); 582 int da = SkGetPackedA32(dst); 583 int Sr, Sg, Sb; 584 585 if(sa && da) { 586 Sr = sr * da; 587 Sg = sg * da; 588 Sb = sb * da; 589 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 590 } else { 591 Sr = 0; 592 Sg = 0; 593 Sb = 0; 594 } 595 596 int a = srcover_byte(sa, da); 597 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 598 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 599 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 600 return SkPackARGB32(a, r, g, b); 601 } 602 603 // kLuminosity_Mode 604 // B(Cb, Cs) = SetLum(Cb, Lum(Cs)) 605 // Create a color with the luminosity of the source color and the hue and saturation of the backdrop color. 606 static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { 607 int sr = SkGetPackedR32(src); 608 int sg = SkGetPackedG32(src); 609 int sb = SkGetPackedB32(src); 610 int sa = SkGetPackedA32(src); 611 612 int dr = SkGetPackedR32(dst); 613 int dg = SkGetPackedG32(dst); 614 int db = SkGetPackedB32(dst); 615 int da = SkGetPackedA32(dst); 616 int Dr, Dg, Db; 617 618 if(sa && da) { 619 Dr = dr * sa; 620 Dg = dg * sa; 621 Db = db * sa; 622 SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); 623 } else { 624 Dr = 0; 625 Dg = 0; 626 Db = 0; 627 } 628 629 int a = srcover_byte(sa, da); 630 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 631 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 632 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 633 return SkPackARGB32(a, r, g, b); 634 } 635 636 const ProcCoeff gProcCoeffs[] = { 637 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 638 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 639 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 640 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 641 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 642 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 643 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 644 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 645 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 646 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 647 { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 648 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 649 650 { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 651 { modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 652 { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, 653 { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 654 { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 655 { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 656 { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 657 { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 658 { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 659 { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 660 { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 661 { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 662 { multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 663 { hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 664 { saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 665 { color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 666 { luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 667 }; 668 669 /////////////////////////////////////////////////////////////////////////////// 670 671 bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const { 672 return false; 673 } 674 675 bool SkXfermode::asMode(Mode* mode) const { 676 return false; 677 } 678 679 bool SkXfermode::asFragmentProcessor(GrFragmentProcessor**, GrTexture*) const { 680 return false; 681 } 682 683 bool SkXfermode::asFragmentProcessorOrCoeff(SkXfermode* xfermode, GrFragmentProcessor** fp, 684 Coeff* src, Coeff* dst, GrTexture* background) { 685 if (NULL == xfermode) { 686 return ModeAsCoeff(kSrcOver_Mode, src, dst); 687 } else if (xfermode->asCoeff(src, dst)) { 688 return true; 689 } else { 690 return xfermode->asFragmentProcessor(fp, background); 691 } 692 } 693 694 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 695 // no-op. subclasses should override this 696 return dst; 697 } 698 699 void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 700 const SkPMColor* SK_RESTRICT src, int count, 701 const SkAlpha* SK_RESTRICT aa) const { 702 SkASSERT(dst && src && count >= 0); 703 704 if (NULL == aa) { 705 for (int i = count - 1; i >= 0; --i) { 706 dst[i] = this->xferColor(src[i], dst[i]); 707 } 708 } else { 709 for (int i = count - 1; i >= 0; --i) { 710 unsigned a = aa[i]; 711 if (0 != a) { 712 SkPMColor dstC = dst[i]; 713 SkPMColor C = this->xferColor(src[i], dstC); 714 if (0xFF != a) { 715 C = SkFourByteInterp(C, dstC, a); 716 } 717 dst[i] = C; 718 } 719 } 720 } 721 } 722 723 void SkXfermode::xfer16(uint16_t* dst, 724 const SkPMColor* SK_RESTRICT src, int count, 725 const SkAlpha* SK_RESTRICT aa) const { 726 SkASSERT(dst && src && count >= 0); 727 728 if (NULL == aa) { 729 for (int i = count - 1; i >= 0; --i) { 730 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 731 dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 732 } 733 } else { 734 for (int i = count - 1; i >= 0; --i) { 735 unsigned a = aa[i]; 736 if (0 != a) { 737 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 738 SkPMColor C = this->xferColor(src[i], dstC); 739 if (0xFF != a) { 740 C = SkFourByteInterp(C, dstC, a); 741 } 742 dst[i] = SkPixel32ToPixel16_ToU16(C); 743 } 744 } 745 } 746 } 747 748 void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 749 const SkPMColor src[], int count, 750 const SkAlpha* SK_RESTRICT aa) const { 751 SkASSERT(dst && src && count >= 0); 752 753 if (NULL == aa) { 754 for (int i = count - 1; i >= 0; --i) { 755 SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 756 dst[i] = SkToU8(SkGetPackedA32(res)); 757 } 758 } else { 759 for (int i = count - 1; i >= 0; --i) { 760 unsigned a = aa[i]; 761 if (0 != a) { 762 SkAlpha dstA = dst[i]; 763 unsigned A = SkGetPackedA32(this->xferColor(src[i], 764 (SkPMColor)(dstA << SK_A32_SHIFT))); 765 if (0xFF != a) { 766 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 767 } 768 dst[i] = SkToU8(A); 769 } 770 } 771 } 772 } 773 774 ////////////////////////////////////////////////////////////////////////////// 775 776 #if SK_SUPPORT_GPU 777 778 #include "GrProcessor.h" 779 #include "GrCoordTransform.h" 780 #include "GrProcessorUnitTest.h" 781 #include "GrTBackendProcessorFactory.h" 782 #include "gl/GrGLProcessor.h" 783 #include "gl/builders/GrGLProgramBuilder.h" 784 785 /** 786 * GrProcessor that implements the all the separable xfer modes that cannot be expressed as Coeffs. 787 */ 788 class XferEffect : public GrFragmentProcessor { 789 public: 790 static bool IsSupportedMode(SkXfermode::Mode mode) { 791 return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode; 792 } 793 794 static GrFragmentProcessor* Create(SkXfermode::Mode mode, GrTexture* background) { 795 if (!IsSupportedMode(mode)) { 796 return NULL; 797 } else { 798 return SkNEW_ARGS(XferEffect, (mode, background)); 799 } 800 } 801 802 virtual void getConstantColorComponents(GrColor* color, 803 uint32_t* validFlags) const SK_OVERRIDE { 804 *validFlags = 0; 805 } 806 807 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE { 808 return GrTBackendFragmentProcessorFactory<XferEffect>::getInstance(); 809 } 810 811 static const char* Name() { return "XferEffect"; } 812 813 SkXfermode::Mode mode() const { return fMode; } 814 const GrTextureAccess& backgroundAccess() const { return fBackgroundAccess; } 815 816 class GLProcessor : public GrGLFragmentProcessor { 817 public: 818 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&) 819 : INHERITED(factory) { 820 } 821 virtual void emitCode(GrGLProgramBuilder* builder, 822 const GrFragmentProcessor& fp, 823 const GrProcessorKey& key, 824 const char* outputColor, 825 const char* inputColor, 826 const TransformedCoordsArray& coords, 827 const TextureSamplerArray& samplers) SK_OVERRIDE { 828 SkXfermode::Mode mode = fp.cast<XferEffect>().mode(); 829 const GrTexture* backgroundTex = 830 fp.cast<XferEffect>().backgroundAccess().getTexture(); 831 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 832 const char* dstColor; 833 if (backgroundTex) { 834 dstColor = "bgColor"; 835 fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor); 836 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType()); 837 fsBuilder->codeAppendf(";\n"); 838 } else { 839 dstColor = fsBuilder->dstColor(); 840 } 841 SkASSERT(dstColor); 842 843 // We don't try to optimize for this case at all 844 if (NULL == inputColor) { 845 fsBuilder->codeAppendf("\t\tconst vec4 ones = vec4(1);\n"); 846 inputColor = "ones"; 847 } 848 fsBuilder->codeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode)); 849 850 // These all perform src-over on the alpha channel. 851 fsBuilder->codeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n", 852 outputColor, inputColor, inputColor, dstColor); 853 854 switch (mode) { 855 case SkXfermode::kOverlay_Mode: 856 // Overlay is Hard-Light with the src and dst reversed 857 HardLight(fsBuilder, outputColor, dstColor, inputColor); 858 break; 859 case SkXfermode::kDarken_Mode: 860 fsBuilder->codeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, " 861 "(1.0 - %s.a) * %s.rgb + %s.rgb);\n", 862 outputColor, 863 inputColor, dstColor, inputColor, 864 dstColor, inputColor, dstColor); 865 break; 866 case SkXfermode::kLighten_Mode: 867 fsBuilder->codeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, " 868 "(1.0 - %s.a) * %s.rgb + %s.rgb);\n", 869 outputColor, 870 inputColor, dstColor, inputColor, 871 dstColor, inputColor, dstColor); 872 break; 873 case SkXfermode::kColorDodge_Mode: 874 ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'r'); 875 ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'g'); 876 ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'b'); 877 break; 878 case SkXfermode::kColorBurn_Mode: 879 ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'r'); 880 ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'g'); 881 ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'b'); 882 break; 883 case SkXfermode::kHardLight_Mode: 884 HardLight(fsBuilder, outputColor, inputColor, dstColor); 885 break; 886 case SkXfermode::kSoftLight_Mode: 887 fsBuilder->codeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor); 888 fsBuilder->codeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor); 889 fsBuilder->codeAppendf("\t\t} else {\n"); 890 SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'r'); 891 SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'g'); 892 SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'b'); 893 fsBuilder->codeAppendf("\t\t}\n"); 894 break; 895 case SkXfermode::kDifference_Mode: 896 fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -" 897 "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n", 898 outputColor, inputColor, dstColor, inputColor, dstColor, 899 dstColor, inputColor); 900 break; 901 case SkXfermode::kExclusion_Mode: 902 fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - " 903 "2.0 * %s.rgb * %s.rgb;\n", 904 outputColor, dstColor, inputColor, dstColor, inputColor); 905 break; 906 case SkXfermode::kMultiply_Mode: 907 fsBuilder->codeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + " 908 "(1.0 - %s.a) * %s.rgb + " 909 "%s.rgb * %s.rgb;\n", 910 outputColor, inputColor, dstColor, dstColor, inputColor, 911 inputColor, dstColor); 912 break; 913 case SkXfermode::kHue_Mode: { 914 // SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S 915 SkString setSat, setLum; 916 AddSatFunction(fsBuilder, &setSat); 917 AddLumFunction(fsBuilder, &setLum); 918 fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n", 919 dstColor, inputColor); 920 fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n", 921 outputColor, setLum.c_str(), setSat.c_str(), inputColor, 922 dstColor); 923 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 924 outputColor, inputColor, dstColor, dstColor, inputColor); 925 break; 926 } 927 case SkXfermode::kSaturation_Mode: { 928 // SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S 929 SkString setSat, setLum; 930 AddSatFunction(fsBuilder, &setSat); 931 AddLumFunction(fsBuilder, &setLum); 932 fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n", 933 dstColor, inputColor); 934 fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n", 935 outputColor, setLum.c_str(), setSat.c_str(), inputColor, 936 dstColor); 937 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 938 outputColor, inputColor, dstColor, dstColor, inputColor); 939 break; 940 } 941 case SkXfermode::kColor_Mode: { 942 // SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S 943 SkString setLum; 944 AddLumFunction(fsBuilder, &setLum); 945 fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n", 946 inputColor, dstColor); 947 fsBuilder->codeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n", 948 outputColor, setLum.c_str(), dstColor, inputColor); 949 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 950 outputColor, inputColor, dstColor, dstColor, inputColor); 951 break; 952 } 953 case SkXfermode::kLuminosity_Mode: { 954 // SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S 955 SkString setLum; 956 AddLumFunction(fsBuilder, &setLum); 957 fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n", 958 inputColor, dstColor); 959 fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n", 960 outputColor, setLum.c_str(), dstColor, inputColor); 961 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n", 962 outputColor, inputColor, dstColor, dstColor, inputColor); 963 break; 964 } 965 default: 966 SkFAIL("Unknown XferEffect mode."); 967 break; 968 } 969 } 970 971 static inline void GenKey(const GrProcessor& proc, const GrGLCaps&, 972 GrProcessorKeyBuilder* b) { 973 // The background may come from the dst or from a texture. 974 uint32_t key = proc.numTextures(); 975 SkASSERT(key <= 1); 976 key |= proc.cast<XferEffect>().mode() << 1; 977 b->add32(key); 978 } 979 980 private: 981 static void HardLight(GrGLFragmentShaderBuilder* fsBuilder, 982 const char* final, 983 const char* src, 984 const char* dst) { 985 static const char kComponents[] = {'r', 'g', 'b'}; 986 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) { 987 char component = kComponents[i]; 988 fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src); 989 fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component); 990 fsBuilder->codeAppend("\t\t} else {\n"); 991 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n", 992 final, component, src, dst, dst, dst, component, src, src, component); 993 fsBuilder->codeAppend("\t\t}\n"); 994 } 995 fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n", 996 final, src, dst, dst, src); 997 } 998 999 // Does one component of color-dodge 1000 static void ColorDodgeComponent(GrGLFragmentShaderBuilder* fsBuilder, 1001 const char* final, 1002 const char* src, 1003 const char* dst, 1004 const char component) { 1005 fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component); 1006 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", 1007 final, component, src, component, dst); 1008 fsBuilder->codeAppend("\t\t} else {\n"); 1009 fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component); 1010 fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n"); 1011 fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 1012 final, component, src, dst, src, component, dst, dst, component, 1013 src); 1014 fsBuilder->codeAppend("\t\t\t} else {\n"); 1015 fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n", 1016 dst, dst, component, src); 1017 fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 1018 final, component, src, src, component, dst, dst, component, src); 1019 fsBuilder->codeAppend("\t\t\t}\n"); 1020 fsBuilder->codeAppend("\t\t}\n"); 1021 } 1022 1023 // Does one component of color-burn 1024 static void ColorBurnComponent(GrGLFragmentShaderBuilder* fsBuilder, 1025 const char* final, 1026 const char* src, 1027 const char* dst, 1028 const char component) { 1029 fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component); 1030 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 1031 final, component, src, dst, src, component, dst, dst, component, 1032 src); 1033 fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component); 1034 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", 1035 final, component, dst, component, src); 1036 fsBuilder->codeAppend("\t\t} else {\n"); 1037 fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n", 1038 dst, dst, dst, component, src, src, component); 1039 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", 1040 final, component, src, src, component, dst, dst, component, src); 1041 fsBuilder->codeAppend("\t\t}\n"); 1042 } 1043 1044 // Does one component of soft-light. Caller should have already checked that dst alpha > 0. 1045 static void SoftLightComponentPosDstAlpha(GrGLFragmentShaderBuilder* fsBuilder, 1046 const char* final, 1047 const char* src, 1048 const char* dst, 1049 const char component) { 1050 // if (2S < Sa) 1051 fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src); 1052 // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1) 1053 fsBuilder->codeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n", 1054 final, component, dst, component, dst, component, src, src, 1055 component, dst, dst, src, component, dst, component, src, src, 1056 component); 1057 // else if (4D < Da) 1058 fsBuilder->codeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n", 1059 dst, component, dst); 1060 fsBuilder->codeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n", 1061 dst, component, dst, component); 1062 fsBuilder->codeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component); 1063 fsBuilder->codeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst); 1064 fsBuilder->codeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst); 1065 // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa-2 S))/Da^2 1066 fsBuilder->codeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n", 1067 final, component, src, component, src, component, dst, component, 1068 src, src, component, dst, src, src, component, src, src, 1069 component); 1070 fsBuilder->codeAppendf("\t\t\t} else {\n"); 1071 // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S 1072 fsBuilder->codeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n", 1073 final, component, dst, dst, component, src, src, component, dst, 1074 src, component, dst, component, src, src, component, src, 1075 component); 1076 fsBuilder->codeAppendf("\t\t\t}\n"); 1077 } 1078 1079 // Adds a function that takes two colors and an alpha as input. It produces a color with the 1080 // hue and saturation of the first color, the luminosity of the second color, and the input 1081 // alpha. It has this signature: 1082 // vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor). 1083 static void AddLumFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setLumFunction) { 1084 // Emit a helper that gets the luminance of a color. 1085 SkString getFunction; 1086 GrGLShaderVar getLumArgs[] = { 1087 GrGLShaderVar("color", kVec3f_GrSLType), 1088 }; 1089 SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n"); 1090 fsBuilder->emitFunction(kFloat_GrSLType, 1091 "luminance", 1092 SK_ARRAY_COUNT(getLumArgs), getLumArgs, 1093 getLumBody.c_str(), 1094 &getFunction); 1095 1096 // Emit the set luminance function. 1097 GrGLShaderVar setLumArgs[] = { 1098 GrGLShaderVar("hueSat", kVec3f_GrSLType), 1099 GrGLShaderVar("alpha", kFloat_GrSLType), 1100 GrGLShaderVar("lumColor", kVec3f_GrSLType), 1101 }; 1102 SkString setLumBody; 1103 setLumBody.printf("\tfloat diff = %s(lumColor - hueSat);\n", getFunction.c_str()); 1104 setLumBody.append("\tvec3 outColor = hueSat + diff;\n"); 1105 setLumBody.appendf("\tfloat outLum = %s(outColor);\n", getFunction.c_str()); 1106 setLumBody.append("\tfloat minComp = min(min(outColor.r, outColor.g), outColor.b);\n" 1107 "\tfloat maxComp = max(max(outColor.r, outColor.g), outColor.b);\n" 1108 "\tif (minComp < 0.0) {\n" 1109 "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * outLum) / (outLum - minComp);\n" 1110 "\t}\n" 1111 "\tif (maxComp > alpha) {\n" 1112 "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / (maxComp - outLum);\n" 1113 "\t}\n" 1114 "\treturn outColor;\n"); 1115 fsBuilder->emitFunction(kVec3f_GrSLType, 1116 "set_luminance", 1117 SK_ARRAY_COUNT(setLumArgs), setLumArgs, 1118 setLumBody.c_str(), 1119 setLumFunction); 1120 } 1121 1122 // Adds a function that creates a color with the hue and luminosity of one input color and 1123 // the saturation of another color. It will have this signature: 1124 // float set_saturation(vec3 hueLumColor, vec3 satColor) 1125 static void AddSatFunction(GrGLFragmentShaderBuilder* fsBuilder, SkString* setSatFunction) { 1126 // Emit a helper that gets the saturation of a color 1127 SkString getFunction; 1128 GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLType) }; 1129 SkString getSatBody; 1130 getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - " 1131 "min(min(color.r, color.g), color.b);\n"); 1132 fsBuilder->emitFunction(kFloat_GrSLType, 1133 "saturation", 1134 SK_ARRAY_COUNT(getSatArgs), getSatArgs, 1135 getSatBody.c_str(), 1136 &getFunction); 1137 1138 // Emit a helper that sets the saturation given sorted input channels. This used 1139 // to use inout params for min, mid, and max components but that seems to cause 1140 // problems on PowerVR drivers. So instead it returns a vec3 where r, g ,b are the 1141 // adjusted min, mid, and max inputs, respectively. 1142 SkString helperFunction; 1143 GrGLShaderVar helperArgs[] = { 1144 GrGLShaderVar("minComp", kFloat_GrSLType), 1145 GrGLShaderVar("midComp", kFloat_GrSLType), 1146 GrGLShaderVar("maxComp", kFloat_GrSLType), 1147 GrGLShaderVar("sat", kFloat_GrSLType), 1148 }; 1149 static const char kHelperBody[] = "\tif (minComp < maxComp) {\n" 1150 "\t\tvec3 result;\n" 1151 "\t\tresult.r = 0.0;\n" 1152 "\t\tresult.g = sat * (midComp - minComp) / (maxComp - minComp);\n" 1153 "\t\tresult.b = sat;\n" 1154 "\t\treturn result;\n" 1155 "\t} else {\n" 1156 "\t\treturn vec3(0, 0, 0);\n" 1157 "\t}\n"; 1158 fsBuilder->emitFunction(kVec3f_GrSLType, 1159 "set_saturation_helper", 1160 SK_ARRAY_COUNT(helperArgs), helperArgs, 1161 kHelperBody, 1162 &helperFunction); 1163 1164 GrGLShaderVar setSatArgs[] = { 1165 GrGLShaderVar("hueLumColor", kVec3f_GrSLType), 1166 GrGLShaderVar("satColor", kVec3f_GrSLType), 1167 }; 1168 const char* helpFunc = helperFunction.c_str(); 1169 SkString setSatBody; 1170 setSatBody.appendf("\tfloat sat = %s(satColor);\n" 1171 "\tif (hueLumColor.r <= hueLumColor.g) {\n" 1172 "\t\tif (hueLumColor.g <= hueLumColor.b) {\n" 1173 "\t\t\thueLumColor.rgb = %s(hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);\n" 1174 "\t\t} else if (hueLumColor.r <= hueLumColor.b) {\n" 1175 "\t\t\thueLumColor.rbg = %s(hueLumColor.r, hueLumColor.b, hueLumColor.g, sat);\n" 1176 "\t\t} else {\n" 1177 "\t\t\thueLumColor.brg = %s(hueLumColor.b, hueLumColor.r, hueLumColor.g, sat);\n" 1178 "\t\t}\n" 1179 "\t} else if (hueLumColor.r <= hueLumColor.b) {\n" 1180 "\t\thueLumColor.grb = %s(hueLumColor.g, hueLumColor.r, hueLumColor.b, sat);\n" 1181 "\t} else if (hueLumColor.g <= hueLumColor.b) {\n" 1182 "\t\thueLumColor.gbr = %s(hueLumColor.g, hueLumColor.b, hueLumColor.r, sat);\n" 1183 "\t} else {\n" 1184 "\t\thueLumColor.bgr = %s(hueLumColor.b, hueLumColor.g, hueLumColor.r, sat);\n" 1185 "\t}\n" 1186 "\treturn hueLumColor;\n", 1187 getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc, 1188 helpFunc, helpFunc); 1189 fsBuilder->emitFunction(kVec3f_GrSLType, 1190 "set_saturation", 1191 SK_ARRAY_COUNT(setSatArgs), setSatArgs, 1192 setSatBody.c_str(), 1193 setSatFunction); 1194 1195 } 1196 1197 typedef GrGLFragmentProcessor INHERITED; 1198 }; 1199 1200 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 1201 1202 private: 1203 XferEffect(SkXfermode::Mode mode, GrTexture* background) 1204 : fMode(mode) { 1205 if (background) { 1206 fBackgroundTransform.reset(kLocal_GrCoordSet, background); 1207 this->addCoordTransform(&fBackgroundTransform); 1208 fBackgroundAccess.reset(background); 1209 this->addTextureAccess(&fBackgroundAccess); 1210 } else { 1211 this->setWillReadDstColor(); 1212 } 1213 } 1214 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { 1215 const XferEffect& s = other.cast<XferEffect>(); 1216 return fMode == s.fMode && 1217 fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture(); 1218 } 1219 1220 SkXfermode::Mode fMode; 1221 GrCoordTransform fBackgroundTransform; 1222 GrTextureAccess fBackgroundAccess; 1223 1224 typedef GrFragmentProcessor INHERITED; 1225 }; 1226 1227 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(XferEffect); 1228 GrFragmentProcessor* XferEffect::TestCreate(SkRandom* rand, 1229 GrContext*, 1230 const GrDrawTargetCaps&, 1231 GrTexture*[]) { 1232 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLastSeparableMode); 1233 1234 return SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL)); 1235 } 1236 1237 #endif 1238 1239 /////////////////////////////////////////////////////////////////////////////// 1240 /////////////////////////////////////////////////////////////////////////////// 1241 1242 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1243 SkProcCoeffXfermode::SkProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) { 1244 uint32_t mode32 = buffer.read32() % SK_ARRAY_COUNT(gProcCoeffs); 1245 if (mode32 >= SK_ARRAY_COUNT(gProcCoeffs)) { 1246 // out of range, just set to something harmless 1247 mode32 = SkXfermode::kSrcOut_Mode; 1248 } 1249 fMode = (SkXfermode::Mode)mode32; 1250 1251 const ProcCoeff& rec = gProcCoeffs[fMode]; 1252 fProc = rec.fProc; 1253 // these may be valid, or may be CANNOT_USE_COEFF 1254 fSrcCoeff = rec.fSC; 1255 fDstCoeff = rec.fDC; 1256 } 1257 #endif 1258 1259 SkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) { 1260 uint32_t mode32 = buffer.read32(); 1261 if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) { 1262 return NULL; 1263 } 1264 return SkXfermode::Create((SkXfermode::Mode)mode32); 1265 } 1266 1267 void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const { 1268 buffer.write32(fMode); 1269 } 1270 1271 bool SkProcCoeffXfermode::asMode(Mode* mode) const { 1272 if (mode) { 1273 *mode = fMode; 1274 } 1275 return true; 1276 } 1277 1278 bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const { 1279 if (CANNOT_USE_COEFF == fSrcCoeff) { 1280 return false; 1281 } 1282 1283 if (sc) { 1284 *sc = fSrcCoeff; 1285 } 1286 if (dc) { 1287 *dc = fDstCoeff; 1288 } 1289 return true; 1290 } 1291 1292 void SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1293 const SkPMColor* SK_RESTRICT src, int count, 1294 const SkAlpha* SK_RESTRICT aa) const { 1295 SkASSERT(dst && src && count >= 0); 1296 1297 SkXfermodeProc proc = fProc; 1298 1299 if (proc) { 1300 if (NULL == aa) { 1301 for (int i = count - 1; i >= 0; --i) { 1302 dst[i] = proc(src[i], dst[i]); 1303 } 1304 } else { 1305 for (int i = count - 1; i >= 0; --i) { 1306 unsigned a = aa[i]; 1307 if (0 != a) { 1308 SkPMColor dstC = dst[i]; 1309 SkPMColor C = proc(src[i], dstC); 1310 if (a != 0xFF) { 1311 C = SkFourByteInterp(C, dstC, a); 1312 } 1313 dst[i] = C; 1314 } 1315 } 1316 } 1317 } 1318 } 1319 1320 void SkProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst, 1321 const SkPMColor* SK_RESTRICT src, int count, 1322 const SkAlpha* SK_RESTRICT aa) const { 1323 SkASSERT(dst && src && count >= 0); 1324 1325 SkXfermodeProc proc = fProc; 1326 1327 if (proc) { 1328 if (NULL == aa) { 1329 for (int i = count - 1; i >= 0; --i) { 1330 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1331 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 1332 } 1333 } else { 1334 for (int i = count - 1; i >= 0; --i) { 1335 unsigned a = aa[i]; 1336 if (0 != a) { 1337 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1338 SkPMColor C = proc(src[i], dstC); 1339 if (0xFF != a) { 1340 C = SkFourByteInterp(C, dstC, a); 1341 } 1342 dst[i] = SkPixel32ToPixel16_ToU16(C); 1343 } 1344 } 1345 } 1346 } 1347 } 1348 1349 void SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1350 const SkPMColor* SK_RESTRICT src, int count, 1351 const SkAlpha* SK_RESTRICT aa) const { 1352 SkASSERT(dst && src && count >= 0); 1353 1354 SkXfermodeProc proc = fProc; 1355 1356 if (proc) { 1357 if (NULL == aa) { 1358 for (int i = count - 1; i >= 0; --i) { 1359 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 1360 dst[i] = SkToU8(SkGetPackedA32(res)); 1361 } 1362 } else { 1363 for (int i = count - 1; i >= 0; --i) { 1364 unsigned a = aa[i]; 1365 if (0 != a) { 1366 SkAlpha dstA = dst[i]; 1367 SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 1368 unsigned A = SkGetPackedA32(res); 1369 if (0xFF != a) { 1370 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 1371 } 1372 dst[i] = SkToU8(A); 1373 } 1374 } 1375 } 1376 } 1377 } 1378 1379 #if SK_SUPPORT_GPU 1380 bool SkProcCoeffXfermode::asFragmentProcessor(GrFragmentProcessor** fp, 1381 GrTexture* background) const { 1382 if (XferEffect::IsSupportedMode(fMode)) { 1383 if (fp) { 1384 *fp = XferEffect::Create(fMode, background); 1385 SkASSERT(*fp); 1386 } 1387 return true; 1388 } 1389 return false; 1390 } 1391 #endif 1392 1393 const char* SkXfermode::ModeName(Mode mode) { 1394 SkASSERT((unsigned) mode <= (unsigned)kLastMode); 1395 const char* gModeStrings[] = { 1396 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 1397 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 1398 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 1399 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", 1400 "Multiply", "Hue", "Saturation", "Color", "Luminosity" 1401 }; 1402 return gModeStrings[mode]; 1403 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, mode_count); 1404 } 1405 1406 #ifndef SK_IGNORE_TO_STRING 1407 void SkProcCoeffXfermode::toString(SkString* str) const { 1408 str->append("SkProcCoeffXfermode: "); 1409 1410 str->append("mode: "); 1411 str->append(ModeName(fMode)); 1412 1413 static const char* gCoeffStrings[kCoeffCount] = { 1414 "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA" 1415 }; 1416 1417 str->append(" src: "); 1418 if (CANNOT_USE_COEFF == fSrcCoeff) { 1419 str->append("can't use"); 1420 } else { 1421 str->append(gCoeffStrings[fSrcCoeff]); 1422 } 1423 1424 str->append(" dst: "); 1425 if (CANNOT_USE_COEFF == fDstCoeff) { 1426 str->append("can't use"); 1427 } else { 1428 str->append(gCoeffStrings[fDstCoeff]); 1429 } 1430 } 1431 #endif 1432 1433 /////////////////////////////////////////////////////////////////////////////// 1434 1435 class SkClearXfermode : public SkProcCoeffXfermode { 1436 public: 1437 static SkClearXfermode* Create(const ProcCoeff& rec) { 1438 return SkNEW_ARGS(SkClearXfermode, (rec)); 1439 } 1440 1441 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1442 virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1443 1444 SK_TO_STRING_OVERRIDE() 1445 1446 private: 1447 SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 1448 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1449 SkClearXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {} 1450 #endif 1451 1452 typedef SkProcCoeffXfermode INHERITED; 1453 }; 1454 1455 void SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1456 const SkPMColor* SK_RESTRICT, int count, 1457 const SkAlpha* SK_RESTRICT aa) const { 1458 SkASSERT(dst && count >= 0); 1459 1460 if (NULL == aa) { 1461 memset(dst, 0, count << 2); 1462 } else { 1463 for (int i = count - 1; i >= 0; --i) { 1464 unsigned a = aa[i]; 1465 if (0xFF == a) { 1466 dst[i] = 0; 1467 } else if (a != 0) { 1468 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 1469 } 1470 } 1471 } 1472 } 1473 void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1474 const SkPMColor* SK_RESTRICT, int count, 1475 const SkAlpha* SK_RESTRICT aa) const { 1476 SkASSERT(dst && count >= 0); 1477 1478 if (NULL == aa) { 1479 memset(dst, 0, count); 1480 } else { 1481 for (int i = count - 1; i >= 0; --i) { 1482 unsigned a = aa[i]; 1483 if (0xFF == a) { 1484 dst[i] = 0; 1485 } else if (0 != a) { 1486 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 1487 } 1488 } 1489 } 1490 } 1491 1492 #ifndef SK_IGNORE_TO_STRING 1493 void SkClearXfermode::toString(SkString* str) const { 1494 this->INHERITED::toString(str); 1495 } 1496 #endif 1497 1498 /////////////////////////////////////////////////////////////////////////////// 1499 1500 class SkSrcXfermode : public SkProcCoeffXfermode { 1501 public: 1502 static SkSrcXfermode* Create(const ProcCoeff& rec) { 1503 return SkNEW_ARGS(SkSrcXfermode, (rec)); 1504 } 1505 1506 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1507 virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1508 1509 SK_TO_STRING_OVERRIDE() 1510 1511 private: 1512 SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 1513 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1514 SkSrcXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {} 1515 #endif 1516 typedef SkProcCoeffXfermode INHERITED; 1517 }; 1518 1519 void SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1520 const SkPMColor* SK_RESTRICT src, int count, 1521 const SkAlpha* SK_RESTRICT aa) const { 1522 SkASSERT(dst && src && count >= 0); 1523 1524 if (NULL == aa) { 1525 memcpy(dst, src, count << 2); 1526 } else { 1527 for (int i = count - 1; i >= 0; --i) { 1528 unsigned a = aa[i]; 1529 if (a == 0xFF) { 1530 dst[i] = src[i]; 1531 } else if (a != 0) { 1532 dst[i] = SkFourByteInterp(src[i], dst[i], a); 1533 } 1534 } 1535 } 1536 } 1537 1538 void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1539 const SkPMColor* SK_RESTRICT src, int count, 1540 const SkAlpha* SK_RESTRICT aa) const { 1541 SkASSERT(dst && src && count >= 0); 1542 1543 if (NULL == aa) { 1544 for (int i = count - 1; i >= 0; --i) { 1545 dst[i] = SkToU8(SkGetPackedA32(src[i])); 1546 } 1547 } else { 1548 for (int i = count - 1; i >= 0; --i) { 1549 unsigned a = aa[i]; 1550 if (0 != a) { 1551 unsigned srcA = SkGetPackedA32(src[i]); 1552 if (a == 0xFF) { 1553 dst[i] = SkToU8(srcA); 1554 } else { 1555 dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 1556 } 1557 } 1558 } 1559 } 1560 } 1561 #ifndef SK_IGNORE_TO_STRING 1562 void SkSrcXfermode::toString(SkString* str) const { 1563 this->INHERITED::toString(str); 1564 } 1565 #endif 1566 1567 /////////////////////////////////////////////////////////////////////////////// 1568 1569 class SkDstInXfermode : public SkProcCoeffXfermode { 1570 public: 1571 static SkDstInXfermode* Create(const ProcCoeff& rec) { 1572 return SkNEW_ARGS(SkDstInXfermode, (rec)); 1573 } 1574 1575 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1576 1577 SK_TO_STRING_OVERRIDE() 1578 1579 private: 1580 SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 1581 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1582 SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {} 1583 #endif 1584 1585 typedef SkProcCoeffXfermode INHERITED; 1586 }; 1587 1588 void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1589 const SkPMColor* SK_RESTRICT src, int count, 1590 const SkAlpha* SK_RESTRICT aa) const { 1591 SkASSERT(dst && src); 1592 1593 if (count <= 0) { 1594 return; 1595 } 1596 if (aa) { 1597 return this->INHERITED::xfer32(dst, src, count, aa); 1598 } 1599 1600 do { 1601 unsigned a = SkGetPackedA32(*src); 1602 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 1603 dst++; 1604 src++; 1605 } while (--count != 0); 1606 } 1607 1608 #ifndef SK_IGNORE_TO_STRING 1609 void SkDstInXfermode::toString(SkString* str) const { 1610 this->INHERITED::toString(str); 1611 } 1612 #endif 1613 1614 /////////////////////////////////////////////////////////////////////////////// 1615 1616 class SkDstOutXfermode : public SkProcCoeffXfermode { 1617 public: 1618 static SkDstOutXfermode* Create(const ProcCoeff& rec) { 1619 return SkNEW_ARGS(SkDstOutXfermode, (rec)); 1620 } 1621 1622 virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 1623 1624 SK_TO_STRING_OVERRIDE() 1625 1626 private: 1627 SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 1628 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1629 SkDstOutXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {} 1630 #endif 1631 1632 typedef SkProcCoeffXfermode INHERITED; 1633 }; 1634 1635 void SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1636 const SkPMColor* SK_RESTRICT src, int count, 1637 const SkAlpha* SK_RESTRICT aa) const { 1638 SkASSERT(dst && src); 1639 1640 if (count <= 0) { 1641 return; 1642 } 1643 if (aa) { 1644 return this->INHERITED::xfer32(dst, src, count, aa); 1645 } 1646 1647 do { 1648 unsigned a = SkGetPackedA32(*src); 1649 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 1650 dst++; 1651 src++; 1652 } while (--count != 0); 1653 } 1654 1655 #ifndef SK_IGNORE_TO_STRING 1656 void SkDstOutXfermode::toString(SkString* str) const { 1657 this->INHERITED::toString(str); 1658 } 1659 #endif 1660 1661 /////////////////////////////////////////////////////////////////////////////// 1662 1663 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXfermode::Mode mode); 1664 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); 1665 1666 // Technically, can't be static and passed as a template parameter. So we use anonymous namespace. 1667 namespace { 1668 SkXfermode* create_mode(int iMode) { 1669 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; 1670 1671 ProcCoeff rec = gProcCoeffs[mode]; 1672 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); 1673 if (pp != NULL) { 1674 rec.fProc = pp; 1675 } 1676 1677 SkXfermode* xfer = NULL; 1678 // check if we have a platform optim for that 1679 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); 1680 if (xfm != NULL) { 1681 xfer = xfm; 1682 } else { 1683 // All modes can in theory be represented by the ProcCoeff rec, since 1684 // it contains function ptrs. However, a few modes are both simple and 1685 // commonly used, so we call those out for their own subclasses here. 1686 switch (mode) { 1687 case SkXfermode::kClear_Mode: 1688 xfer = SkClearXfermode::Create(rec); 1689 break; 1690 case SkXfermode::kSrc_Mode: 1691 xfer = SkSrcXfermode::Create(rec); 1692 break; 1693 case SkXfermode::kSrcOver_Mode: 1694 SkASSERT(false); // should not land here 1695 break; 1696 case SkXfermode::kDstIn_Mode: 1697 xfer = SkDstInXfermode::Create(rec); 1698 break; 1699 case SkXfermode::kDstOut_Mode: 1700 xfer = SkDstOutXfermode::Create(rec); 1701 break; 1702 default: 1703 // no special-case, just rely in the rec and its function-ptrs 1704 xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 1705 break; 1706 } 1707 } 1708 return xfer; 1709 } 1710 } // namespace 1711 1712 1713 SkXfermode* SkXfermode::Create(Mode mode) { 1714 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1715 1716 if ((unsigned)mode >= kModeCount) { 1717 // report error 1718 return NULL; 1719 } 1720 1721 // Skia's "default" mode is srcover. NULL in SkPaint is interpreted as srcover 1722 // so we can just return NULL from the factory. 1723 if (kSrcOver_Mode == mode) { 1724 return NULL; 1725 } 1726 1727 SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, kModeCount, create_mode); 1728 return SkSafeRef(cached[mode]); 1729 } 1730 1731 SkXfermodeProc SkXfermode::GetProc(Mode mode) { 1732 SkXfermodeProc proc = NULL; 1733 if ((unsigned)mode < kModeCount) { 1734 proc = gProcCoeffs[mode].fProc; 1735 } 1736 return proc; 1737 } 1738 1739 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 1740 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1741 1742 if ((unsigned)mode >= (unsigned)kModeCount) { 1743 // illegal mode parameter 1744 return false; 1745 } 1746 1747 const ProcCoeff& rec = gProcCoeffs[mode]; 1748 1749 if (CANNOT_USE_COEFF == rec.fSC) { 1750 return false; 1751 } 1752 1753 SkASSERT(CANNOT_USE_COEFF != rec.fDC); 1754 if (src) { 1755 *src = rec.fSC; 1756 } 1757 if (dst) { 1758 *dst = rec.fDC; 1759 } 1760 return true; 1761 } 1762 1763 bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) { 1764 if (NULL == xfer) { 1765 if (mode) { 1766 *mode = kSrcOver_Mode; 1767 } 1768 return true; 1769 } 1770 return xfer->asMode(mode); 1771 } 1772 1773 bool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) { 1774 if (NULL == xfer) { 1775 return ModeAsCoeff(kSrcOver_Mode, src, dst); 1776 } 1777 return xfer->asCoeff(src, dst); 1778 } 1779 1780 bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) { 1781 // if xfer==null then the mode is srcover 1782 Mode m = kSrcOver_Mode; 1783 if (xfer && !xfer->asMode(&m)) { 1784 return false; 1785 } 1786 return mode == m; 1787 } 1788 1789 /////////////////////////////////////////////////////////////////////////////// 1790 //////////// 16bit xfermode procs 1791 1792 #ifdef SK_DEBUG 1793 static bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 1794 static bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 1795 #endif 1796 1797 static uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 1798 SkASSERT(require_255(src)); 1799 return SkPixel32ToPixel16(src); 1800 } 1801 1802 static uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 1803 return dst; 1804 } 1805 1806 static uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 1807 SkASSERT(require_0(src)); 1808 return dst; 1809 } 1810 1811 static uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 1812 SkASSERT(require_255(src)); 1813 return SkPixel32ToPixel16(src); 1814 } 1815 1816 static uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 1817 SkASSERT(require_0(src)); 1818 return dst; 1819 } 1820 1821 static uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 1822 SkASSERT(require_255(src)); 1823 return dst; 1824 } 1825 1826 static uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 1827 SkASSERT(require_255(src)); 1828 return SkPixel32ToPixel16(src); 1829 } 1830 1831 static uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 1832 SkASSERT(require_255(src)); 1833 return dst; 1834 } 1835 1836 static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 1837 SkASSERT(require_0(src)); 1838 return dst; 1839 } 1840 1841 static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 1842 unsigned isa = 255 - SkGetPackedA32(src); 1843 1844 return SkPackRGB16( 1845 SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 1846 SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 1847 SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 1848 } 1849 1850 static uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 1851 SkASSERT(require_0(src)); 1852 return dst; 1853 } 1854 1855 static uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1856 SkASSERT(require_255(src)); 1857 return SkPixel32ToPixel16(src); 1858 } 1859 1860 static uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1861 SkASSERT(require_255(src)); 1862 return dst; 1863 } 1864 1865 /********* 1866 darken and lighten boil down to this. 1867 1868 darken = (1 - Sa) * Dc + min(Sc, Dc) 1869 lighten = (1 - Sa) * Dc + max(Sc, Dc) 1870 1871 if (Sa == 0) these become 1872 darken = Dc + min(0, Dc) = 0 1873 lighten = Dc + max(0, Dc) = Dc 1874 1875 if (Sa == 1) these become 1876 darken = min(Sc, Dc) 1877 lighten = max(Sc, Dc) 1878 */ 1879 1880 static uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 1881 SkASSERT(require_0(src)); 1882 return 0; 1883 } 1884 1885 static uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 1886 SkASSERT(require_255(src)); 1887 unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1888 unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1889 unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1890 return SkPackRGB16(r, g, b); 1891 } 1892 1893 static uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 1894 SkASSERT(require_0(src)); 1895 return dst; 1896 } 1897 1898 static uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 1899 SkASSERT(require_255(src)); 1900 unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1901 unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1902 unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1903 return SkPackRGB16(r, g, b); 1904 } 1905 1906 struct Proc16Rec { 1907 SkXfermodeProc16 fProc16_0; 1908 SkXfermodeProc16 fProc16_255; 1909 SkXfermodeProc16 fProc16_General; 1910 }; 1911 1912 static const Proc16Rec gModeProcs16[] = { 1913 { NULL, NULL, NULL }, // CLEAR 1914 { NULL, src_modeproc16_255, NULL }, 1915 { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 1916 { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 1917 { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 1918 { NULL, srcin_modeproc16_255, NULL }, 1919 { NULL, dstin_modeproc16_255, NULL }, 1920 { NULL, NULL, NULL },// SRC_OUT 1921 { dstout_modeproc16_0, NULL, NULL }, 1922 { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 1923 { NULL, dstatop_modeproc16_255, NULL }, 1924 { NULL, NULL, NULL }, // XOR 1925 1926 { NULL, NULL, NULL }, // plus 1927 { NULL, NULL, NULL }, // modulate 1928 { NULL, NULL, NULL }, // screen 1929 { NULL, NULL, NULL }, // overlay 1930 { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 1931 { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 1932 { NULL, NULL, NULL }, // colordodge 1933 { NULL, NULL, NULL }, // colorburn 1934 { NULL, NULL, NULL }, // hardlight 1935 { NULL, NULL, NULL }, // softlight 1936 { NULL, NULL, NULL }, // difference 1937 { NULL, NULL, NULL }, // exclusion 1938 { NULL, NULL, NULL }, // multiply 1939 { NULL, NULL, NULL }, // hue 1940 { NULL, NULL, NULL }, // saturation 1941 { NULL, NULL, NULL }, // color 1942 { NULL, NULL, NULL }, // luminosity 1943 }; 1944 1945 SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 1946 SkXfermodeProc16 proc16 = NULL; 1947 if ((unsigned)mode < kModeCount) { 1948 const Proc16Rec& rec = gModeProcs16[mode]; 1949 unsigned a = SkColorGetA(srcColor); 1950 1951 if (0 == a) { 1952 proc16 = rec.fProc16_0; 1953 } else if (255 == a) { 1954 proc16 = rec.fProc16_255; 1955 } else { 1956 proc16 = rec.fProc16_General; 1957 } 1958 } 1959 return proc16; 1960 } 1961 1962 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1963 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1964 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1965