| 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" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 SkBlitRow::Proc16 fOpaqueProc; | 127 SkBlitRow::Proc16 fOpaqueProc; |
| 128 SkBlitRow::Proc16 fAlphaProc; | 128 SkBlitRow::Proc16 fAlphaProc; |
| 129 | 129 |
| 130 private: | 130 private: |
| 131 // illegal | 131 // illegal |
| 132 SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); | 132 SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); |
| 133 | 133 |
| 134 typedef SkShaderBlitter INHERITED; | 134 typedef SkShaderBlitter INHERITED; |
| 135 }; | 135 }; |
| 136 | 136 |
| 137 // used only if the shader can perform shadSpan16 | |
| 138 class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter { | |
| 139 public: | |
| 140 SkRGB16_Shader16_Blitter(const SkPixmap& device, const SkPaint& paint, | |
| 141 SkShader::Context* shaderContext); | |
| 142 void blitH(int x, int y, int width) override; | |
| 143 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, | |
| 144 const int16_t* runs) override; | |
| 145 void blitRect(int x, int y, int width, int height) override; | |
| 146 | |
| 147 private: | |
| 148 typedef SkRGB16_Shader_Blitter INHERITED; | |
| 149 }; | |
| 150 | |
| 151 class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { | 137 class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { |
| 152 public: | 138 public: |
| 153 SkRGB16_Shader_Xfermode_Blitter(const SkPixmap& device, const SkPaint& paint
, | 139 SkRGB16_Shader_Xfermode_Blitter(const SkPixmap& device, const SkPaint& paint
, |
| 154 SkShader::Context* shaderContext); | 140 SkShader::Context* shaderContext); |
| 155 virtual ~SkRGB16_Shader_Xfermode_Blitter(); | 141 virtual ~SkRGB16_Shader_Xfermode_Blitter(); |
| 156 void blitH(int x, int y, int width) override; | 142 void blitH(int x, int y, int width) override; |
| 157 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, | 143 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, |
| 158 const int16_t* runs) override; | 144 const int16_t* runs) override; |
| 159 | 145 |
| 160 private: | 146 private: |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 size_t deviceRB = fDevice.rowBytes(); | 671 size_t deviceRB = fDevice.rowBytes(); |
| 686 | 672 |
| 687 while (--height >= 0) { | 673 while (--height >= 0) { |
| 688 fColorProc16(device, fSrcColor32, width, x, y); | 674 fColorProc16(device, fSrcColor32, width, x, y); |
| 689 device = (uint16_t*)((char*)device + deviceRB); | 675 device = (uint16_t*)((char*)device + deviceRB); |
| 690 } | 676 } |
| 691 } | 677 } |
| 692 | 678 |
| 693 /////////////////////////////////////////////////////////////////////////////// | 679 /////////////////////////////////////////////////////////////////////////////// |
| 694 | 680 |
| 695 SkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkPixmap& device, | |
| 696 const SkPaint& paint, | |
| 697 SkShader::Context* shaderCont
ext) | |
| 698 : SkRGB16_Shader_Blitter(device, paint, shaderContext) | |
| 699 { | |
| 700 SkASSERT(SkShader::CanCallShadeSpan16(fShaderFlags)); | |
| 701 } | |
| 702 | |
| 703 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) { | |
| 704 SkASSERT(x + width <= fDevice.width()); | |
| 705 | |
| 706 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); | |
| 707 SkShader::Context* shaderContext = fShaderContext; | |
| 708 | |
| 709 int alpha = shaderContext->getSpan16Alpha(); | |
| 710 if (0xFF == alpha) { | |
| 711 shaderContext->shadeSpan16(x, y, device, width); | |
| 712 } else { | |
| 713 uint16_t* span16 = (uint16_t*)fBuffer; | |
| 714 shaderContext->shadeSpan16(x, y, span16, width); | |
| 715 SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width); | |
| 716 } | |
| 717 } | |
| 718 | |
| 719 void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) { | |
| 720 SkShader::Context* shaderContext = fShaderContext; | |
| 721 uint16_t* dst = fDevice.writable_addr16(x, y); | |
| 722 size_t dstRB = fDevice.rowBytes(); | |
| 723 int alpha = shaderContext->getSpan16Alpha(); | |
| 724 | |
| 725 if (0xFF == alpha) { | |
| 726 if (fShaderFlags & SkShader::kConstInY16_Flag) { | |
| 727 // have the shader blit directly into the device the first time | |
| 728 shaderContext->shadeSpan16(x, y, dst, width); | |
| 729 // and now just memcpy that line on the subsequent lines | |
| 730 if (--height > 0) { | |
| 731 const uint16_t* orig = dst; | |
| 732 do { | |
| 733 dst = (uint16_t*)((char*)dst + dstRB); | |
| 734 memcpy(dst, orig, width << 1); | |
| 735 } while (--height); | |
| 736 } | |
| 737 } else { // need to call shadeSpan16 for every line | |
| 738 do { | |
| 739 shaderContext->shadeSpan16(x, y, dst, width); | |
| 740 y += 1; | |
| 741 dst = (uint16_t*)((char*)dst + dstRB); | |
| 742 } while (--height); | |
| 743 } | |
| 744 } else { | |
| 745 int scale = SkAlpha255To256(alpha); | |
| 746 uint16_t* span16 = (uint16_t*)fBuffer; | |
| 747 if (fShaderFlags & SkShader::kConstInY16_Flag) { | |
| 748 shaderContext->shadeSpan16(x, y, span16, width); | |
| 749 do { | |
| 750 SkBlendRGB16(span16, dst, scale, width); | |
| 751 dst = (uint16_t*)((char*)dst + dstRB); | |
| 752 } while (--height); | |
| 753 } else { | |
| 754 do { | |
| 755 shaderContext->shadeSpan16(x, y, span16, width); | |
| 756 SkBlendRGB16(span16, dst, scale, width); | |
| 757 y += 1; | |
| 758 dst = (uint16_t*)((char*)dst + dstRB); | |
| 759 } while (--height); | |
| 760 } | |
| 761 } | |
| 762 } | |
| 763 | |
| 764 void SkRGB16_Shader16_Blitter::blitAntiH(int x, int y, | |
| 765 const SkAlpha* SK_RESTRICT antialias, | |
| 766 const int16_t* SK_RESTRICT runs) { | |
| 767 SkShader::Context* shaderContext = fShaderContext; | |
| 768 SkPMColor* SK_RESTRICT span = fBuffer; | |
| 769 uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); | |
| 770 | |
| 771 int alpha = shaderContext->getSpan16Alpha(); | |
| 772 uint16_t* span16 = (uint16_t*)span; | |
| 773 | |
| 774 if (0xFF == alpha) { | |
| 775 for (;;) { | |
| 776 int count = *runs; | |
| 777 if (count <= 0) { | |
| 778 break; | |
| 779 } | |
| 780 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer | |
| 781 | |
| 782 int aa = *antialias; | |
| 783 if (aa == 255) { | |
| 784 // go direct to the device! | |
| 785 shaderContext->shadeSpan16(x, y, device, count); | |
| 786 } else if (aa) { | |
| 787 shaderContext->shadeSpan16(x, y, span16, count); | |
| 788 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); | |
| 789 } | |
| 790 device += count; | |
| 791 runs += count; | |
| 792 antialias += count; | |
| 793 x += count; | |
| 794 } | |
| 795 } else { // span alpha is < 255 | |
| 796 alpha = SkAlpha255To256(alpha); | |
| 797 for (;;) { | |
| 798 int count = *runs; | |
| 799 if (count <= 0) { | |
| 800 break; | |
| 801 } | |
| 802 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer | |
| 803 | |
| 804 int aa = SkAlphaMul(*antialias, alpha); | |
| 805 if (aa) { | |
| 806 shaderContext->shadeSpan16(x, y, span16, count); | |
| 807 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); | |
| 808 } | |
| 809 | |
| 810 device += count; | |
| 811 runs += count; | |
| 812 antialias += count; | |
| 813 x += count; | |
| 814 } | |
| 815 } | |
| 816 } | |
| 817 | |
| 818 /////////////////////////////////////////////////////////////////////////////// | |
| 819 | |
| 820 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkPixmap& device, | 681 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkPixmap& device, |
| 821 const SkPaint& paint, | 682 const SkPaint& paint, |
| 822 SkShader::Context* shaderContext) | 683 SkShader::Context* shaderContext) |
| 823 : INHERITED(device, paint, shaderContext) | 684 : INHERITED(device, paint, shaderContext) |
| 824 { | 685 { |
| 825 SkASSERT(paint.getXfermode() == nullptr); | 686 SkASSERT(paint.getXfermode() == nullptr); |
| 826 | 687 |
| 827 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); | 688 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); |
| 828 | 689 |
| 829 // compute SkBlitRow::Procs | 690 // compute SkBlitRow::Procs |
| 830 unsigned flags = 0; | 691 unsigned flags = 0; |
| 831 | 692 |
| 832 uint32_t shaderFlags = fShaderFlags; | 693 uint32_t shaderFlags = fShaderFlags; |
| 833 // shaders take care of global alpha, so we never set it in SkBlitRow | 694 // shaders take care of global alpha, so we never set it in SkBlitRow |
| 834 if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { | 695 if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { |
| 835 flags |= SkBlitRow::kSrcPixelAlpha_Flag; | 696 flags |= SkBlitRow::kSrcPixelAlpha_Flag; |
| 836 } | 697 } |
| 837 // don't dither if the shader is really 16bit | 698 if (paint.isDither()) { |
| 838 if (paint.isDither() && !(shaderFlags & SkShader::kIntrinsicly16_Flag)) { | |
| 839 flags |= SkBlitRow::kDither_Flag; | 699 flags |= SkBlitRow::kDither_Flag; |
| 840 } | 700 } |
| 841 // used when we know our global alpha is 0xFF | 701 // used when we know our global alpha is 0xFF |
| 842 fOpaqueProc = SkBlitRow::Factory16(flags); | 702 fOpaqueProc = SkBlitRow::Factory16(flags); |
| 843 // used when we know our global alpha is < 0xFF | 703 // used when we know our global alpha is < 0xFF |
| 844 fAlphaProc = SkBlitRow::Factory16(flags | SkBlitRow::kGlobalAlpha_Flag); | 704 fAlphaProc = SkBlitRow::Factory16(flags | SkBlitRow::kGlobalAlpha_Flag); |
| 845 } | 705 } |
| 846 | 706 |
| 847 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { | 707 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { |
| 848 sk_free(fBuffer); | 708 sk_free(fBuffer); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 SkXfermode* mode = paint.getXfermode(); | 900 SkXfermode* mode = paint.getXfermode(); |
| 1041 | 901 |
| 1042 // we require a shader if there is an xfermode, handled by our caller | 902 // we require a shader if there is an xfermode, handled by our caller |
| 1043 SkASSERT(nullptr == mode || shader); | 903 SkASSERT(nullptr == mode || shader); |
| 1044 | 904 |
| 1045 if (shader) { | 905 if (shader) { |
| 1046 SkASSERT(shaderContext != nullptr); | 906 SkASSERT(shaderContext != nullptr); |
| 1047 if (mode) { | 907 if (mode) { |
| 1048 blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device
, paint, | 908 blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device
, paint, |
| 1049 shader
Context); | 909 shader
Context); |
| 1050 } else if (shaderContext->canCallShadeSpan16()) { | |
| 1051 blitter = allocator->createT<SkRGB16_Shader16_Blitter>(device, paint
, shaderContext); | |
| 1052 } else { | 910 } else { |
| 1053 blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint,
shaderContext); | 911 blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint,
shaderContext); |
| 1054 } | 912 } |
| 1055 } else { | 913 } else { |
| 1056 // no shader, no xfermode, (and we always ignore colorfilter) | 914 // no shader, no xfermode, (and we always ignore colorfilter) |
| 1057 SkColor color = paint.getColor(); | 915 SkColor color = paint.getColor(); |
| 1058 if (0 == SkColorGetA(color)) { | 916 if (0 == SkColorGetA(color)) { |
| 1059 blitter = allocator->createT<SkNullBlitter>(); | 917 blitter = allocator->createT<SkNullBlitter>(); |
| 1060 #ifdef USE_BLACK_BLITTER | 918 #ifdef USE_BLACK_BLITTER |
| 1061 } else if (SK_ColorBLACK == color) { | 919 } else if (SK_ColorBLACK == color) { |
| 1062 blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint); | 920 blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint); |
| 1063 #endif | 921 #endif |
| 1064 } else if (0xFF == SkColorGetA(color)) { | 922 } else if (0xFF == SkColorGetA(color)) { |
| 1065 blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); | 923 blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); |
| 1066 } else { | 924 } else { |
| 1067 blitter = allocator->createT<SkRGB16_Blitter>(device, paint); | 925 blitter = allocator->createT<SkRGB16_Blitter>(device, paint); |
| 1068 } | 926 } |
| 1069 } | 927 } |
| 1070 | 928 |
| 1071 return blitter; | 929 return blitter; |
| 1072 } | 930 } |
| OLD | NEW |