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 |