OLD | NEW |
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 #include "SkBlitRow.h" | 8 #include "SkBlitRow.h" |
9 #include "SkCoreBlitters.h" | 9 #include "SkCoreBlitters.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
11 #include "SkDither.h" | 11 #include "SkDither.h" |
12 #include "SkShader.h" | 12 #include "SkShader.h" |
13 #include "SkUtils.h" | 13 #include "SkUtils.h" |
14 #include "SkUtilsArm.h" | 14 #include "SkUtilsArm.h" |
15 #include "SkXfermode.h" | 15 #include "SkXfermode.h" |
16 | 16 |
17 #if SK_MIPS_HAS_DSP | 17 #if SK_MIPS_HAS_DSP |
18 extern void blitmask_d565_opaque_mips(int width, int height, uint16_t* device, | 18 extern void blitmask_d565_opaque_mips(int width, int height, uint16_t* device, |
19 unsigned deviceRB, const uint8_t* alpha, | 19 unsigned deviceRB, const uint8_t* alpha, |
20 uint32_t expanded32, unsigned maskRB); | 20 uint32_t expanded32, unsigned maskRB); |
21 #endif | 21 #endif |
22 | 22 |
23 #if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) | 23 #if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) |
24 #include <arm_neon.h> | 24 #include <arm_neon.h> |
| 25 extern void SkRGB16BlitterBlitV_neon(uint16_t* device, |
| 26 int height, |
| 27 size_t deviceRB, |
| 28 unsigned scale, |
| 29 uint32_t src32); |
25 #else | 30 #else |
26 // if we don't have neon, then our black blitter is worth the extra code | 31 // if we don't have neon, then our black blitter is worth the extra code |
27 #define USE_BLACK_BLITTER | 32 #define USE_BLACK_BLITTER |
28 #endif | 33 #endif |
29 | 34 |
30 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, | 35 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, |
31 int count) { | 36 int count) { |
32 if (count > 0) { | 37 if (count > 0) { |
33 // see if we need to write one short before we can cast to an 4byte ptr | 38 // see if we need to write one short before we can cast to an 4byte ptr |
34 // (we do this subtract rather than (unsigned)dst so we don't get warnin
gs | 39 // (we do this subtract rather than (unsigned)dst so we don't get warnin
gs |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 } | 482 } |
478 | 483 |
479 void SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { | 484 void SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { |
480 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); | 485 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); |
481 size_t deviceRB = fDevice.rowBytes(); | 486 size_t deviceRB = fDevice.rowBytes(); |
482 | 487 |
483 // TODO: respect fDoDither | 488 // TODO: respect fDoDither |
484 unsigned scale5 = SkAlpha255To256(alpha) >> 3; | 489 unsigned scale5 = SkAlpha255To256(alpha) >> 3; |
485 uint32_t src32 = fExpandedRaw16 * scale5; | 490 uint32_t src32 = fExpandedRaw16 * scale5; |
486 scale5 = 32 - scale5; | 491 scale5 = 32 - scale5; |
| 492 #if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) |
| 493 SkRGB16BlitterBlitV_neon(device, height, deviceRB, scale5, src32); |
| 494 #else |
487 do { | 495 do { |
488 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; | 496 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; |
489 *device = SkCompact_rgb_16((src32 + dst32) >> 5); | 497 *device = SkCompact_rgb_16((src32 + dst32) >> 5); |
490 device = (uint16_t*)((char*)device + deviceRB); | 498 device = (uint16_t*)((char*)device + deviceRB); |
491 } while (--height != 0); | 499 } while (--height != 0); |
| 500 #endif |
492 } | 501 } |
493 | 502 |
494 void SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) { | 503 void SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) { |
495 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); | 504 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); |
496 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); | 505 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); |
497 size_t deviceRB = fDevice.rowBytes(); | 506 size_t deviceRB = fDevice.rowBytes(); |
498 uint16_t color16 = fColor16; | 507 uint16_t color16 = fColor16; |
499 | 508 |
500 if (fDoDither) { | 509 if (fDoDither) { |
501 uint16_t ditherColor = fRawDither16; | 510 uint16_t ditherColor = fRawDither16; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 } | 661 } |
653 | 662 |
654 void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { | 663 void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { |
655 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); | 664 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); |
656 size_t deviceRB = fDevice.rowBytes(); | 665 size_t deviceRB = fDevice.rowBytes(); |
657 | 666 |
658 // TODO: respect fDoDither | 667 // TODO: respect fDoDither |
659 unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); | 668 unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); |
660 uint32_t src32 = fExpandedRaw16 * scale5; | 669 uint32_t src32 = fExpandedRaw16 * scale5; |
661 scale5 = 32 - scale5; | 670 scale5 = 32 - scale5; |
| 671 #if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN) |
| 672 SkRGB16BlitterBlitV_neon(device, height, deviceRB, scale5, src32); |
| 673 #else |
662 do { | 674 do { |
663 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; | 675 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; |
664 *device = SkCompact_rgb_16((src32 + dst32) >> 5); | 676 *device = SkCompact_rgb_16((src32 + dst32) >> 5); |
665 device = (uint16_t*)((char*)device + deviceRB); | 677 device = (uint16_t*)((char*)device + deviceRB); |
666 } while (--height != 0); | 678 } while (--height != 0); |
| 679 #endif |
667 } | 680 } |
668 | 681 |
669 void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { | 682 void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { |
670 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); | 683 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); |
671 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); | 684 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); |
672 size_t deviceRB = fDevice.rowBytes(); | 685 size_t deviceRB = fDevice.rowBytes(); |
673 | 686 |
674 while (--height >= 0) { | 687 while (--height >= 0) { |
675 fColorProc16(device, fSrcColor32, width, x, y); | 688 fColorProc16(device, fSrcColor32, width, x, y); |
676 device = (uint16_t*)((char*)device + deviceRB); | 689 device = (uint16_t*)((char*)device + deviceRB); |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 #endif | 1063 #endif |
1051 } else if (0xFF == SkColorGetA(color)) { | 1064 } else if (0xFF == SkColorGetA(color)) { |
1052 blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); | 1065 blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); |
1053 } else { | 1066 } else { |
1054 blitter = allocator->createT<SkRGB16_Blitter>(device, paint); | 1067 blitter = allocator->createT<SkRGB16_Blitter>(device, paint); |
1055 } | 1068 } |
1056 } | 1069 } |
1057 | 1070 |
1058 return blitter; | 1071 return blitter; |
1059 } | 1072 } |
OLD | NEW |