LEFT | RIGHT |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #ifndef SkColorPriv_DEFINED | 10 #ifndef SkColorPriv_DEFINED |
11 #define SkColorPriv_DEFINED | 11 #define SkColorPriv_DEFINED |
12 | 12 |
13 // turn this own for extra debug checking when blending onto 565 | 13 // turn this own for extra debug checking when blending onto 565 |
14 #ifdef SK_DEBUG | 14 #ifdef SK_DEBUG |
15 #define CHECK_FOR_565_OVERFLOW | 15 #define CHECK_FOR_565_OVERFLOW |
16 #endif | 16 #endif |
17 | 17 |
18 #include "SkColor.h" | 18 #include "SkColor.h" |
19 #include "SkMath.h" | 19 #include "SkMath.h" |
| 20 |
| 21 ///@{ |
| 22 /** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/ |
| 23 #define SK_ITU_BT709_LUM_COEFF_R (0.2126f) |
| 24 #define SK_ITU_BT709_LUM_COEFF_G (0.7152f) |
| 25 #define SK_ITU_BT709_LUM_COEFF_B (0.0722f) |
| 26 ///@} |
| 27 |
| 28 ///@{ |
| 29 /** A float value which specifies this channel's contribution to luminance. */ |
| 30 #define SK_LUM_COEFF_R SK_ITU_BT709_LUM_COEFF_R |
| 31 #define SK_LUM_COEFF_G SK_ITU_BT709_LUM_COEFF_G |
| 32 #define SK_LUM_COEFF_B SK_ITU_BT709_LUM_COEFF_B |
| 33 ///@} |
| 34 |
| 35 /** Computes the luminance from the given r, g, and b in accordance with |
| 36 SK_LUM_COEFF_X. For correct results, r, g, and b should be in linear space. |
| 37 */ |
| 38 static inline U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b) { |
| 39 //The following is |
| 40 //r * SK_LUM_COEFF_R + g * SK_LUM_COEFF_G + b * SK_LUM_COEFF_B |
| 41 //with SK_LUM_COEFF_X in 1.8 fixed point (rounding adjusted to sum to 256). |
| 42 return (r * 54 + g * 183 + b * 19) >> 8; |
| 43 } |
20 | 44 |
21 /** Turn 0..255 into 0..256, or a 0..15 into 0..16. */ | 45 /** Turn 0..255 into 0..256, or a 0..15 into 0..16. */ |
22 static inline U8CPU SkAlphaToScale(U8CPU alpha) { return alpha + 1; } | 46 static inline U8CPU SkAlphaToScale(U8CPU alpha) { return alpha + 1; } |
23 | 47 |
24 /** Turn 0..n-1 into 0..n, and then return the inverse alpha within the new | 48 /** Turn 0..n-1 into 0..n, and then return the inverse alpha within the new |
25 scale. | 49 scale. |
26 */ | 50 */ |
27 static inline U8CPU SkAlphaToInvScale4(U8CPU alpha) { | 51 static inline U8CPU SkAlphaToInvScale4(U8CPU alpha) { |
28 SkASSERT(SkToU8(alpha) == alpha); | 52 SkASSERT(SkToU8(alpha) == alpha); |
29 SkASSERT(alpha < 16); | 53 SkASSERT(alpha < 16); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 | 86 |
63 /** | 87 /** |
64 * Returns (src * alpha + dst * (255 - alpha)) / 255 | 88 * Returns (src * alpha + dst * (255 - alpha)) / 255 |
65 * | 89 * |
66 * This is more accurate than SkAlphaBlend, but slightly slower | 90 * This is more accurate than SkAlphaBlend, but slightly slower |
67 */ | 91 */ |
68 static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) { | 92 static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) { |
69 SkASSERT((int16_t)src == src); | 93 SkASSERT((int16_t)src == src); |
70 SkASSERT((int16_t)dst == dst); | 94 SkASSERT((int16_t)dst == dst); |
71 SkASSERT((uint8_t)alpha == alpha); | 95 SkASSERT((uint8_t)alpha == alpha); |
72 | 96 |
73 int prod = SkMulS16(src - dst, alpha) + 128; | 97 int prod = SkMulS16(src - dst, alpha) + 128; |
74 prod = (prod + (prod >> 8)) >> 8; | 98 prod = (prod + (prod >> 8)) >> 8; |
75 return dst + prod; | 99 return dst + prod; |
76 } | 100 } |
77 | 101 |
78 #define SK_R16_BITS 5 | 102 #define SK_R16_BITS 5 |
79 #define SK_G16_BITS 6 | 103 #define SK_G16_BITS 6 |
80 #define SK_B16_BITS 5 | 104 #define SK_B16_BITS 5 |
81 | 105 |
82 #define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS) | 106 #define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS) |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 | 253 |
230 return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | | 254 return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | |
231 (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); | 255 (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); |
232 } | 256 } |
233 | 257 |
234 /** | 258 /** |
235 * Abstract 4-byte interpolation, implemented on top of SkPMColor | 259 * Abstract 4-byte interpolation, implemented on top of SkPMColor |
236 * utility functions. Third parameter controls blending of the first two: | 260 * utility functions. Third parameter controls blending of the first two: |
237 * (src, dst, 0) returns dst | 261 * (src, dst, 0) returns dst |
238 * (src, dst, 0xFF) returns src | 262 * (src, dst, 0xFF) returns src |
| 263 * srcWeight is [0..256], unlike SkFourByteInterp which takes [0..255] |
| 264 */ |
| 265 static inline SkPMColor SkFourByteInterp256(SkPMColor src, SkPMColor dst, |
| 266 unsigned scale) { |
| 267 unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale); |
| 268 unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale); |
| 269 unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale); |
| 270 unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale); |
| 271 |
| 272 return SkPackARGB32(a, r, g, b); |
| 273 } |
| 274 |
| 275 /** |
| 276 * Abstract 4-byte interpolation, implemented on top of SkPMColor |
| 277 * utility functions. Third parameter controls blending of the first two: |
| 278 * (src, dst, 0) returns dst |
| 279 * (src, dst, 0xFF) returns src |
239 */ | 280 */ |
240 static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst, | 281 static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst, |
241 U8CPU srcWeight) { | 282 U8CPU srcWeight) { |
242 unsigned scale = SkAlpha255To256(srcWeight); | 283 unsigned scale = SkAlpha255To256(srcWeight); |
243 | 284 return SkFourByteInterp256(src, dst, scale); |
244 unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale); | |
245 unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale); | |
246 unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale); | |
247 unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale); | |
248 | |
249 return SkPackARGB32(a, r, g, b); | |
250 } | 285 } |
251 | 286 |
252 /** | 287 /** |
253 * 32b optimized version; currently appears to be 10% faster even on 64b | 288 * 32b optimized version; currently appears to be 10% faster even on 64b |
254 * architectures than an equivalent 64b version and 30% faster than | 289 * architectures than an equivalent 64b version and 30% faster than |
255 * SkFourByteInterp(). Third parameter controls blending of the first two: | 290 * SkFourByteInterp(). Third parameter controls blending of the first two: |
256 * (src, dst, 0) returns dst | 291 * (src, dst, 0) returns dst |
257 * (src, dst, 0xFF) returns src | 292 * (src, dst, 256) returns src |
258 * ** Does not match the results of SkFourByteInterp() because we use | 293 * ** Does not match the results of SkFourByteInterp256() because we use |
259 * a more accurate scale computation! | 294 * a more accurate scale computation! |
260 * TODO: migrate Skia function to using an accurate 255->266 alpha | 295 * TODO: migrate Skia function to using an accurate 255->266 alpha |
261 * conversion. | 296 * conversion. |
262 */ | 297 */ |
263 static inline SkPMColor SkFastFourByteInterp(SkPMColor src, | 298 static inline SkPMColor SkFastFourByteInterp256(SkPMColor src, |
264 SkPMColor dst, | 299 SkPMColor dst, |
265 U8CPU srcWeight) { | 300 unsigned scale) { |
266 SkASSERT(srcWeight < 256); | 301 SkASSERT(scale <= 256); |
267 | 302 |
268 // Reorders ARGB to AG-RB in order to reduce the number of operations. | 303 // Reorders ARGB to AG-RB in order to reduce the number of operations. |
269 const uint32_t mask = 0xFF00FF; | 304 const uint32_t mask = 0xFF00FF; |
270 uint32_t src_rb = src & mask; | 305 uint32_t src_rb = src & mask; |
271 uint32_t src_ag = (src >> 8) & mask; | 306 uint32_t src_ag = (src >> 8) & mask; |
272 uint32_t dst_rb = dst & mask; | 307 uint32_t dst_rb = dst & mask; |
273 uint32_t dst_ag = (dst >> 8) & mask; | 308 uint32_t dst_ag = (dst >> 8) & mask; |
274 | 309 |
| 310 uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb; |
| 311 uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag; |
| 312 |
| 313 return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8); |
| 314 } |
| 315 |
| 316 static inline SkPMColor SkFastFourByteInterp(SkPMColor src, |
| 317 SkPMColor dst, |
| 318 U8CPU srcWeight) { |
| 319 SkASSERT(srcWeight <= 255); |
275 // scale = srcWeight + (srcWeight >> 7) is more accurate than | 320 // scale = srcWeight + (srcWeight >> 7) is more accurate than |
276 // scale = srcWeight + 1, but 7% slower | 321 // scale = srcWeight + 1, but 7% slower |
277 int scale = srcWeight + (srcWeight >> 7); | 322 return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7)); |
278 | |
279 uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb; | |
280 uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag; | |
281 | |
282 return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8); | |
283 } | 323 } |
284 | 324 |
285 /** | 325 /** |
286 * Same as SkPackARGB32, but this version guarantees to not check that the | 326 * Same as SkPackARGB32, but this version guarantees to not check that the |
287 * values are premultiplied in the debug version. | 327 * values are premultiplied in the debug version. |
288 */ | 328 */ |
289 static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
{ | 329 static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
{ |
290 return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | | 330 return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | |
291 (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); | 331 (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); |
292 } | 332 } |
293 | 333 |
294 static inline | 334 static inline |
295 SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { | 335 SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { |
296 SkA32Assert(a); | 336 SkA32Assert(a); |
297 SkA32Assert(r); | 337 SkR32Assert(r); |
298 SkA32Assert(g); | 338 SkG32Assert(g); |
299 SkA32Assert(b); | 339 SkB32Assert(b); |
300 | 340 |
301 if (a != 255) { | 341 if (a != 255) { |
302 r = SkMulDiv255Round(r, a); | 342 r = SkMulDiv255Round(r, a); |
303 g = SkMulDiv255Round(g, a); | 343 g = SkMulDiv255Round(g, a); |
304 b = SkMulDiv255Round(b, a); | 344 b = SkMulDiv255Round(b, a); |
305 } | 345 } |
306 return SkPackARGB32(a, r, g, b); | 346 return SkPackARGB32(a, r, g, b); |
307 } | 347 } |
308 | 348 |
309 SK_API extern const uint32_t gMask_00FF00FF; | 349 SK_API extern const uint32_t gMask_00FF00FF; |
310 | 350 |
311 static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) { | 351 static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) { |
312 uint32_t mask = gMask_00FF00FF; | 352 uint32_t mask = gMask_00FF00FF; |
313 // uint32_t mask = 0xFF00FF; | |
314 | 353 |
315 uint32_t rb = ((c & mask) * scale) >> 8; | 354 uint32_t rb = ((c & mask) * scale) >> 8; |
316 uint32_t ag = ((c >> 8) & mask) * scale; | 355 uint32_t ag = ((c >> 8) & mask) * scale; |
317 return (rb & mask) | (ag & ~mask); | 356 return (rb & mask) | (ag & ~mask); |
318 } | 357 } |
319 | 358 |
320 static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) { | 359 static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) { |
321 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); | 360 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); |
322 } | 361 } |
323 | 362 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 } | 777 } |
739 | 778 |
740 static inline int SkBlend32(int src, int dst, int scale) { | 779 static inline int SkBlend32(int src, int dst, int scale) { |
741 SkASSERT((unsigned)src <= 0xFF); | 780 SkASSERT((unsigned)src <= 0xFF); |
742 SkASSERT((unsigned)dst <= 0xFF); | 781 SkASSERT((unsigned)dst <= 0xFF); |
743 SkASSERT((unsigned)scale <= 32); | 782 SkASSERT((unsigned)scale <= 32); |
744 return dst + ((src - dst) * scale >> 5); | 783 return dst + ((src - dst) * scale >> 5); |
745 } | 784 } |
746 | 785 |
747 static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB, | 786 static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB, |
748 SkPMColor dst, uint16_t mask) { | 787 SkPMColor dst, uint16_t mask) { |
749 if (mask == 0) { | 788 if (mask == 0) { |
750 return dst; | 789 return dst; |
751 } | 790 } |
752 | 791 |
753 /* We want all of these in 5bits, hence the shifts in case one of them | 792 /* We want all of these in 5bits, hence the shifts in case one of them |
754 * (green) is 6bits. | 793 * (green) is 6bits. |
755 */ | 794 */ |
756 int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); | 795 int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); |
757 int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); | 796 int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); |
758 int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); | 797 int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); |
759 | 798 |
760 // Now upscale them to 0..32, so we can use blend32 | 799 // Now upscale them to 0..32, so we can use blend32 |
761 maskR = SkUpscale31To32(maskR); | 800 maskR = SkUpscale31To32(maskR); |
762 maskG = SkUpscale31To32(maskG); | 801 maskG = SkUpscale31To32(maskG); |
763 maskB = SkUpscale31To32(maskB); | 802 maskB = SkUpscale31To32(maskB); |
764 | 803 |
765 // srcA has been upscaled to 256 before passed into this function | 804 // srcA has been upscaled to 256 before passed into this function |
766 maskR = maskR * srcA >> 8; | 805 maskR = maskR * srcA >> 8; |
767 maskG = maskG * srcA >> 8; | 806 maskG = maskG * srcA >> 8; |
768 maskB = maskB * srcA >> 8; | 807 maskB = maskB * srcA >> 8; |
769 | 808 |
770 int dstR = SkGetPackedR32(dst); | 809 int dstR = SkGetPackedR32(dst); |
771 int dstG = SkGetPackedG32(dst); | 810 int dstG = SkGetPackedG32(dst); |
772 int dstB = SkGetPackedB32(dst); | 811 int dstB = SkGetPackedB32(dst); |
773 | 812 |
774 // LCD blitting is only supported if the dst is known/required | 813 // LCD blitting is only supported if the dst is known/required |
775 // to be opaque | 814 // to be opaque |
776 return SkPackARGB32(0xFF, | 815 return SkPackARGB32(0xFF, |
777 SkBlend32(srcR, dstR, maskR), | 816 SkBlend32(srcR, dstR, maskR), |
778 SkBlend32(srcG, dstG, maskG), | 817 SkBlend32(srcG, dstG, maskG), |
779 SkBlend32(srcB, dstB, maskB)); | 818 SkBlend32(srcB, dstB, maskB)); |
780 } | 819 } |
781 | 820 |
782 static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB, | 821 static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB, |
783 SkPMColor dst, uint16_t mask, | 822 SkPMColor dst, uint16_t mask, |
784 SkPMColor opaqueDst) { | 823 SkPMColor opaqueDst) { |
785 if (mask == 0) { | 824 if (mask == 0) { |
786 return dst; | 825 return dst; |
787 } | 826 } |
788 | 827 |
789 if (0xFFFF == mask) { | 828 if (0xFFFF == mask) { |
790 return opaqueDst; | 829 return opaqueDst; |
791 } | 830 } |
792 | 831 |
793 /* We want all of these in 5bits, hence the shifts in case one of them | 832 /* We want all of these in 5bits, hence the shifts in case one of them |
794 * (green) is 6bits. | 833 * (green) is 6bits. |
795 */ | 834 */ |
796 int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); | 835 int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); |
797 int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); | 836 int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); |
798 int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); | 837 int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); |
799 | 838 |
800 // Now upscale them to 0..32, so we can use blend32 | 839 // Now upscale them to 0..32, so we can use blend32 |
801 maskR = SkUpscale31To32(maskR); | 840 maskR = SkUpscale31To32(maskR); |
802 maskG = SkUpscale31To32(maskG); | 841 maskG = SkUpscale31To32(maskG); |
803 maskB = SkUpscale31To32(maskB); | 842 maskB = SkUpscale31To32(maskB); |
804 | 843 |
805 int dstR = SkGetPackedR32(dst); | 844 int dstR = SkGetPackedR32(dst); |
806 int dstG = SkGetPackedG32(dst); | 845 int dstG = SkGetPackedG32(dst); |
807 int dstB = SkGetPackedB32(dst); | 846 int dstB = SkGetPackedB32(dst); |
808 | 847 |
809 // LCD blitting is only supported if the dst is known/required | 848 // LCD blitting is only supported if the dst is known/required |
810 // to be opaque | 849 // to be opaque |
811 return SkPackARGB32(0xFF, | 850 return SkPackARGB32(0xFF, |
812 SkBlend32(srcR, dstR, maskR), | 851 SkBlend32(srcR, dstR, maskR), |
813 SkBlend32(srcG, dstG, maskG), | 852 SkBlend32(srcG, dstG, maskG), |
814 SkBlend32(srcB, dstB, maskB)); | 853 SkBlend32(srcB, dstB, maskB)); |
815 } | 854 } |
816 | 855 |
817 static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t src[], | 856 static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t mask[], |
818 SkColor color, int width, SkPMColor) { | 857 SkColor src, int width, SkPMColor) { |
819 int srcA = SkColorGetA(color); | 858 int srcA = SkColorGetA(src); |
820 int srcR = SkColorGetR(color); | 859 int srcR = SkColorGetR(src); |
821 int srcG = SkColorGetG(color); | 860 int srcG = SkColorGetG(src); |
822 int srcB = SkColorGetB(color); | 861 int srcB = SkColorGetB(src); |
823 | 862 |
824 srcA = SkAlpha255To256(srcA); | 863 srcA = SkAlpha255To256(srcA); |
825 | 864 |
826 for (int i = 0; i < width; i++) { | 865 for (int i = 0; i < width; i++) { |
827 dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], src[i]); | 866 dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], mask[i]); |
828 } | 867 } |
829 } | 868 } |
830 | 869 |
831 static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t src[], | 870 static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t mask[], |
832 SkColor color, int width, | 871 SkColor src, int width, |
833 SkPMColor opaqueDst) { | 872 SkPMColor opaqueDst) { |
834 int srcR = SkColorGetR(color); | 873 int srcR = SkColorGetR(src); |
835 int srcG = SkColorGetG(color); | 874 int srcG = SkColorGetG(src); |
836 int srcB = SkColorGetB(color); | 875 int srcB = SkColorGetB(src); |
837 | 876 |
838 for (int i = 0; i < width; i++) { | 877 for (int i = 0; i < width; i++) { |
839 dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], src[i], | 878 dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i], |
840 opaqueDst); | 879 opaqueDst); |
841 } | 880 } |
842 } | 881 } |
843 | 882 |
844 #endif | 883 #endif |
845 | |
LEFT | RIGHT |