Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: include/core/SkColorPriv.h

Issue 2097883002: revise row blits to keep intermediate precision so that color is preserved when blended against its… (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: guard more changes with SK_SUPPORT_LEGACY_BROKEN_LERP Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gm/blend.cpp ('k') | src/core/SkBlitRow_D16.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkColorPriv_DEFINED 8 #ifndef SkColorPriv_DEFINED
9 #define SkColorPriv_DEFINED 9 #define SkColorPriv_DEFINED
10 10
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 static inline unsigned Sk255To256(U8CPU value) { 193 static inline unsigned Sk255To256(U8CPU value) {
194 SkASSERT(SkToU8(value) == value); 194 SkASSERT(SkToU8(value) == value);
195 return value + (value >> 7); 195 return value + (value >> 7);
196 } 196 }
197 197
198 /** Multiplify value by 0..256, and shift the result down 8 198 /** Multiplify value by 0..256, and shift the result down 8
199 (i.e. return (value * alpha256) >> 8) 199 (i.e. return (value * alpha256) >> 8)
200 */ 200 */
201 #define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8) 201 #define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8)
202 202
203 /** Calculates 256 - (value * alpha256) / 255 in range [0,256],
204 * for [0,255] value and [0,256] alpha256.
205 */
206 static inline U16CPU SkAlphaMulInv256(U16CPU value, U16CPU alpha256) {
207 #ifdef SK_SUPPORT_LEGACY_BROKEN_LERP
208 return SkAlpha255To256(255 - SkAlphaMul(value, alpha256));
209 #else
210 unsigned prod = 0xFFFF - value * alpha256;
211 return (prod + (prod >> 8)) >> 8;
212 #endif
213 }
214
203 // The caller may want negative values, so keep all params signed (int) 215 // The caller may want negative values, so keep all params signed (int)
204 // so we don't accidentally slip into unsigned math and lose the sign 216 // so we don't accidentally slip into unsigned math and lose the sign
205 // extension when we shift (in SkAlphaMul) 217 // extension when we shift (in SkAlphaMul)
206 static inline int SkAlphaBlend(int src, int dst, int scale256) { 218 static inline int SkAlphaBlend(int src, int dst, int scale256) {
207 SkASSERT((unsigned)scale256 <= 256); 219 SkASSERT((unsigned)scale256 <= 256);
208 return dst + SkAlphaMul(src - dst, scale256); 220 return dst + SkAlphaMul(src - dst, scale256);
209 } 221 }
210 222
211 /** 223 /**
212 * Returns (src * alpha + dst * (255 - alpha)) / 255 224 * Returns (src * alpha + dst * (255 - alpha)) / 255
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 573
562 uint32_t rb = ((c & mask) * scale) >> 8; 574 uint32_t rb = ((c & mask) * scale) >> 8;
563 uint32_t ag = ((c >> 8) & mask) * scale; 575 uint32_t ag = ((c >> 8) & mask) * scale;
564 return (rb & mask) | (ag & ~mask); 576 return (rb & mask) | (ag & ~mask);
565 } 577 }
566 578
567 static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) { 579 static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
568 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 580 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
569 } 581 }
570 582
583 /**
584 * Interpolates between colors src and dst using [0,256] scale.
585 */
586 static inline SkPMColor SkPMLerp(SkPMColor src, SkPMColor dst, unsigned scale) {
587 #ifdef SK_SUPPORT_LEGACY_BROKEN_LERP
588 return SkAlphaMulQ(src, scale) + SkAlphaMulQ(dst, 256 - scale);
589 #else
590 return SkFastFourByteInterp256(src, dst, scale);
591 #endif
592 }
593
571 static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) { 594 static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
572 SkASSERT((unsigned)aa <= 255); 595 SkASSERT((unsigned)aa <= 255);
573 596
574 unsigned src_scale = SkAlpha255To256(aa); 597 unsigned src_scale = SkAlpha255To256(aa);
598 #ifdef SK_SUPPORT_LEGACY_BROKEN_LERP
575 unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), s rc_scale)); 599 unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), s rc_scale));
576 600
577 return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale); 601 return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
602 #else
603 unsigned dst_scale = SkAlphaMulInv256(SkGetPackedA32(src), src_scale);
604
605 const uint32_t mask = 0xFF00FF;
606
607 uint32_t src_rb = (src & mask) * src_scale;
608 uint32_t src_ag = ((src >> 8) & mask) * src_scale;
609
610 uint32_t dst_rb = (dst & mask) * dst_scale;
611 uint32_t dst_ag = ((dst >> 8) & mask) * dst_scale;
612
613 return (((src_rb + dst_rb) >> 8) & mask) | ((src_ag + dst_ag) & ~mask);
614 #endif
578 } 615 }
579 616
580 //////////////////////////////////////////////////////////////////////////////// //////////// 617 //////////////////////////////////////////////////////////////////////////////// ////////////
581 // Convert a 32bit pixel to a 16bit pixel (no dither) 618 // Convert a 32bit pixel to a 16bit pixel (no dither)
582 619
583 #define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS)) 620 #define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
584 #define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS)) 621 #define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
585 #define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS)) 622 #define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
586 623
587 #ifdef SK_DEBUG 624 #ifdef SK_DEBUG
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 int srcG = SkColorGetG(src); 1089 int srcG = SkColorGetG(src);
1053 int srcB = SkColorGetB(src); 1090 int srcB = SkColorGetB(src);
1054 1091
1055 for (int i = 0; i < width; i++) { 1092 for (int i = 0; i < width; i++) {
1056 dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i], 1093 dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i],
1057 opaqueDst); 1094 opaqueDst);
1058 } 1095 }
1059 } 1096 }
1060 1097
1061 #endif 1098 #endif
OLDNEW
« no previous file with comments | « gm/blend.cpp ('k') | src/core/SkBlitRow_D16.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698