1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkXfermode_proccoeff.h" 9 #include "SkColorPriv.h" 10 #include "SkMathPriv.h" 11 #include "SkOnce.h" 12 #include "SkOpts.h" 13 #include "SkRasterPipeline.h" 14 #include "SkReadBuffer.h" 15 #include "SkString.h" 16 #include "SkWriteBuffer.h" 17 #include "SkPM4f.h" 18 19 #if SK_SUPPORT_GPU 20 #include "GrFragmentProcessor.h" 21 #include "effects/GrCustomXfermode.h" 22 #include "effects/GrPorterDuffXferProcessor.h" 23 #include "effects/GrXfermodeFragmentProcessor.h" 24 #endif 25 26 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 27 28 static inline unsigned saturated_add(unsigned a, unsigned b) { 29 SkASSERT(a <= 255); 30 SkASSERT(b <= 255); 31 unsigned sum = a + b; 32 if (sum > 255) { 33 sum = 255; 34 } 35 return sum; 36 } 37 38 static inline int clamp_signed_byte(int n) { 39 if (n < 0) { 40 n = 0; 41 } else if (n > 255) { 42 n = 255; 43 } 44 return n; 45 } 46 47 static inline int clamp_div255round(int prod) { 48 if (prod <= 0) { 49 return 0; 50 } else if (prod >= 255*255) { 51 return 255; 52 } else { 53 return SkDiv255Round(prod); 54 } 55 } 56 57 /////////////////////////////////////////////////////////////////////////////// 58 #include "SkNx.h" 59 60 static Sk4f alpha(const Sk4f& color) { return Sk4f(color[3]); } 61 static Sk4f inv_alpha(const Sk4f& color) { return Sk4f(1 - color[3]); } 62 static Sk4f pin_1(const Sk4f& value) { return Sk4f::Min(value, Sk4f(1)); } 63 64 static Sk4f color_alpha(const Sk4f& color, float newAlpha) { 65 return Sk4f(color[0], color[1], color[2], newAlpha); 66 } 67 static Sk4f color_alpha(const Sk4f& color, const Sk4f& newAlpha) { 68 return color_alpha(color, newAlpha[3]); 69 } 70 71 static Sk4f set_argb(float a, float r, float g, float b) { 72 if (0 == SkPM4f::R) { 73 return Sk4f(r, g, b, a); 74 } else { 75 return Sk4f(b, g, r, a); 76 } 77 } 78 79 static Sk4f clear_4f(const Sk4f& s, const Sk4f& d) { return Sk4f(0); } 80 static Sk4f src_4f(const Sk4f& s, const Sk4f& d) { return s; } 81 static Sk4f dst_4f(const Sk4f& s, const Sk4f& d) { return d; } 82 static Sk4f srcover_4f(const Sk4f& s, const Sk4f& d) { return s + inv_alpha(s) * d; } 83 static Sk4f dstover_4f(const Sk4f& s, const Sk4f& d) { return d + inv_alpha(d) * s; } 84 static Sk4f srcin_4f(const Sk4f& s, const Sk4f& d) { return s * alpha(d); } 85 static Sk4f dstin_4f(const Sk4f& s, const Sk4f& d) { return d * alpha(s); } 86 static Sk4f srcout_4f(const Sk4f& s, const Sk4f& d) { return s * inv_alpha(d); } 87 static Sk4f dstout_4f(const Sk4f& s, const Sk4f& d) { return d * inv_alpha(s); } 88 static Sk4f srcatop_4f(const Sk4f& s, const Sk4f& d) { return s * alpha(d) + d * inv_alpha(s); } 89 static Sk4f dstatop_4f(const Sk4f& s, const Sk4f& d) { return d * alpha(s) + s * inv_alpha(d); } 90 static Sk4f xor_4f(const Sk4f& s, const Sk4f& d) { return s * inv_alpha(d) + d * inv_alpha(s);} 91 static Sk4f plus_4f(const Sk4f& s, const Sk4f& d) { return pin_1(s + d); } 92 static Sk4f modulate_4f(const Sk4f& s, const Sk4f& d) { return s * d; } 93 static Sk4f screen_4f(const Sk4f& s, const Sk4f& d) { return s + d - s * d; } 94 95 static Sk4f multiply_4f(const Sk4f& s, const Sk4f& d) { 96 return s * inv_alpha(d) + d * inv_alpha(s) + s * d; 97 } 98 99 static Sk4f overlay_4f(const Sk4f& s, const Sk4f& d) { 100 Sk4f sa = alpha(s); 101 Sk4f da = alpha(d); 102 Sk4f two = Sk4f(2); 103 Sk4f rc = (two * d <= da).thenElse(two * s * d, 104 sa * da - two * (da - d) * (sa - s)); 105 return pin_1(s + d - s * da + color_alpha(rc - d * sa, 0)); 106 } 107 108 static Sk4f hardlight_4f(const Sk4f& s, const Sk4f& d) { 109 return overlay_4f(d, s); 110 } 111 112 static Sk4f darken_4f(const Sk4f& s, const Sk4f& d) { 113 Sk4f sa = alpha(s); 114 Sk4f da = alpha(d); 115 return s + d - Sk4f::Max(s * da, d * sa); 116 } 117 118 static Sk4f lighten_4f(const Sk4f& s, const Sk4f& d) { 119 Sk4f sa = alpha(s); 120 Sk4f da = alpha(d); 121 return s + d - Sk4f::Min(s * da, d * sa); 122 } 123 124 static Sk4f colordodge_4f(const Sk4f& s, const Sk4f& d) { 125 Sk4f sa = alpha(s); 126 Sk4f da = alpha(d); 127 Sk4f isa = Sk4f(1) - sa; 128 Sk4f ida = Sk4f(1) - da; 129 130 Sk4f srcover = s + d * isa; 131 Sk4f dstover = d + s * ida; 132 Sk4f otherwise = sa * Sk4f::Min(da, (d * sa) / (sa - s)) + s * ida + d * isa; 133 134 // Order matters here, preferring d==0 over s==sa. 135 auto colors = (d == Sk4f(0)).thenElse(dstover, 136 (s == sa).thenElse(srcover, 137 otherwise)); 138 return color_alpha(colors, srcover); 139 } 140 141 static Sk4f colorburn_4f(const Sk4f& s, const Sk4f& d) { 142 Sk4f sa = alpha(s); 143 Sk4f da = alpha(d); 144 Sk4f isa = Sk4f(1) - sa; 145 Sk4f ida = Sk4f(1) - da; 146 147 Sk4f srcover = s + d * isa; 148 Sk4f dstover = d + s * ida; 149 Sk4f otherwise = sa * (da - Sk4f::Min(da, (da - d) * sa / s)) + s * ida + d * isa; 150 151 // Order matters here, preferring d==da over s==0. 152 auto colors = (d == da).thenElse(dstover, 153 (s == Sk4f(0)).thenElse(srcover, 154 otherwise)); 155 return color_alpha(colors, srcover); 156 } 157 158 static Sk4f softlight_4f(const Sk4f& s, const Sk4f& d) { 159 Sk4f sa = alpha(s); 160 Sk4f da = alpha(d); 161 Sk4f isa = Sk4f(1) - sa; 162 Sk4f ida = Sk4f(1) - da; 163 164 // Some common terms. 165 Sk4f m = (da > Sk4f(0)).thenElse(d / da, Sk4f(0)); 166 Sk4f s2 = Sk4f(2) * s; 167 Sk4f m4 = Sk4f(4) * m; 168 169 // The logic forks three ways: 170 // 1. dark src? 171 // 2. light src, dark dst? 172 // 3. light src, light dst? 173 Sk4f darkSrc = d * (sa + (s2 - sa) * (Sk4f(1) - m)); // Used in case 1. 174 Sk4f darkDst = (m4 * m4 + m4) * (m - Sk4f(1)) + Sk4f(7) * m; // Used in case 2. 175 Sk4f liteDst = m.sqrt() - m; // Used in case 3. 176 Sk4f liteSrc = d * sa + da * (s2 - sa) * (Sk4f(4) * d <= da).thenElse(darkDst, 177 liteDst); // Case 2 or 3? 178 179 return color_alpha(s * ida + d * isa + (s2 <= sa).thenElse(darkSrc, liteSrc), // Case 1 or 2/3? 180 s + d * isa); 181 } 182 183 static Sk4f difference_4f(const Sk4f& s, const Sk4f& d) { 184 Sk4f min = Sk4f::Min(s * alpha(d), d * alpha(s)); 185 return s + d - min - color_alpha(min, 0); 186 } 187 188 static Sk4f exclusion_4f(const Sk4f& s, const Sk4f& d) { 189 Sk4f product = s * d; 190 return s + d - product - color_alpha(product, 0); 191 } 192 193 //////////////////////////////////////////////////// 194 195 // The CSS compositing spec introduces the following formulas: 196 // (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable) 197 // SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709 198 // while PDF and CG uses the one from Rec. Rec. 601 199 // See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm 200 static inline float Lum(float r, float g, float b) { 201 return r * 0.2126f + g * 0.7152f + b * 0.0722f; 202 } 203 204 static inline float max(float a, float b, float c) { 205 return SkTMax(a, SkTMax(b, c)); 206 } 207 208 static inline float min(float a, float b, float c) { 209 return SkTMin(a, SkTMin(b, c)); 210 } 211 212 static inline float Sat(float r, float g, float b) { 213 return max(r, g, b) - min(r, g, b); 214 } 215 216 static inline void setSaturationComponents(float* Cmin, float* Cmid, float* Cmax, float s) { 217 if(*Cmax > *Cmin) { 218 *Cmid = (*Cmid - *Cmin) * s / (*Cmax - *Cmin); 219 *Cmax = s; 220 } else { 221 *Cmax = 0; 222 *Cmid = 0; 223 } 224 *Cmin = 0; 225 } 226 227 static inline void SetSat(float* r, float* g, float* b, float s) { 228 if(*r <= *g) { 229 if(*g <= *b) { 230 setSaturationComponents(r, g, b, s); 231 } else if(*r <= *b) { 232 setSaturationComponents(r, b, g, s); 233 } else { 234 setSaturationComponents(b, r, g, s); 235 } 236 } else if(*r <= *b) { 237 setSaturationComponents(g, r, b, s); 238 } else if(*g <= *b) { 239 setSaturationComponents(g, b, r, s); 240 } else { 241 setSaturationComponents(b, g, r, s); 242 } 243 } 244 245 static inline void clipColor(float* r, float* g, float* b, float a) { 246 float L = Lum(*r, *g, *b); 247 float n = min(*r, *g, *b); 248 float x = max(*r, *g, *b); 249 float denom; 250 if ((n < 0) && (denom = L - n)) { // Compute denom and make sure it's non zero 251 float scale = L / denom; 252 *r = L + (*r - L) * scale; 253 *g = L + (*g - L) * scale; 254 *b = L + (*b - L) * scale; 255 } 256 257 if ((x > a) && (denom = x - L)) { // Compute denom and make sure it's non zero 258 float scale = (a - L) / denom; 259 *r = L + (*r - L) * scale; 260 *g = L + (*g - L) * scale; 261 *b = L + (*b - L) * scale; 262 } 263 } 264 265 static inline void SetLum(float* r, float* g, float* b, float a, float l) { 266 float d = l - Lum(*r, *g, *b); 267 *r += d; 268 *g += d; 269 *b += d; 270 clipColor(r, g, b, a); 271 } 272 273 static Sk4f hue_4f(const Sk4f& s, const Sk4f& d) { 274 float sa = s[SkPM4f::A]; 275 float sr = s[SkPM4f::R]; 276 float sg = s[SkPM4f::G]; 277 float sb = s[SkPM4f::B]; 278 279 float da = d[SkPM4f::A]; 280 float dr = d[SkPM4f::R]; 281 float dg = d[SkPM4f::G]; 282 float db = d[SkPM4f::B]; 283 284 float Sr = sr; 285 float Sg = sg; 286 float Sb = sb; 287 SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); 288 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 289 290 return color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Sr, Sg, Sb), 291 sa + da - sa * da); 292 } 293 294 static Sk4f saturation_4f(const Sk4f& s, const Sk4f& d) { 295 float sa = s[SkPM4f::A]; 296 float sr = s[SkPM4f::R]; 297 float sg = s[SkPM4f::G]; 298 float sb = s[SkPM4f::B]; 299 300 float da = d[SkPM4f::A]; 301 float dr = d[SkPM4f::R]; 302 float dg = d[SkPM4f::G]; 303 float db = d[SkPM4f::B]; 304 305 float Dr = dr; 306 float Dg = dg; 307 float Db = db; 308 SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); 309 SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); 310 311 return color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Dr, Dg, Db), 312 sa + da - sa * da); 313 } 314 315 static Sk4f color_4f(const Sk4f& s, const Sk4f& d) { 316 float sa = s[SkPM4f::A]; 317 float sr = s[SkPM4f::R]; 318 float sg = s[SkPM4f::G]; 319 float sb = s[SkPM4f::B]; 320 321 float da = d[SkPM4f::A]; 322 float dr = d[SkPM4f::R]; 323 float dg = d[SkPM4f::G]; 324 float db = d[SkPM4f::B]; 325 326 float Sr = sr; 327 float Sg = sg; 328 float Sb = sb; 329 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 330 331 Sk4f res = color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Sr, Sg, Sb), 332 sa + da - sa * da); 333 // Can return tiny negative values ... 334 return Sk4f::Max(res, Sk4f(0)); 335 } 336 337 static Sk4f luminosity_4f(const Sk4f& s, const Sk4f& d) { 338 float sa = s[SkPM4f::A]; 339 float sr = s[SkPM4f::R]; 340 float sg = s[SkPM4f::G]; 341 float sb = s[SkPM4f::B]; 342 343 float da = d[SkPM4f::A]; 344 float dr = d[SkPM4f::R]; 345 float dg = d[SkPM4f::G]; 346 float db = d[SkPM4f::B]; 347 348 float Dr = dr; 349 float Dg = dg; 350 float Db = db; 351 SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); 352 353 Sk4f res = color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Dr, Dg, Db), 354 sa + da - sa * da); 355 // Can return tiny negative values ... 356 return Sk4f::Max(res, Sk4f(0)); 357 } 358 359 /////////////////////////////////////////////////////////////////////////////// 360 361 // kClear_Mode, //!< [0, 0] 362 static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 363 return 0; 364 } 365 366 // kSrc_Mode, //!< [Sa, Sc] 367 static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 368 return src; 369 } 370 371 // kDst_Mode, //!< [Da, Dc] 372 static SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 373 return dst; 374 } 375 376 // kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 377 static SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 378 #if 0 379 // this is the old, more-correct way, but it doesn't guarantee that dst==255 380 // will always stay opaque 381 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 382 #else 383 // this is slightly faster, but more importantly guarantees that dst==255 384 // will always stay opaque 385 return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 386 #endif 387 } 388 389 // kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 390 static SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 391 // this is the reverse of srcover, just flipping src and dst 392 // see srcover's comment about the 256 for opaqueness guarantees 393 return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 394 } 395 396 // kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 397 static SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 398 return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 399 } 400 401 // kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 402 static SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 403 return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 404 } 405 406 // kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 407 static SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 408 return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 409 } 410 411 // kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 412 static SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 413 return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 414 } 415 416 // kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 417 static SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 418 unsigned sa = SkGetPackedA32(src); 419 unsigned da = SkGetPackedA32(dst); 420 unsigned isa = 255 - sa; 421 422 return SkPackARGB32(da, 423 SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 424 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 425 SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 426 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 427 SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 428 SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 429 } 430 431 // kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 432 static SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 433 unsigned sa = SkGetPackedA32(src); 434 unsigned da = SkGetPackedA32(dst); 435 unsigned ida = 255 - da; 436 437 return SkPackARGB32(sa, 438 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 439 SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 440 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 441 SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 442 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 443 SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 444 } 445 446 // kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 447 static SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 448 unsigned sa = SkGetPackedA32(src); 449 unsigned da = SkGetPackedA32(dst); 450 unsigned isa = 255 - sa; 451 unsigned ida = 255 - da; 452 453 return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 454 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 455 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 456 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 457 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 458 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 459 SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 460 } 461 462 /////////////////////////////////////////////////////////////////////////////// 463 464 // kPlus_Mode 465 static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 466 unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 467 unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 468 unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 469 unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 470 return SkPackARGB32(a, r, g, b); 471 } 472 473 // kModulate_Mode 474 static SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) { 475 int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 476 int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 477 int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 478 int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 479 return SkPackARGB32(a, r, g, b); 480 } 481 482 static inline int srcover_byte(int a, int b) { 483 return a + b - SkAlphaMulAlpha(a, b); 484 } 485 486 // kMultiply_Mode 487 // B(Cb, Cs) = Cb x Cs 488 // multiply uses its own version of blendfunc_byte because sa and da are not needed 489 static int blendfunc_multiply_byte(int sc, int dc, int sa, int da) { 490 return clamp_div255round(sc * (255 - da) + dc * (255 - sa) + sc * dc); 491 } 492 493 static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { 494 int sa = SkGetPackedA32(src); 495 int da = SkGetPackedA32(dst); 496 int a = srcover_byte(sa, da); 497 int r = blendfunc_multiply_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 498 int g = blendfunc_multiply_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 499 int b = blendfunc_multiply_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 500 return SkPackARGB32(a, r, g, b); 501 } 502 503 // kScreen_Mode 504 static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 505 int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 506 int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 507 int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 508 int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 509 return SkPackARGB32(a, r, g, b); 510 } 511 512 // kOverlay_Mode 513 static inline int overlay_byte(int sc, int dc, int sa, int da) { 514 int tmp = sc * (255 - da) + dc * (255 - sa); 515 int rc; 516 if (2 * dc <= da) { 517 rc = 2 * sc * dc; 518 } else { 519 rc = sa * da - 2 * (da - dc) * (sa - sc); 520 } 521 return clamp_div255round(rc + tmp); 522 } 523 static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 524 int sa = SkGetPackedA32(src); 525 int da = SkGetPackedA32(dst); 526 int a = srcover_byte(sa, da); 527 int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 528 int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 529 int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 530 return SkPackARGB32(a, r, g, b); 531 } 532 533 // kDarken_Mode 534 static inline int darken_byte(int sc, int dc, int sa, int da) { 535 int sd = sc * da; 536 int ds = dc * sa; 537 if (sd < ds) { 538 // srcover 539 return sc + dc - SkDiv255Round(ds); 540 } else { 541 // dstover 542 return dc + sc - SkDiv255Round(sd); 543 } 544 } 545 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 546 int sa = SkGetPackedA32(src); 547 int da = SkGetPackedA32(dst); 548 int a = srcover_byte(sa, da); 549 int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 550 int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 551 int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 552 return SkPackARGB32(a, r, g, b); 553 } 554 555 // kLighten_Mode 556 static inline int lighten_byte(int sc, int dc, int sa, int da) { 557 int sd = sc * da; 558 int ds = dc * sa; 559 if (sd > ds) { 560 // srcover 561 return sc + dc - SkDiv255Round(ds); 562 } else { 563 // dstover 564 return dc + sc - SkDiv255Round(sd); 565 } 566 } 567 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 568 int sa = SkGetPackedA32(src); 569 int da = SkGetPackedA32(dst); 570 int a = srcover_byte(sa, da); 571 int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 572 int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 573 int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 574 return SkPackARGB32(a, r, g, b); 575 } 576 577 // kColorDodge_Mode 578 static inline int colordodge_byte(int sc, int dc, int sa, int da) { 579 int diff = sa - sc; 580 int rc; 581 if (0 == dc) { 582 return SkAlphaMulAlpha(sc, 255 - da); 583 } else if (0 == diff) { 584 rc = sa * da + sc * (255 - da) + dc * (255 - sa); 585 } else { 586 diff = dc * sa / diff; 587 rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa); 588 } 589 return clamp_div255round(rc); 590 } 591 static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 592 int sa = SkGetPackedA32(src); 593 int da = SkGetPackedA32(dst); 594 int a = srcover_byte(sa, da); 595 int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 596 int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 597 int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 598 return SkPackARGB32(a, r, g, b); 599 } 600 601 // kColorBurn_Mode 602 static inline int colorburn_byte(int sc, int dc, int sa, int da) { 603 int rc; 604 if (dc == da) { 605 rc = sa * da + sc * (255 - da) + dc * (255 - sa); 606 } else if (0 == sc) { 607 return SkAlphaMulAlpha(dc, 255 - sa); 608 } else { 609 int tmp = (da - dc) * sa / sc; 610 rc = sa * (da - ((da < tmp) ? da : tmp)) 611 + sc * (255 - da) + dc * (255 - sa); 612 } 613 return clamp_div255round(rc); 614 } 615 static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 616 int sa = SkGetPackedA32(src); 617 int da = SkGetPackedA32(dst); 618 int a = srcover_byte(sa, da); 619 int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 620 int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 621 int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 622 return SkPackARGB32(a, r, g, b); 623 } 624 625 // kHardLight_Mode 626 static inline int hardlight_byte(int sc, int dc, int sa, int da) { 627 int rc; 628 if (2 * sc <= sa) { 629 rc = 2 * sc * dc; 630 } else { 631 rc = sa * da - 2 * (da - dc) * (sa - sc); 632 } 633 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 634 } 635 static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 636 int sa = SkGetPackedA32(src); 637 int da = SkGetPackedA32(dst); 638 int a = srcover_byte(sa, da); 639 int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 640 int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 641 int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 642 return SkPackARGB32(a, r, g, b); 643 } 644 645 // returns 255 * sqrt(n/255) 646 static U8CPU sqrt_unit_byte(U8CPU n) { 647 return SkSqrtBits(n, 15+4); 648 } 649 650 // kSoftLight_Mode 651 static inline int softlight_byte(int sc, int dc, int sa, int da) { 652 int m = da ? dc * 256 / da : 0; 653 int rc; 654 if (2 * sc <= sa) { 655 rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 656 } else if (4 * dc <= da) { 657 int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 658 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 659 } else { 660 int tmp = sqrt_unit_byte(m) - m; 661 rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 662 } 663 return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 664 } 665 static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 666 int sa = SkGetPackedA32(src); 667 int da = SkGetPackedA32(dst); 668 int a = srcover_byte(sa, da); 669 int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 670 int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 671 int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 672 return SkPackARGB32(a, r, g, b); 673 } 674 675 // kDifference_Mode 676 static inline int difference_byte(int sc, int dc, int sa, int da) { 677 int tmp = SkMin32(sc * da, dc * sa); 678 return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 679 } 680 static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 681 int sa = SkGetPackedA32(src); 682 int da = SkGetPackedA32(dst); 683 int a = srcover_byte(sa, da); 684 int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 685 int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 686 int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 687 return SkPackARGB32(a, r, g, b); 688 } 689 690 // kExclusion_Mode 691 static inline int exclusion_byte(int sc, int dc, int, int) { 692 // this equations is wacky, wait for SVG to confirm it 693 //int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 694 695 // The above equation can be simplified as follows 696 int r = 255*(sc + dc) - 2 * sc * dc; 697 return clamp_div255round(r); 698 } 699 static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 700 int sa = SkGetPackedA32(src); 701 int da = SkGetPackedA32(dst); 702 int a = srcover_byte(sa, da); 703 int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 704 int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 705 int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 706 return SkPackARGB32(a, r, g, b); 707 } 708 709 // The CSS compositing spec introduces the following formulas: 710 // (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable) 711 // SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709 712 // while PDF and CG uses the one from Rec. Rec. 601 713 // See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm 714 static inline int Lum(int r, int g, int b) 715 { 716 return SkDiv255Round(r * 77 + g * 150 + b * 28); 717 } 718 719 static inline int min2(int a, int b) { return a < b ? a : b; } 720 static inline int max2(int a, int b) { return a > b ? a : b; } 721 #define minimum(a, b, c) min2(min2(a, b), c) 722 #define maximum(a, b, c) max2(max2(a, b), c) 723 724 static inline int Sat(int r, int g, int b) { 725 return maximum(r, g, b) - minimum(r, g, b); 726 } 727 728 static inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) { 729 if(*Cmax > *Cmin) { 730 *Cmid = SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin); 731 *Cmax = s; 732 } else { 733 *Cmax = 0; 734 *Cmid = 0; 735 } 736 737 *Cmin = 0; 738 } 739 740 static inline void SetSat(int* r, int* g, int* b, int s) { 741 if(*r <= *g) { 742 if(*g <= *b) { 743 setSaturationComponents(r, g, b, s); 744 } else if(*r <= *b) { 745 setSaturationComponents(r, b, g, s); 746 } else { 747 setSaturationComponents(b, r, g, s); 748 } 749 } else if(*r <= *b) { 750 setSaturationComponents(g, r, b, s); 751 } else if(*g <= *b) { 752 setSaturationComponents(g, b, r, s); 753 } else { 754 setSaturationComponents(b, g, r, s); 755 } 756 } 757 758 static inline void clipColor(int* r, int* g, int* b, int a) { 759 int L = Lum(*r, *g, *b); 760 int n = minimum(*r, *g, *b); 761 int x = maximum(*r, *g, *b); 762 int denom; 763 if ((n < 0) && (denom = L - n)) { // Compute denom and make sure it's non zero 764 *r = L + SkMulDiv(*r - L, L, denom); 765 *g = L + SkMulDiv(*g - L, L, denom); 766 *b = L + SkMulDiv(*b - L, L, denom); 767 } 768 769 if ((x > a) && (denom = x - L)) { // Compute denom and make sure it's non zero 770 int numer = a - L; 771 *r = L + SkMulDiv(*r - L, numer, denom); 772 *g = L + SkMulDiv(*g - L, numer, denom); 773 *b = L + SkMulDiv(*b - L, numer, denom); 774 } 775 } 776 777 static inline void SetLum(int* r, int* g, int* b, int a, int l) { 778 int d = l - Lum(*r, *g, *b); 779 *r += d; 780 *g += d; 781 *b += d; 782 783 clipColor(r, g, b, a); 784 } 785 786 // non-separable blend modes are done in non-premultiplied alpha 787 #define blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \ 788 clamp_div255round(sc * (255 - da) + dc * (255 - sa) + blendval) 789 790 // kHue_Mode 791 // B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)) 792 // Create a color with the hue of the source color and the saturation and luminosity of the backdrop color. 793 static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) { 794 int sr = SkGetPackedR32(src); 795 int sg = SkGetPackedG32(src); 796 int sb = SkGetPackedB32(src); 797 int sa = SkGetPackedA32(src); 798 799 int dr = SkGetPackedR32(dst); 800 int dg = SkGetPackedG32(dst); 801 int db = SkGetPackedB32(dst); 802 int da = SkGetPackedA32(dst); 803 int Sr, Sg, Sb; 804 805 if(sa && da) { 806 Sr = sr * sa; 807 Sg = sg * sa; 808 Sb = sb * sa; 809 SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa); 810 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 811 } else { 812 Sr = 0; 813 Sg = 0; 814 Sb = 0; 815 } 816 817 int a = srcover_byte(sa, da); 818 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 819 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 820 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 821 return SkPackARGB32(a, r, g, b); 822 } 823 824 // kSaturation_Mode 825 // B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)) 826 // Create a color with the saturation of the source color and the hue and luminosity of the backdrop color. 827 static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) { 828 int sr = SkGetPackedR32(src); 829 int sg = SkGetPackedG32(src); 830 int sb = SkGetPackedB32(src); 831 int sa = SkGetPackedA32(src); 832 833 int dr = SkGetPackedR32(dst); 834 int dg = SkGetPackedG32(dst); 835 int db = SkGetPackedB32(dst); 836 int da = SkGetPackedA32(dst); 837 int Dr, Dg, Db; 838 839 if(sa && da) { 840 Dr = dr * sa; 841 Dg = dg * sa; 842 Db = db * sa; 843 SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da); 844 SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa); 845 } else { 846 Dr = 0; 847 Dg = 0; 848 Db = 0; 849 } 850 851 int a = srcover_byte(sa, da); 852 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 853 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 854 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 855 return SkPackARGB32(a, r, g, b); 856 } 857 858 // kColor_Mode 859 // B(Cb, Cs) = SetLum(Cs, Lum(Cb)) 860 // Create a color with the hue and saturation of the source color and the luminosity of the backdrop color. 861 static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) { 862 int sr = SkGetPackedR32(src); 863 int sg = SkGetPackedG32(src); 864 int sb = SkGetPackedB32(src); 865 int sa = SkGetPackedA32(src); 866 867 int dr = SkGetPackedR32(dst); 868 int dg = SkGetPackedG32(dst); 869 int db = SkGetPackedB32(dst); 870 int da = SkGetPackedA32(dst); 871 int Sr, Sg, Sb; 872 873 if(sa && da) { 874 Sr = sr * da; 875 Sg = sg * da; 876 Sb = sb * da; 877 SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa); 878 } else { 879 Sr = 0; 880 Sg = 0; 881 Sb = 0; 882 } 883 884 int a = srcover_byte(sa, da); 885 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr); 886 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg); 887 int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb); 888 return SkPackARGB32(a, r, g, b); 889 } 890 891 // kLuminosity_Mode 892 // B(Cb, Cs) = SetLum(Cb, Lum(Cs)) 893 // Create a color with the luminosity of the source color and the hue and saturation of the backdrop color. 894 static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) { 895 int sr = SkGetPackedR32(src); 896 int sg = SkGetPackedG32(src); 897 int sb = SkGetPackedB32(src); 898 int sa = SkGetPackedA32(src); 899 900 int dr = SkGetPackedR32(dst); 901 int dg = SkGetPackedG32(dst); 902 int db = SkGetPackedB32(dst); 903 int da = SkGetPackedA32(dst); 904 int Dr, Dg, Db; 905 906 if(sa && da) { 907 Dr = dr * sa; 908 Dg = dg * sa; 909 Db = db * sa; 910 SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da); 911 } else { 912 Dr = 0; 913 Dg = 0; 914 Db = 0; 915 } 916 917 int a = srcover_byte(sa, da); 918 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 919 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 920 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 921 return SkPackARGB32(a, r, g, b); 922 } 923 924 /////////////////////////////////////////////////////////////////////////////////////////////////// 925 926 static SkPM4f as_pm4f(const Sk4f& x) { 927 SkPM4f pm4; 928 x.store(pm4.fVec); 929 return pm4; 930 } 931 932 static Sk4f as_4f(const SkPM4f& pm4) { 933 return Sk4f::Load(pm4.fVec); 934 } 935 936 static void assert_unit(const SkPM4f& r) { 937 #ifdef SK_DEBUG 938 const float eps = 0.00001f; 939 const float min = 0 - eps; 940 const float max = 1 + eps; 941 for (int i = 0; i < 4; ++i) { 942 SkASSERT(r.fVec[i] >= min && r.fVec[i] <= max); 943 } 944 #endif 945 } 946 947 template <Sk4f (blend)(const Sk4f&, const Sk4f&)> SkPM4f proc_4f(const SkPM4f& s, const SkPM4f& d) { 948 assert_unit(s); 949 assert_unit(d); 950 SkPM4f r = as_pm4f(blend(as_4f(s), as_4f(d))); 951 // Turn this assert off for now because srgb conversions may end up in rgb > a 952 // assert_unit(r); 953 return r; 954 } 955 956 const ProcCoeff gProcCoeffs[] = { 957 { clear_modeproc, proc_4f<clear_4f>, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 958 { src_modeproc, proc_4f<src_4f>, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 959 { dst_modeproc, proc_4f<dst_4f>, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 960 { srcover_modeproc, proc_4f<srcover_4f>, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 961 { dstover_modeproc, proc_4f<dstover_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 962 { srcin_modeproc, proc_4f<srcin_4f>, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 963 { dstin_modeproc, proc_4f<dstin_4f>, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 964 { srcout_modeproc, proc_4f<srcout_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 965 { dstout_modeproc, proc_4f<dstout_4f>, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 966 { srcatop_modeproc, proc_4f<srcatop_4f>, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 967 { dstatop_modeproc, proc_4f<dstatop_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 968 { xor_modeproc, proc_4f<xor_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 969 970 { plus_modeproc, proc_4f<plus_4f>, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 971 { modulate_modeproc, proc_4f<modulate_4f>, SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 972 { screen_modeproc, proc_4f<screen_4f>, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, 973 { overlay_modeproc, proc_4f<overlay_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 974 { darken_modeproc, proc_4f<darken_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 975 { lighten_modeproc, proc_4f<lighten_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 976 { colordodge_modeproc, proc_4f<colordodge_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 977 { colorburn_modeproc, proc_4f<colorburn_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 978 { hardlight_modeproc, proc_4f<hardlight_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 979 { softlight_modeproc, proc_4f<softlight_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 980 { difference_modeproc, proc_4f<difference_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 981 { exclusion_modeproc, proc_4f<exclusion_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 982 { multiply_modeproc, proc_4f<multiply_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 983 { hue_modeproc, proc_4f<hue_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 984 { saturation_modeproc, proc_4f<saturation_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 985 { color_modeproc, proc_4f<color_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 986 { luminosity_modeproc, proc_4f<luminosity_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 987 }; 988 989 /////////////////////////////////////////////////////////////////////////////// 990 991 bool SkXfermode::asMode(Mode* mode) const { 992 return false; 993 } 994 995 #if SK_SUPPORT_GPU 996 sk_sp<GrFragmentProcessor> SkXfermode::makeFragmentProcessorForImageFilter( 997 sk_sp<GrFragmentProcessor>) const { 998 // This should never be called. 999 // TODO: make pure virtual in SkXfermode once Android update lands 1000 SkASSERT(0); 1001 return nullptr; 1002 } 1003 1004 const GrXPFactory* SkXfermode::asXPFactory() const { 1005 // This should never be called. 1006 // TODO: make pure virtual in SkXfermode once Android update lands 1007 SkASSERT(0); 1008 return nullptr; 1009 } 1010 #endif 1011 1012 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 1013 // no-op. subclasses should override this 1014 return dst; 1015 } 1016 1017 void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1018 const SkPMColor* SK_RESTRICT src, int count, 1019 const SkAlpha* SK_RESTRICT aa) const { 1020 SkASSERT(dst && src && count >= 0); 1021 1022 if (nullptr == aa) { 1023 for (int i = count - 1; i >= 0; --i) { 1024 dst[i] = this->xferColor(src[i], dst[i]); 1025 } 1026 } else { 1027 for (int i = count - 1; i >= 0; --i) { 1028 unsigned a = aa[i]; 1029 if (0 != a) { 1030 SkPMColor dstC = dst[i]; 1031 SkPMColor C = this->xferColor(src[i], dstC); 1032 if (0xFF != a) { 1033 C = SkFourByteInterp(C, dstC, a); 1034 } 1035 dst[i] = C; 1036 } 1037 } 1038 } 1039 } 1040 1041 void SkXfermode::xfer16(uint16_t* dst, 1042 const SkPMColor* SK_RESTRICT src, int count, 1043 const SkAlpha* SK_RESTRICT aa) const { 1044 SkASSERT(dst && src && count >= 0); 1045 1046 if (nullptr == aa) { 1047 for (int i = count - 1; i >= 0; --i) { 1048 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1049 dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 1050 } 1051 } else { 1052 for (int i = count - 1; i >= 0; --i) { 1053 unsigned a = aa[i]; 1054 if (0 != a) { 1055 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1056 SkPMColor C = this->xferColor(src[i], dstC); 1057 if (0xFF != a) { 1058 C = SkFourByteInterp(C, dstC, a); 1059 } 1060 dst[i] = SkPixel32ToPixel16_ToU16(C); 1061 } 1062 } 1063 } 1064 } 1065 1066 void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1067 const SkPMColor src[], int count, 1068 const SkAlpha* SK_RESTRICT aa) const { 1069 SkASSERT(dst && src && count >= 0); 1070 1071 if (nullptr == aa) { 1072 for (int i = count - 1; i >= 0; --i) { 1073 SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 1074 dst[i] = SkToU8(SkGetPackedA32(res)); 1075 } 1076 } else { 1077 for (int i = count - 1; i >= 0; --i) { 1078 unsigned a = aa[i]; 1079 if (0 != a) { 1080 SkAlpha dstA = dst[i]; 1081 unsigned A = SkGetPackedA32(this->xferColor(src[i], 1082 (SkPMColor)(dstA << SK_A32_SHIFT))); 1083 if (0xFF != a) { 1084 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 1085 } 1086 dst[i] = SkToU8(A); 1087 } 1088 } 1089 } 1090 } 1091 1092 bool SkXfermode::supportsCoverageAsAlpha() const { 1093 return false; 1094 } 1095 1096 bool SkXfermode::isOpaque(SkXfermode::SrcColorOpacity opacityType) const { 1097 return false; 1098 } 1099 1100 /////////////////////////////////////////////////////////////////////////////// 1101 /////////////////////////////////////////////////////////////////////////////// 1102 1103 sk_sp<SkFlattenable> SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) { 1104 uint32_t mode32 = buffer.read32(); 1105 if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) { 1106 return nullptr; 1107 } 1108 return SkXfermode::Make((SkXfermode::Mode)mode32); 1109 } 1110 1111 void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const { 1112 buffer.write32((int)fMode); 1113 } 1114 1115 bool SkProcCoeffXfermode::asMode(Mode* mode) const { 1116 if (mode) { 1117 *mode = (Mode)fMode; 1118 } 1119 return true; 1120 } 1121 1122 bool SkProcCoeffXfermode::supportsCoverageAsAlpha() const { 1123 if (CANNOT_USE_COEFF == fSrcCoeff) { 1124 return false; 1125 } 1126 1127 switch (fDstCoeff) { 1128 case SkXfermode::kOne_Coeff: 1129 case SkXfermode::kISA_Coeff: 1130 case SkXfermode::kISC_Coeff: 1131 return true; 1132 default: 1133 return false; 1134 } 1135 } 1136 1137 bool SkProcCoeffXfermode::isOpaque(SkXfermode::SrcColorOpacity opacityType) const { 1138 if (CANNOT_USE_COEFF == fSrcCoeff) { 1139 return false; 1140 } 1141 1142 if (SkXfermode::kDA_Coeff == fSrcCoeff || SkXfermode::kDC_Coeff == fSrcCoeff || 1143 SkXfermode::kIDA_Coeff == fSrcCoeff || SkXfermode::kIDC_Coeff == fSrcCoeff) { 1144 return false; 1145 } 1146 1147 switch (fDstCoeff) { 1148 case SkXfermode::kZero_Coeff: 1149 return true; 1150 case SkXfermode::kISA_Coeff: 1151 return SkXfermode::kOpaque_SrcColorOpacity == opacityType; 1152 case SkXfermode::kSA_Coeff: 1153 return SkXfermode::kTransparentBlack_SrcColorOpacity == opacityType || 1154 SkXfermode::kTransparentAlpha_SrcColorOpacity == opacityType; 1155 case SkXfermode::kSC_Coeff: 1156 return SkXfermode::kTransparentBlack_SrcColorOpacity == opacityType; 1157 default: 1158 return false; 1159 } 1160 1161 } 1162 1163 void SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 1164 const SkPMColor* SK_RESTRICT src, int count, 1165 const SkAlpha* SK_RESTRICT aa) const { 1166 SkASSERT(dst && src && count >= 0); 1167 1168 SkXfermodeProc proc = fProc; 1169 1170 if (proc) { 1171 if (nullptr == aa) { 1172 for (int i = count - 1; i >= 0; --i) { 1173 dst[i] = proc(src[i], dst[i]); 1174 } 1175 } else { 1176 for (int i = count - 1; i >= 0; --i) { 1177 unsigned a = aa[i]; 1178 if (0 != a) { 1179 SkPMColor dstC = dst[i]; 1180 SkPMColor C = proc(src[i], dstC); 1181 if (a != 0xFF) { 1182 C = SkFourByteInterp(C, dstC, a); 1183 } 1184 dst[i] = C; 1185 } 1186 } 1187 } 1188 } 1189 } 1190 1191 void SkProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst, 1192 const SkPMColor* SK_RESTRICT src, int count, 1193 const SkAlpha* SK_RESTRICT aa) const { 1194 SkASSERT(dst && src && count >= 0); 1195 1196 SkXfermodeProc proc = fProc; 1197 1198 if (proc) { 1199 if (nullptr == aa) { 1200 for (int i = count - 1; i >= 0; --i) { 1201 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1202 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 1203 } 1204 } else { 1205 for (int i = count - 1; i >= 0; --i) { 1206 unsigned a = aa[i]; 1207 if (0 != a) { 1208 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 1209 SkPMColor C = proc(src[i], dstC); 1210 if (0xFF != a) { 1211 C = SkFourByteInterp(C, dstC, a); 1212 } 1213 dst[i] = SkPixel32ToPixel16_ToU16(C); 1214 } 1215 } 1216 } 1217 } 1218 } 1219 1220 void SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 1221 const SkPMColor* SK_RESTRICT src, int count, 1222 const SkAlpha* SK_RESTRICT aa) const { 1223 SkASSERT(dst && src && count >= 0); 1224 1225 SkXfermodeProc proc = fProc; 1226 1227 if (proc) { 1228 if (nullptr == aa) { 1229 for (int i = count - 1; i >= 0; --i) { 1230 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 1231 dst[i] = SkToU8(SkGetPackedA32(res)); 1232 } 1233 } else { 1234 for (int i = count - 1; i >= 0; --i) { 1235 unsigned a = aa[i]; 1236 if (0 != a) { 1237 SkAlpha dstA = dst[i]; 1238 SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 1239 unsigned A = SkGetPackedA32(res); 1240 if (0xFF != a) { 1241 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 1242 } 1243 dst[i] = SkToU8(A); 1244 } 1245 } 1246 } 1247 } 1248 } 1249 1250 #if SK_SUPPORT_GPU 1251 sk_sp<GrFragmentProcessor> SkProcCoeffXfermode::makeFragmentProcessorForImageFilter( 1252 sk_sp<GrFragmentProcessor> dst) const { 1253 SkASSERT(dst); 1254 return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(dst), fMode); 1255 } 1256 1257 const GrXPFactory* SkProcCoeffXfermode::asXPFactory() const { 1258 if (CANNOT_USE_COEFF != fSrcCoeff) { 1259 const GrXPFactory* result(GrPorterDuffXPFactory::Get(fMode)); 1260 SkASSERT(result); 1261 return result; 1262 } 1263 1264 SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); 1265 return GrCustomXfermode::Get(fMode); 1266 } 1267 #endif 1268 1269 const char* SkXfermode::ModeName(Mode mode) { 1270 SkASSERT((unsigned) mode <= (unsigned)kLastMode); 1271 const char* gModeStrings[] = { 1272 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 1273 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 1274 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 1275 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", 1276 "Multiply", "Hue", "Saturation", "Color", "Luminosity" 1277 }; 1278 return gModeStrings[mode]; 1279 static_assert(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, "mode_count"); 1280 } 1281 1282 const char* SkBlendMode_Name(SkBlendMode mode) { 1283 return SkXfermode::ModeName((SkXfermode::Mode)mode); 1284 } 1285 1286 #ifndef SK_IGNORE_TO_STRING 1287 void SkProcCoeffXfermode::toString(SkString* str) const { 1288 str->append("SkProcCoeffXfermode: "); 1289 1290 str->append("mode: "); 1291 str->append(ModeName(fMode)); 1292 1293 static const char* gCoeffStrings[kCoeffCount] = { 1294 "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA" 1295 }; 1296 1297 str->append(" src: "); 1298 if (CANNOT_USE_COEFF == fSrcCoeff) { 1299 str->append("can't use"); 1300 } else { 1301 str->append(gCoeffStrings[fSrcCoeff]); 1302 } 1303 1304 str->append(" dst: "); 1305 if (CANNOT_USE_COEFF == fDstCoeff) { 1306 str->append("can't use"); 1307 } else { 1308 str->append(gCoeffStrings[fDstCoeff]); 1309 } 1310 } 1311 #endif 1312 1313 1314 sk_sp<SkXfermode> SkXfermode::Make(SkBlendMode mode) { 1315 if ((unsigned)mode > (unsigned)SkBlendMode::kLastMode) { 1316 // report error 1317 return nullptr; 1318 } 1319 1320 // Skia's "default" mode is srcover. nullptr in SkPaint is interpreted as srcover 1321 // so we can just return nullptr from the factory. 1322 if (SkBlendMode::kSrcOver == mode) { 1323 return nullptr; 1324 } 1325 1326 const int COUNT_BLENDMODES = (int)SkBlendMode::kLastMode + 1; 1327 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == COUNT_BLENDMODES); 1328 1329 static SkOnce once[COUNT_BLENDMODES]; 1330 static SkXfermode* cached[COUNT_BLENDMODES]; 1331 1332 once[(int)mode]([mode] { 1333 ProcCoeff rec = gProcCoeffs[(int)mode]; 1334 if (auto xfermode = SkOpts::create_xfermode(rec, mode)) { 1335 cached[(int)mode] = xfermode; 1336 } else { 1337 cached[(int)mode] = new SkProcCoeffXfermode(rec, mode); 1338 } 1339 }); 1340 return sk_ref_sp(cached[(int)mode]); 1341 } 1342 1343 SkXfermodeProc SkXfermode::GetProc(SkBlendMode mode) { 1344 SkXfermodeProc proc = nullptr; 1345 if ((unsigned)mode < kModeCount) { 1346 proc = gProcCoeffs[(unsigned)mode].fProc; 1347 } 1348 return proc; 1349 } 1350 1351 SkXfermodeProc4f SkXfermode::GetProc4f(SkBlendMode mode) { 1352 SkXfermodeProc4f proc = nullptr; 1353 if ((unsigned)mode < kModeCount) { 1354 proc = gProcCoeffs[(unsigned)mode].fProc4f; 1355 } 1356 return proc; 1357 } 1358 1359 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 1360 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1361 1362 if ((unsigned)mode >= (unsigned)kModeCount) { 1363 // illegal mode parameter 1364 return false; 1365 } 1366 1367 const ProcCoeff& rec = gProcCoeffs[mode]; 1368 1369 if (CANNOT_USE_COEFF == rec.fSC) { 1370 return false; 1371 } 1372 1373 SkASSERT(CANNOT_USE_COEFF != rec.fDC); 1374 if (src) { 1375 *src = rec.fSC; 1376 } 1377 if (dst) { 1378 *dst = rec.fDC; 1379 } 1380 return true; 1381 } 1382 1383 bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) { 1384 if (nullptr == xfer) { 1385 if (mode) { 1386 *mode = kSrcOver_Mode; 1387 } 1388 return true; 1389 } 1390 return xfer->asMode(mode); 1391 } 1392 1393 bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) { 1394 // if xfer==null then the mode is srcover 1395 Mode m = kSrcOver_Mode; 1396 if (xfer && !xfer->asMode(&m)) { 1397 return false; 1398 } 1399 return mode == m; 1400 } 1401 1402 bool SkXfermode::SupportsCoverageAsAlpha(const SkXfermode* xfer) { 1403 // if xfer is nullptr we treat it as srcOver which always supports coverageAsAlpha 1404 if (!xfer) { 1405 return true; 1406 } 1407 1408 return xfer->supportsCoverageAsAlpha(); 1409 } 1410 1411 bool SkXfermode::IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType) { 1412 // if xfer is nullptr we treat it as srcOver which is opaque if our src is opaque 1413 if (!xfer) { 1414 return SkXfermode::kOpaque_SrcColorOpacity == opacityType; 1415 } 1416 1417 return xfer->isOpaque(opacityType); 1418 } 1419 1420 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1421 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1422 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1423 1424 /////////////////////////////////////////////////////////////////////////////////////////////////// 1425 1426 bool SkBlendMode_SupportsCoverageAsAlpha(SkBlendMode mode) { 1427 switch (mode) { 1428 case SkBlendMode::kDst: 1429 case SkBlendMode::kSrcOver: 1430 case SkBlendMode::kDstOver: 1431 case SkBlendMode::kDstOut: 1432 case SkBlendMode::kSrcATop: 1433 case SkBlendMode::kXor: 1434 case SkBlendMode::kPlus: 1435 return true; 1436 default: 1437 break; 1438 } 1439 return false; 1440 } 1441 1442 bool SkXfermode::IsOpaque(SkBlendMode mode, SrcColorOpacity opacityType) { 1443 const ProcCoeff rec = gProcCoeffs[(int)mode]; 1444 1445 switch (rec.fSC) { 1446 case kDA_Coeff: 1447 case kDC_Coeff: 1448 case kIDA_Coeff: 1449 case kIDC_Coeff: 1450 return false; 1451 default: 1452 break; 1453 } 1454 1455 switch (rec.fDC) { 1456 case kZero_Coeff: 1457 return true; 1458 case kISA_Coeff: 1459 return kOpaque_SrcColorOpacity == opacityType; 1460 case kSA_Coeff: 1461 return kTransparentBlack_SrcColorOpacity == opacityType || 1462 kTransparentAlpha_SrcColorOpacity == opacityType; 1463 case kSC_Coeff: 1464 return kTransparentBlack_SrcColorOpacity == opacityType; 1465 default: 1466 return false; 1467 } 1468 return false; 1469 } 1470 1471 #if SK_SUPPORT_GPU 1472 const GrXPFactory* SkBlendMode_AsXPFactory(SkBlendMode mode) { 1473 const ProcCoeff rec = gProcCoeffs[(int)mode]; 1474 if (CANNOT_USE_COEFF != rec.fSC) { 1475 const GrXPFactory* result = GrPorterDuffXPFactory::Get(mode); 1476 SkASSERT(result); 1477 return result; 1478 } 1479 1480 SkASSERT(GrCustomXfermode::IsSupportedMode(mode)); 1481 return GrCustomXfermode::Get(mode); 1482 } 1483 #endif 1484 1485 bool SkBlendMode_CanOverflow(SkBlendMode mode) { return mode == SkBlendMode::kPlus; } 1486 1487 bool SkBlendMode_AppendStages(SkBlendMode mode, SkRasterPipeline* p) { 1488 auto stage = SkRasterPipeline::srcover; 1489 switch (mode) { 1490 case SkBlendMode::kClear: stage = SkRasterPipeline::clear; break; 1491 case SkBlendMode::kSrc: return true; // This stage is a no-op. 1492 case SkBlendMode::kDst: stage = SkRasterPipeline::move_dst_src; break; 1493 case SkBlendMode::kSrcOver: stage = SkRasterPipeline::srcover; break; 1494 case SkBlendMode::kDstOver: stage = SkRasterPipeline::dstover; break; 1495 case SkBlendMode::kSrcIn: stage = SkRasterPipeline::srcin; break; 1496 case SkBlendMode::kDstIn: stage = SkRasterPipeline::dstin; break; 1497 case SkBlendMode::kSrcOut: stage = SkRasterPipeline::srcout; break; 1498 case SkBlendMode::kDstOut: stage = SkRasterPipeline::dstout; break; 1499 case SkBlendMode::kSrcATop: stage = SkRasterPipeline::srcatop; break; 1500 case SkBlendMode::kDstATop: stage = SkRasterPipeline::dstatop; break; 1501 case SkBlendMode::kXor: stage = SkRasterPipeline::xor_; break; 1502 case SkBlendMode::kPlus: stage = SkRasterPipeline::plus_; break; 1503 case SkBlendMode::kModulate: stage = SkRasterPipeline::modulate; break; 1504 1505 case SkBlendMode::kScreen: stage = SkRasterPipeline::screen; break; 1506 case SkBlendMode::kOverlay: stage = SkRasterPipeline::overlay; break; 1507 case SkBlendMode::kDarken: stage = SkRasterPipeline::darken; break; 1508 case SkBlendMode::kLighten: stage = SkRasterPipeline::lighten; break; 1509 case SkBlendMode::kColorDodge: stage = SkRasterPipeline::colordodge; break; 1510 case SkBlendMode::kColorBurn: stage = SkRasterPipeline::colorburn; break; 1511 case SkBlendMode::kHardLight: stage = SkRasterPipeline::hardlight; break; 1512 case SkBlendMode::kSoftLight: stage = SkRasterPipeline::softlight; break; 1513 case SkBlendMode::kDifference: stage = SkRasterPipeline::difference; break; 1514 case SkBlendMode::kExclusion: stage = SkRasterPipeline::exclusion; break; 1515 case SkBlendMode::kMultiply: stage = SkRasterPipeline::multiply; break; 1516 1517 case SkBlendMode::kHue: 1518 case SkBlendMode::kSaturation: 1519 case SkBlendMode::kColor: 1520 case SkBlendMode::kLuminosity: return false; // TODO 1521 } 1522 if (p) { 1523 p->append(stage); 1524 } 1525 return true; 1526 } 1527