Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include "SkBlitRow.h" | 10 #include "SkBlitRow.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, | 100 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, |
| 101 const int16_t* runs); | 101 const int16_t* runs); |
| 102 | 102 |
| 103 private: | 103 private: |
| 104 typedef SkRGB16_Opaque_Blitter INHERITED; | 104 typedef SkRGB16_Opaque_Blitter INHERITED; |
| 105 }; | 105 }; |
| 106 #endif | 106 #endif |
| 107 | 107 |
| 108 class SkRGB16_Shader_Blitter : public SkShaderBlitter { | 108 class SkRGB16_Shader_Blitter : public SkShaderBlitter { |
| 109 public: | 109 public: |
| 110 SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint); | 110 SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint, |
| 111 SkShader::Context* shaderContext); | |
| 111 virtual ~SkRGB16_Shader_Blitter(); | 112 virtual ~SkRGB16_Shader_Blitter(); |
| 112 virtual void blitH(int x, int y, int width); | 113 virtual void blitH(int x, int y, int width); |
| 113 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, | 114 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, |
| 114 const int16_t* runs); | 115 const int16_t* runs); |
| 115 virtual void blitRect(int x, int y, int width, int height); | 116 virtual void blitRect(int x, int y, int width, int height); |
| 116 | 117 |
| 117 protected: | 118 protected: |
| 118 SkPMColor* fBuffer; | 119 SkPMColor* fBuffer; |
| 119 SkBlitRow::Proc fOpaqueProc; | 120 SkBlitRow::Proc fOpaqueProc; |
| 120 SkBlitRow::Proc fAlphaProc; | 121 SkBlitRow::Proc fAlphaProc; |
| 121 | 122 |
| 122 private: | 123 private: |
| 123 // illegal | 124 // illegal |
| 124 SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); | 125 SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); |
| 125 | 126 |
| 126 typedef SkShaderBlitter INHERITED; | 127 typedef SkShaderBlitter INHERITED; |
| 127 }; | 128 }; |
| 128 | 129 |
| 129 // used only if the shader can perform shadSpan16 | 130 // used only if the shader can perform shadSpan16 |
| 130 class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter { | 131 class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter { |
| 131 public: | 132 public: |
| 132 SkRGB16_Shader16_Blitter(const SkBitmap& device, const SkPaint& paint); | 133 SkRGB16_Shader16_Blitter(const SkBitmap& device, const SkPaint& paint, |
| 134 SkShader::Context* shaderContext); | |
| 133 virtual void blitH(int x, int y, int width); | 135 virtual void blitH(int x, int y, int width); |
| 134 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, | 136 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, |
| 135 const int16_t* runs); | 137 const int16_t* runs); |
| 136 virtual void blitRect(int x, int y, int width, int height); | 138 virtual void blitRect(int x, int y, int width, int height); |
| 137 | 139 |
| 138 private: | 140 private: |
| 139 typedef SkRGB16_Shader_Blitter INHERITED; | 141 typedef SkRGB16_Shader_Blitter INHERITED; |
| 140 }; | 142 }; |
| 141 | 143 |
| 142 class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { | 144 class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { |
| 143 public: | 145 public: |
| 144 SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint ); | 146 SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint , |
| 147 SkShader::Context* shaderContext); | |
| 145 virtual ~SkRGB16_Shader_Xfermode_Blitter(); | 148 virtual ~SkRGB16_Shader_Xfermode_Blitter(); |
| 146 virtual void blitH(int x, int y, int width); | 149 virtual void blitH(int x, int y, int width); |
| 147 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, | 150 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, |
| 148 const int16_t* runs); | 151 const int16_t* runs); |
| 149 | 152 |
| 150 private: | 153 private: |
| 151 SkXfermode* fXfermode; | 154 SkXfermode* fXfermode; |
| 152 SkPMColor* fBuffer; | 155 SkPMColor* fBuffer; |
| 153 uint8_t* fAAExpand; | 156 uint8_t* fAAExpand; |
| 154 | 157 |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 672 | 675 |
| 673 while (--height >= 0) { | 676 while (--height >= 0) { |
| 674 blend32_16_row(src32, device, width); | 677 blend32_16_row(src32, device, width); |
| 675 device = (uint16_t*)((char*)device + deviceRB); | 678 device = (uint16_t*)((char*)device + deviceRB); |
| 676 } | 679 } |
| 677 } | 680 } |
| 678 | 681 |
| 679 /////////////////////////////////////////////////////////////////////////////// | 682 /////////////////////////////////////////////////////////////////////////////// |
| 680 | 683 |
| 681 SkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkBitmap& device, | 684 SkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkBitmap& device, |
| 682 const SkPaint& paint) | 685 const SkPaint& paint, |
| 683 : SkRGB16_Shader_Blitter(device, paint) { | 686 SkShader::Context* shaderCont ext) |
| 687 : SkRGB16_Shader_Blitter(device, paint, shaderContext) { | |
| 684 SkASSERT(SkShader::CanCallShadeSpan16(fShaderFlags)); | 688 SkASSERT(SkShader::CanCallShadeSpan16(fShaderFlags)); |
| 685 } | 689 } |
| 686 | 690 |
| 687 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) { | 691 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) { |
| 688 SkASSERT(x + width <= fDevice.width()); | 692 SkASSERT(x + width <= fDevice.width()); |
| 689 | 693 |
| 690 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | 694 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); |
| 691 SkShader* shader = fShader; | |
|
scroggo
2014/03/24 21:24:46
More instances of caching a value and not using th
Dominik Grewe
2014/03/26 17:22:22
I didn't realize we can't always rely on the compi
| |
| 692 | 695 |
| 693 int alpha = shader->getSpan16Alpha(); | 696 int alpha = fShaderContext->getSpan16Alpha(); |
| 694 if (0xFF == alpha) { | 697 if (0xFF == alpha) { |
| 695 shader->shadeSpan16(x, y, device, width); | 698 fShaderContext->shadeSpan16(x, y, device, width); |
| 696 } else { | 699 } else { |
| 697 uint16_t* span16 = (uint16_t*)fBuffer; | 700 uint16_t* span16 = (uint16_t*)fBuffer; |
| 698 shader->shadeSpan16(x, y, span16, width); | 701 fShaderContext->shadeSpan16(x, y, span16, width); |
| 699 SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width); | 702 SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width); |
| 700 } | 703 } |
| 701 } | 704 } |
| 702 | 705 |
| 703 void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) { | 706 void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) { |
| 704 SkShader* shader = fShader; | |
| 705 uint16_t* dst = fDevice.getAddr16(x, y); | 707 uint16_t* dst = fDevice.getAddr16(x, y); |
| 706 size_t dstRB = fDevice.rowBytes(); | 708 size_t dstRB = fDevice.rowBytes(); |
| 707 int alpha = shader->getSpan16Alpha(); | 709 int alpha = fShaderContext->getSpan16Alpha(); |
| 708 | 710 |
| 709 if (0xFF == alpha) { | 711 if (0xFF == alpha) { |
| 710 if (fShaderFlags & SkShader::kConstInY16_Flag) { | 712 if (fShaderFlags & SkShader::kConstInY16_Flag) { |
| 711 // have the shader blit directly into the device the first time | 713 // have the shader blit directly into the device the first time |
| 712 shader->shadeSpan16(x, y, dst, width); | 714 fShaderContext->shadeSpan16(x, y, dst, width); |
| 713 // and now just memcpy that line on the subsequent lines | 715 // and now just memcpy that line on the subsequent lines |
| 714 if (--height > 0) { | 716 if (--height > 0) { |
| 715 const uint16_t* orig = dst; | 717 const uint16_t* orig = dst; |
| 716 do { | 718 do { |
| 717 dst = (uint16_t*)((char*)dst + dstRB); | 719 dst = (uint16_t*)((char*)dst + dstRB); |
| 718 memcpy(dst, orig, width << 1); | 720 memcpy(dst, orig, width << 1); |
| 719 } while (--height); | 721 } while (--height); |
| 720 } | 722 } |
| 721 } else { // need to call shadeSpan16 for every line | 723 } else { // need to call shadeSpan16 for every line |
| 722 do { | 724 do { |
| 723 shader->shadeSpan16(x, y, dst, width); | 725 fShaderContext->shadeSpan16(x, y, dst, width); |
| 724 y += 1; | 726 y += 1; |
| 725 dst = (uint16_t*)((char*)dst + dstRB); | 727 dst = (uint16_t*)((char*)dst + dstRB); |
| 726 } while (--height); | 728 } while (--height); |
| 727 } | 729 } |
| 728 } else { | 730 } else { |
| 729 int scale = SkAlpha255To256(alpha); | 731 int scale = SkAlpha255To256(alpha); |
| 730 uint16_t* span16 = (uint16_t*)fBuffer; | 732 uint16_t* span16 = (uint16_t*)fBuffer; |
| 731 if (fShaderFlags & SkShader::kConstInY16_Flag) { | 733 if (fShaderFlags & SkShader::kConstInY16_Flag) { |
| 732 shader->shadeSpan16(x, y, span16, width); | 734 fShaderContext->shadeSpan16(x, y, span16, width); |
| 733 do { | 735 do { |
| 734 SkBlendRGB16(span16, dst, scale, width); | 736 SkBlendRGB16(span16, dst, scale, width); |
| 735 dst = (uint16_t*)((char*)dst + dstRB); | 737 dst = (uint16_t*)((char*)dst + dstRB); |
| 736 } while (--height); | 738 } while (--height); |
| 737 } else { | 739 } else { |
| 738 do { | 740 do { |
| 739 shader->shadeSpan16(x, y, span16, width); | 741 fShaderContext->shadeSpan16(x, y, span16, width); |
| 740 SkBlendRGB16(span16, dst, scale, width); | 742 SkBlendRGB16(span16, dst, scale, width); |
| 741 y += 1; | 743 y += 1; |
| 742 dst = (uint16_t*)((char*)dst + dstRB); | 744 dst = (uint16_t*)((char*)dst + dstRB); |
| 743 } while (--height); | 745 } while (--height); |
| 744 } | 746 } |
| 745 } | 747 } |
| 746 } | 748 } |
| 747 | 749 |
| 748 void SkRGB16_Shader16_Blitter::blitAntiH(int x, int y, | 750 void SkRGB16_Shader16_Blitter::blitAntiH(int x, int y, |
| 749 const SkAlpha* SK_RESTRICT antialias, | 751 const SkAlpha* SK_RESTRICT antialias, |
| 750 const int16_t* SK_RESTRICT runs) { | 752 const int16_t* SK_RESTRICT runs) { |
| 751 SkShader* shader = fShader; | |
| 752 SkPMColor* SK_RESTRICT span = fBuffer; | 753 SkPMColor* SK_RESTRICT span = fBuffer; |
| 753 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | 754 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); |
| 754 | 755 |
| 755 int alpha = shader->getSpan16Alpha(); | 756 int alpha = fShaderContext->getSpan16Alpha(); |
| 756 uint16_t* span16 = (uint16_t*)span; | 757 uint16_t* span16 = (uint16_t*)span; |
| 757 | 758 |
| 758 if (0xFF == alpha) { | 759 if (0xFF == alpha) { |
| 759 for (;;) { | 760 for (;;) { |
| 760 int count = *runs; | 761 int count = *runs; |
| 761 if (count <= 0) { | 762 if (count <= 0) { |
| 762 break; | 763 break; |
| 763 } | 764 } |
| 764 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer | 765 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer |
| 765 | 766 |
| 766 int aa = *antialias; | 767 int aa = *antialias; |
| 767 if (aa == 255) { | 768 if (aa == 255) { |
| 768 // go direct to the device! | 769 // go direct to the device! |
| 769 shader->shadeSpan16(x, y, device, count); | 770 fShaderContext->shadeSpan16(x, y, device, count); |
| 770 } else if (aa) { | 771 } else if (aa) { |
| 771 shader->shadeSpan16(x, y, span16, count); | 772 fShaderContext->shadeSpan16(x, y, span16, count); |
| 772 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); | 773 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); |
| 773 } | 774 } |
| 774 device += count; | 775 device += count; |
| 775 runs += count; | 776 runs += count; |
| 776 antialias += count; | 777 antialias += count; |
| 777 x += count; | 778 x += count; |
| 778 } | 779 } |
| 779 } else { // span alpha is < 255 | 780 } else { // span alpha is < 255 |
| 780 alpha = SkAlpha255To256(alpha); | 781 alpha = SkAlpha255To256(alpha); |
| 781 for (;;) { | 782 for (;;) { |
| 782 int count = *runs; | 783 int count = *runs; |
| 783 if (count <= 0) { | 784 if (count <= 0) { |
| 784 break; | 785 break; |
| 785 } | 786 } |
| 786 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer | 787 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer |
| 787 | 788 |
| 788 int aa = SkAlphaMul(*antialias, alpha); | 789 int aa = SkAlphaMul(*antialias, alpha); |
| 789 if (aa) { | 790 if (aa) { |
| 790 shader->shadeSpan16(x, y, span16, count); | 791 fShaderContext->shadeSpan16(x, y, span16, count); |
| 791 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); | 792 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); |
| 792 } | 793 } |
| 793 | 794 |
| 794 device += count; | 795 device += count; |
| 795 runs += count; | 796 runs += count; |
| 796 antialias += count; | 797 antialias += count; |
| 797 x += count; | 798 x += count; |
| 798 } | 799 } |
| 799 } | 800 } |
| 800 } | 801 } |
| 801 | 802 |
| 802 /////////////////////////////////////////////////////////////////////////////// | 803 /////////////////////////////////////////////////////////////////////////////// |
| 803 | 804 |
| 804 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device, | 805 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device, |
| 805 const SkPaint& paint) | 806 const SkPaint& paint, |
| 806 : INHERITED(device, paint) { | 807 SkShader::Context* shaderContext) |
| 808 : INHERITED(device, paint, shaderContext) { | |
| 807 SkASSERT(paint.getXfermode() == NULL); | 809 SkASSERT(paint.getXfermode() == NULL); |
| 808 | 810 |
| 809 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); | 811 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); |
| 810 | 812 |
| 811 // compute SkBlitRow::Procs | 813 // compute SkBlitRow::Procs |
| 812 unsigned flags = 0; | 814 unsigned flags = 0; |
| 813 | 815 |
| 814 uint32_t shaderFlags = fShaderFlags; | 816 uint32_t shaderFlags = fShaderFlags; |
| 815 // shaders take care of global alpha, so we never set it in SkBlitRow | 817 // shaders take care of global alpha, so we never set it in SkBlitRow |
| 816 if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { | 818 if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 827 SkBitmap::kRGB_565_Config); | 829 SkBitmap::kRGB_565_Config); |
| 828 } | 830 } |
| 829 | 831 |
| 830 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { | 832 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { |
| 831 sk_free(fBuffer); | 833 sk_free(fBuffer); |
| 832 } | 834 } |
| 833 | 835 |
| 834 void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { | 836 void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { |
| 835 SkASSERT(x + width <= fDevice.width()); | 837 SkASSERT(x + width <= fDevice.width()); |
| 836 | 838 |
| 837 fShader->shadeSpan(x, y, fBuffer, width); | 839 fShaderContext->shadeSpan(x, y, fBuffer, width); |
| 838 // shaders take care of global alpha, so we pass 0xFF (should be ignored) | 840 // shaders take care of global alpha, so we pass 0xFF (should be ignored) |
| 839 fOpaqueProc(fDevice.getAddr16(x, y), fBuffer, width, 0xFF, x, y); | 841 fOpaqueProc(fDevice.getAddr16(x, y), fBuffer, width, 0xFF, x, y); |
| 840 } | 842 } |
| 841 | 843 |
| 842 void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) { | 844 void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) { |
| 843 SkShader* shader = fShader; | |
| 844 SkBlitRow::Proc proc = fOpaqueProc; | 845 SkBlitRow::Proc proc = fOpaqueProc; |
| 845 SkPMColor* buffer = fBuffer; | 846 SkPMColor* buffer = fBuffer; |
| 846 uint16_t* dst = fDevice.getAddr16(x, y); | 847 uint16_t* dst = fDevice.getAddr16(x, y); |
| 847 size_t dstRB = fDevice.rowBytes(); | 848 size_t dstRB = fDevice.rowBytes(); |
| 848 | 849 |
| 849 if (fShaderFlags & SkShader::kConstInY32_Flag) { | 850 if (fShaderFlags & SkShader::kConstInY32_Flag) { |
| 850 shader->shadeSpan(x, y, buffer, width); | 851 fShaderContext->shadeSpan(x, y, buffer, width); |
| 851 do { | 852 do { |
| 852 proc(dst, buffer, width, 0xFF, x, y); | 853 proc(dst, buffer, width, 0xFF, x, y); |
| 853 y += 1; | 854 y += 1; |
| 854 dst = (uint16_t*)((char*)dst + dstRB); | 855 dst = (uint16_t*)((char*)dst + dstRB); |
| 855 } while (--height); | 856 } while (--height); |
| 856 } else { | 857 } else { |
| 857 do { | 858 do { |
| 858 shader->shadeSpan(x, y, buffer, width); | 859 fShaderContext->shadeSpan(x, y, buffer, width); |
| 859 proc(dst, buffer, width, 0xFF, x, y); | 860 proc(dst, buffer, width, 0xFF, x, y); |
| 860 y += 1; | 861 y += 1; |
| 861 dst = (uint16_t*)((char*)dst + dstRB); | 862 dst = (uint16_t*)((char*)dst + dstRB); |
| 862 } while (--height); | 863 } while (--height); |
| 863 } | 864 } |
| 864 } | 865 } |
| 865 | 866 |
| 866 static inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { | 867 static inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { |
| 867 int count = 0; | 868 int count = 0; |
| 868 for (;;) { | 869 for (;;) { |
| 869 int n = *runs; | 870 int n = *runs; |
| 870 if (n == 0 || *aa == 0) { | 871 if (n == 0 || *aa == 0) { |
| 871 break; | 872 break; |
| 872 } | 873 } |
| 873 runs += n; | 874 runs += n; |
| 874 aa += n; | 875 aa += n; |
| 875 count += n; | 876 count += n; |
| 876 } | 877 } |
| 877 return count; | 878 return count; |
| 878 } | 879 } |
| 879 | 880 |
| 880 void SkRGB16_Shader_Blitter::blitAntiH(int x, int y, | 881 void SkRGB16_Shader_Blitter::blitAntiH(int x, int y, |
| 881 const SkAlpha* SK_RESTRICT antialias, | 882 const SkAlpha* SK_RESTRICT antialias, |
| 882 const int16_t* SK_RESTRICT runs) { | 883 const int16_t* SK_RESTRICT runs) { |
| 883 SkShader* shader = fShader; | |
| 884 SkPMColor* SK_RESTRICT span = fBuffer; | 884 SkPMColor* SK_RESTRICT span = fBuffer; |
| 885 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | 885 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); |
| 886 | 886 |
| 887 for (;;) { | 887 for (;;) { |
| 888 int count = *runs; | 888 int count = *runs; |
| 889 if (count <= 0) { | 889 if (count <= 0) { |
| 890 break; | 890 break; |
| 891 } | 891 } |
| 892 int aa = *antialias; | 892 int aa = *antialias; |
| 893 if (0 == aa) { | 893 if (0 == aa) { |
| 894 device += count; | 894 device += count; |
| 895 runs += count; | 895 runs += count; |
| 896 antialias += count; | 896 antialias += count; |
| 897 x += count; | 897 x += count; |
| 898 continue; | 898 continue; |
| 899 } | 899 } |
| 900 | 900 |
| 901 int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count); | 901 int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count); |
| 902 | 902 |
| 903 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer | 903 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer |
| 904 shader->shadeSpan(x, y, span, nonZeroCount); | 904 fShaderContext->shadeSpan(x, y, span, nonZeroCount); |
| 905 | 905 |
| 906 SkPMColor* localSpan = span; | 906 SkPMColor* localSpan = span; |
| 907 for (;;) { | 907 for (;;) { |
| 908 SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc; | 908 SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc; |
| 909 proc(device, localSpan, count, aa, x, y); | 909 proc(device, localSpan, count, aa, x, y); |
| 910 | 910 |
| 911 x += count; | 911 x += count; |
| 912 device += count; | 912 device += count; |
| 913 runs += count; | 913 runs += count; |
| 914 antialias += count; | 914 antialias += count; |
| 915 nonZeroCount -= count; | 915 nonZeroCount -= count; |
| 916 if (nonZeroCount == 0) { | 916 if (nonZeroCount == 0) { |
| 917 break; | 917 break; |
| 918 } | 918 } |
| 919 localSpan += count; | 919 localSpan += count; |
| 920 SkASSERT(nonZeroCount > 0); | 920 SkASSERT(nonZeroCount > 0); |
| 921 count = *runs; | 921 count = *runs; |
| 922 SkASSERT(count > 0); | 922 SkASSERT(count > 0); |
| 923 aa = *antialias; | 923 aa = *antialias; |
| 924 } | 924 } |
| 925 } | 925 } |
| 926 } | 926 } |
| 927 | 927 |
| 928 /////////////////////////////////////////////////////////////////////// | 928 /////////////////////////////////////////////////////////////////////// |
| 929 | 929 |
| 930 SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( | 930 SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( |
| 931 const SkBitmap& device, const SkPaint& paint) | 931 const SkBitmap& device, const SkPaint& paint, |
| 932 : INHERITED(device, paint) { | 932 SkShader::Context* shaderContext) |
| 933 : INHERITED(device, paint, shaderContext) { | |
| 933 fXfermode = paint.getXfermode(); | 934 fXfermode = paint.getXfermode(); |
| 934 SkASSERT(fXfermode); | 935 SkASSERT(fXfermode); |
| 935 fXfermode->ref(); | 936 fXfermode->ref(); |
| 936 | 937 |
| 937 int width = device.width(); | 938 int width = device.width(); |
| 938 fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * siz eof(SkPMColor)); | 939 fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * siz eof(SkPMColor)); |
| 939 fAAExpand = (uint8_t*)(fBuffer + width); | 940 fAAExpand = (uint8_t*)(fBuffer + width); |
| 940 } | 941 } |
| 941 | 942 |
| 942 SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { | 943 SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { |
| 943 fXfermode->unref(); | 944 fXfermode->unref(); |
| 944 sk_free(fBuffer); | 945 sk_free(fBuffer); |
| 945 } | 946 } |
| 946 | 947 |
| 947 void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { | 948 void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { |
| 948 SkASSERT(x + width <= fDevice.width()); | 949 SkASSERT(x + width <= fDevice.width()); |
| 949 | 950 |
| 950 uint16_t* device = fDevice.getAddr16(x, y); | 951 uint16_t* device = fDevice.getAddr16(x, y); |
| 951 SkPMColor* span = fBuffer; | 952 SkPMColor* span = fBuffer; |
| 952 | 953 |
| 953 fShader->shadeSpan(x, y, span, width); | 954 fShaderContext->shadeSpan(x, y, span, width); |
| 954 fXfermode->xfer16(device, span, width, NULL); | 955 fXfermode->xfer16(device, span, width, NULL); |
| 955 } | 956 } |
| 956 | 957 |
| 957 void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, | 958 void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, |
| 958 const SkAlpha* SK_RESTRICT antialias, | 959 const SkAlpha* SK_RESTRICT antialias, |
| 959 const int16_t* SK_RESTRICT runs) { | 960 const int16_t* SK_RESTRICT runs) { |
| 960 SkShader* shader = fShader; | |
| 961 SkXfermode* mode = fXfermode; | 961 SkXfermode* mode = fXfermode; |
| 962 SkPMColor* SK_RESTRICT span = fBuffer; | 962 SkPMColor* SK_RESTRICT span = fBuffer; |
| 963 uint8_t* SK_RESTRICT aaExpand = fAAExpand; | 963 uint8_t* SK_RESTRICT aaExpand = fAAExpand; |
| 964 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | 964 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); |
| 965 | 965 |
| 966 for (;;) { | 966 for (;;) { |
| 967 int count = *runs; | 967 int count = *runs; |
| 968 if (count <= 0) { | 968 if (count <= 0) { |
| 969 break; | 969 break; |
| 970 } | 970 } |
| 971 int aa = *antialias; | 971 int aa = *antialias; |
| 972 if (0 == aa) { | 972 if (0 == aa) { |
| 973 device += count; | 973 device += count; |
| 974 runs += count; | 974 runs += count; |
| 975 antialias += count; | 975 antialias += count; |
| 976 x += count; | 976 x += count; |
| 977 continue; | 977 continue; |
| 978 } | 978 } |
| 979 | 979 |
| 980 int nonZeroCount = count + count_nonzero_span(runs + count, | 980 int nonZeroCount = count + count_nonzero_span(runs + count, |
| 981 antialias + count); | 981 antialias + count); |
| 982 | 982 |
| 983 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer | 983 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer |
| 984 shader->shadeSpan(x, y, span, nonZeroCount); | 984 fShaderContext->shadeSpan(x, y, span, nonZeroCount); |
| 985 | 985 |
| 986 x += nonZeroCount; | 986 x += nonZeroCount; |
| 987 SkPMColor* localSpan = span; | 987 SkPMColor* localSpan = span; |
| 988 for (;;) { | 988 for (;;) { |
| 989 if (aa == 0xFF) { | 989 if (aa == 0xFF) { |
| 990 mode->xfer16(device, localSpan, count, NULL); | 990 mode->xfer16(device, localSpan, count, NULL); |
| 991 } else { | 991 } else { |
| 992 SkASSERT(aa); | 992 SkASSERT(aa); |
| 993 memset(aaExpand, aa, count); | 993 memset(aaExpand, aa, count); |
| 994 mode->xfer16(device, localSpan, count, aaExpand); | 994 mode->xfer16(device, localSpan, count, aaExpand); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1005 count = *runs; | 1005 count = *runs; |
| 1006 SkASSERT(count > 0); | 1006 SkASSERT(count > 0); |
| 1007 aa = *antialias; | 1007 aa = *antialias; |
| 1008 } | 1008 } |
| 1009 } | 1009 } |
| 1010 } | 1010 } |
| 1011 | 1011 |
| 1012 /////////////////////////////////////////////////////////////////////////////// | 1012 /////////////////////////////////////////////////////////////////////////////// |
| 1013 | 1013 |
| 1014 SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, | 1014 SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, |
| 1015 SkShader::Context* shaderContext, | |
| 1015 SkTBlitterAllocator* allocator) { | 1016 SkTBlitterAllocator* allocator) { |
| 1016 SkASSERT(allocator != NULL); | 1017 SkASSERT(allocator != NULL); |
| 1017 | 1018 |
| 1018 SkBlitter* blitter; | 1019 SkBlitter* blitter; |
| 1019 SkShader* shader = paint.getShader(); | 1020 SkShader* shader = paint.getShader(); |
| 1020 SkXfermode* mode = paint.getXfermode(); | 1021 SkXfermode* mode = paint.getXfermode(); |
| 1021 | 1022 |
| 1022 // we require a shader if there is an xfermode, handled by our caller | 1023 // we require a shader if there is an xfermode, handled by our caller |
| 1023 SkASSERT(NULL == mode || NULL != shader); | 1024 SkASSERT(NULL == mode || NULL != shader); |
| 1024 | 1025 |
| 1025 if (shader) { | 1026 if (shader) { |
| 1027 SkASSERT(shaderContext != NULL); | |
| 1026 if (mode) { | 1028 if (mode) { |
| 1027 blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device , paint); | 1029 blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device , paint, |
| 1028 } else if (shader->canCallShadeSpan16()) { | 1030 shader Context); |
| 1029 blitter = allocator->createT<SkRGB16_Shader16_Blitter>(device, paint ); | 1031 } else if (shaderContext->canCallShadeSpan16()) { |
| 1032 blitter = allocator->createT<SkRGB16_Shader16_Blitter>(device, paint , shaderContext); | |
| 1030 } else { | 1033 } else { |
| 1031 blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint); | 1034 blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint, shaderContext); |
| 1032 } | 1035 } |
| 1033 } else { | 1036 } else { |
| 1034 // no shader, no xfermode, (and we always ignore colorfilter) | 1037 // no shader, no xfermode, (and we always ignore colorfilter) |
| 1035 SkColor color = paint.getColor(); | 1038 SkColor color = paint.getColor(); |
| 1036 if (0 == SkColorGetA(color)) { | 1039 if (0 == SkColorGetA(color)) { |
| 1037 blitter = allocator->createT<SkNullBlitter>(); | 1040 blitter = allocator->createT<SkNullBlitter>(); |
| 1038 #ifdef USE_BLACK_BLITTER | 1041 #ifdef USE_BLACK_BLITTER |
| 1039 } else if (SK_ColorBLACK == color) { | 1042 } else if (SK_ColorBLACK == color) { |
| 1040 blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint); | 1043 blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint); |
| 1041 #endif | 1044 #endif |
| 1042 } else if (0xFF == SkColorGetA(color)) { | 1045 } else if (0xFF == SkColorGetA(color)) { |
| 1043 blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); | 1046 blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint); |
| 1044 } else { | 1047 } else { |
| 1045 blitter = allocator->createT<SkRGB16_Blitter>(device, paint); | 1048 blitter = allocator->createT<SkRGB16_Blitter>(device, paint); |
| 1046 } | 1049 } |
| 1047 } | 1050 } |
| 1048 | 1051 |
| 1049 return blitter; | 1052 return blitter; |
| 1050 } | 1053 } |
| OLD | NEW |