Changeset 846 for trunk/src/gui/painting/qdrawhelper.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/painting/qdrawhelper.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include <private/qpainter_p.h> 45 45 #include <private/qdrawhelper_x86_p.h> 46 #include <private/qdrawhelper_arm v6_p.h>46 #include <private/qdrawhelper_arm_simd_p.h> 47 47 #include <private/qdrawhelper_neon_p.h> 48 48 #include <private/qmath_p.h> … … 70 70 */ 71 71 72 static const int fixed_scale = 1 << 16; 73 static const int half_point = 1 << 15; 72 enum { 73 fixed_scale = 1 << 16, 74 half_point = 1 << 15 75 }; 74 76 static const int buffer_size = 2048; 75 77 … … 175 177 # define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch<Arg> 176 178 177 static constDestFetchProc destFetchProc[QImage::NImageFormats] =179 static DestFetchProc destFetchProc[QImage::NImageFormats] = 178 180 { 179 181 0, // Format_Invalid … … 323 325 # define SPANFUNC_POINTER_DESTSTORE(DEST) destStore<DEST> 324 326 325 static constDestStoreProc destStoreProc[QImage::NImageFormats] =327 static DestStoreProc destStoreProc[QImage::NImageFormats] = 326 328 { 327 329 0, // Format_Invalid … … 654 656 } 655 657 658 /** \internal 659 interpolate 4 argb pixels with the distx and disty factor. 660 distx and disty bust be between 0 and 16 661 */ 662 static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, int distx, int disty) 663 { 664 uint distxy = distx * disty; 665 //idistx * disty = (16-distx) * disty = 16*disty - distxy 666 //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*dity + distxy 667 uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy); 668 uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy); 669 uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy)); 670 uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy)); 671 uint blrb = ((bl & 0x00ff00ff) * (disty*16 - distxy)); 672 uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy)); 673 uint brrb = ((br & 0x00ff00ff) * (distxy)); 674 uint brag = (((br & 0xff00ff00) >> 8) * (distxy)); 675 return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00); 676 } 677 678 #if defined(QT_ALWAYS_HAVE_SSE2) 679 #define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b) \ 680 { \ 681 const __m128i dxdy = _mm_mullo_epi16 (distx, disty); \ 682 const __m128i distx_ = _mm_slli_epi16(distx, 4); \ 683 const __m128i disty_ = _mm_slli_epi16(disty, 4); \ 684 const __m128i idxidy = _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_))); \ 685 const __m128i dxidy = _mm_sub_epi16(distx_, dxdy); \ 686 const __m128i idxdy = _mm_sub_epi16(disty_, dxdy); \ 687 \ 688 __m128i tlAG = _mm_srli_epi16(tl, 8); \ 689 __m128i tlRB = _mm_and_si128(tl, colorMask); \ 690 __m128i trAG = _mm_srli_epi16(tr, 8); \ 691 __m128i trRB = _mm_and_si128(tr, colorMask); \ 692 __m128i blAG = _mm_srli_epi16(bl, 8); \ 693 __m128i blRB = _mm_and_si128(bl, colorMask); \ 694 __m128i brAG = _mm_srli_epi16(br, 8); \ 695 __m128i brRB = _mm_and_si128(br, colorMask); \ 696 \ 697 tlAG = _mm_mullo_epi16(tlAG, idxidy); \ 698 tlRB = _mm_mullo_epi16(tlRB, idxidy); \ 699 trAG = _mm_mullo_epi16(trAG, dxidy); \ 700 trRB = _mm_mullo_epi16(trRB, dxidy); \ 701 blAG = _mm_mullo_epi16(blAG, idxdy); \ 702 blRB = _mm_mullo_epi16(blRB, idxdy); \ 703 brAG = _mm_mullo_epi16(brAG, dxdy); \ 704 brRB = _mm_mullo_epi16(brRB, dxdy); \ 705 \ 706 /* Add the values, and shift to only keep 8 significant bits per colors */ \ 707 __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG)); \ 708 __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB)); \ 709 rAG = _mm_andnot_si128(colorMask, rAG); \ 710 rRB = _mm_srli_epi16(rRB, 8); \ 711 _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \ 712 } 713 #endif 714 715 #if defined(QT_ALWAYS_HAVE_NEON) 716 #define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \ 717 { \ 718 const int16x8_t dxdy = vmulq_s16(distx, disty); \ 719 const int16x8_t distx_ = vshlq_n_s16(distx, 4); \ 720 const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_))); \ 721 const int16x8_t dxidy = vsubq_s16(distx_, dxdy); \ 722 const int16x8_t idxdy = vsubq_s16(disty_, dxdy); \ 723 \ 724 int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8)); \ 725 int16x8_t tlRB = vandq_s16(tl, colorMask); \ 726 int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8)); \ 727 int16x8_t trRB = vandq_s16(tr, colorMask); \ 728 int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8)); \ 729 int16x8_t blRB = vandq_s16(bl, colorMask); \ 730 int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8)); \ 731 int16x8_t brRB = vandq_s16(br, colorMask); \ 732 \ 733 int16x8_t rAG = vmulq_s16(tlAG, idxidy); \ 734 int16x8_t rRB = vmulq_s16(tlRB, idxidy); \ 735 rAG = vmlaq_s16(rAG, trAG, dxidy); \ 736 rRB = vmlaq_s16(rRB, trRB, dxidy); \ 737 rAG = vmlaq_s16(rAG, blAG, idxdy); \ 738 rRB = vmlaq_s16(rRB, blRB, idxdy); \ 739 rAG = vmlaq_s16(rAG, brAG, dxdy); \ 740 rRB = vmlaq_s16(rRB, brRB, dxdy); \ 741 \ 742 rAG = vandq_s16(invColorMask, rAG); \ 743 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); \ 744 vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \ 745 } 746 #endif 747 748 template<TextureBlendType blendType> 749 Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2) 750 { 751 if (blendType == BlendTransformedBilinearTiled) { 752 v1 %= max; 753 if (v1 < 0) v1 += max; 754 v2 = v1 + 1; 755 v2 %= max; 756 } else { 757 if (v1 < l1) { 758 v2 = v1 = l1; 759 } else if (v1 >= l2) { 760 v2 = v1 = l2; 761 } else { 762 v2 = v1 + 1; 763 } 764 } 765 766 Q_ASSERT(v1 >= 0 && v1 < max); 767 Q_ASSERT(v2 >= 0 && v2 < max); 768 } 769 656 770 template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */ 657 771 Q_STATIC_TEMPLATE_FUNCTION … … 672 786 int image_height = data->texture.height; 673 787 788 int image_x1 = data->texture.x1; 789 int image_y1 = data->texture.y1; 790 int image_x2 = data->texture.x2 - 1; 791 int image_y2 = data->texture.y2 - 1; 792 674 793 const qreal cx = x + 0.5; 675 794 const qreal cy = y + 0.5; 676 795 677 constuint *end = buffer + length;796 uint *end = buffer + length; 678 797 uint *b = buffer; 679 798 if (data->fast_matrix) { … … 689 808 fx -= half_point; 690 809 fy -= half_point; 691 while (b < end) { 692 int x1 = (fx >> 16); 693 int x2 = x1 + 1; 810 811 if (fdy == 0) { //simple scale, no rotation 694 812 int y1 = (fy >> 16); 695 int y2 = y1 + 1; 696 697 int distx = ((fx - (x1 << 16)) >> 8); 698 int disty = ((fy - (y1 << 16)) >> 8); 699 int idistx = 256 - distx; 700 int idisty = 256 - disty; 701 702 if (blendType == BlendTransformedBilinearTiled) { 703 x1 %= image_width; 704 x2 %= image_width; 705 y1 %= image_height; 706 y2 %= image_height; 707 708 if (x1 < 0) x1 += image_width; 709 if (x2 < 0) x2 += image_width; 710 if (y1 < 0) y1 += image_height; 711 if (y2 < 0) y2 += image_height; 712 713 Q_ASSERT(x1 >= 0 && x1 < image_width); 714 Q_ASSERT(x2 >= 0 && x2 < image_width); 715 Q_ASSERT(y1 >= 0 && y1 < image_height); 716 Q_ASSERT(y2 >= 0 && y2 < image_height); 717 } else { 718 x1 = qBound(0, x1, image_width - 1); 719 x2 = qBound(0, x2, image_width - 1); 720 y1 = qBound(0, y1, image_height - 1); 721 y2 = qBound(0, y2, image_height - 1); 722 } 723 813 int y2; 814 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 724 815 const uchar *s1 = data->texture.scanLine(y1); 725 816 const uchar *s2 = data->texture.scanLine(y2); 726 817 727 uint tl = fetch(s1, x1, data->texture.colorTable); 728 uint tr = fetch(s1, x2, data->texture.colorTable); 729 uint bl = fetch(s2, x1, data->texture.colorTable); 730 uint br = fetch(s2, x2, data->texture.colorTable); 731 732 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); 733 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); 734 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); 735 736 fx += fdx; 737 fy += fdy; 738 ++b; 818 if (fdx <= fixed_scale && fdx > 0) { // scale up on X 819 int disty = (fy & 0x0000ffff) >> 8; 820 int idisty = 256 - disty; 821 int x = fx >> 16; 822 823 // The idea is first to do the interpolation between the row s1 and the row s2 824 // into an intermediate buffer, then we interpolate between two pixel of this buffer. 825 826 // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB 827 // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG 828 quint32 intermediate_buffer[2][buffer_size + 2]; 829 // count is the size used in the intermediate_buffer. 830 int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors. 831 Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case 832 int f = 0; 833 int lim = count; 834 if (blendType == BlendTransformedBilinearTiled) { 835 x %= image_width; 836 if (x < 0) x += image_width; 837 } else { 838 lim = qMin(count, image_x2-x+1); 839 if (x < image_x1) { 840 Q_ASSERT(x <= image_x2); 841 uint t = fetch(s1, image_x1, data->texture.colorTable); 842 uint b = fetch(s2, image_x1, data->texture.colorTable); 843 quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; 844 quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff; 845 do { 846 intermediate_buffer[0][f] = rb; 847 intermediate_buffer[1][f] = ag; 848 f++; 849 x++; 850 } while (x < image_x1 && f < lim); 851 } 852 } 853 854 if (blendType != BlendTransformedBilinearTiled && 855 (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { 856 #if defined(QT_ALWAYS_HAVE_SSE2) 857 const __m128i disty_ = _mm_set1_epi16(disty); 858 const __m128i idisty_ = _mm_set1_epi16(idisty); 859 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 860 861 lim -= 3; 862 for (; f < lim; x += 4, f += 4) { 863 // Load 4 pixels from s1, and split the alpha-green and red-blue component 864 __m128i top = _mm_loadu_si128((__m128i*)((const uint *)(s1)+x)); 865 __m128i topAG = _mm_srli_epi16(top, 8); 866 __m128i topRB = _mm_and_si128(top, colorMask); 867 // Multiplies each colour component by idisty 868 topAG = _mm_mullo_epi16 (topAG, idisty_); 869 topRB = _mm_mullo_epi16 (topRB, idisty_); 870 871 // Same for the s2 vector 872 __m128i bottom = _mm_loadu_si128((__m128i*)((const uint *)(s2)+x)); 873 __m128i bottomAG = _mm_srli_epi16(bottom, 8); 874 __m128i bottomRB = _mm_and_si128(bottom, colorMask); 875 bottomAG = _mm_mullo_epi16 (bottomAG, disty_); 876 bottomRB = _mm_mullo_epi16 (bottomRB, disty_); 877 878 // Add the values, and shift to only keep 8 significant bits per colors 879 __m128i rAG =_mm_add_epi16(topAG, bottomAG); 880 rAG = _mm_srli_epi16(rAG, 8); 881 _mm_storeu_si128((__m128i*)(&intermediate_buffer[1][f]), rAG); 882 __m128i rRB =_mm_add_epi16(topRB, bottomRB); 883 rRB = _mm_srli_epi16(rRB, 8); 884 _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB); 885 } 886 #elif defined(QT_ALWAYS_HAVE_NEON) 887 const int16x8_t disty_ = vdupq_n_s16(disty); 888 const int16x8_t idisty_ = vdupq_n_s16(idisty); 889 const int16x8_t colorMask = vdupq_n_s16(0x00ff); 890 891 lim -= 3; 892 for (; f < lim; x += 4, f += 4) { 893 // Load 4 pixels from s1, and split the alpha-green and red-blue component 894 int16x8_t top = vld1q_s16((int16_t*)((const uint *)(s1)+x)); 895 int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8)); 896 int16x8_t topRB = vandq_s16(top, colorMask); 897 // Multiplies each colour component by idisty 898 topAG = vmulq_s16(topAG, idisty_); 899 topRB = vmulq_s16(topRB, idisty_); 900 901 // Same for the s2 vector 902 int16x8_t bottom = vld1q_s16((int16_t*)((const uint *)(s2)+x)); 903 int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8)); 904 int16x8_t bottomRB = vandq_s16(bottom, colorMask); 905 bottomAG = vmulq_s16(bottomAG, disty_); 906 bottomRB = vmulq_s16(bottomRB, disty_); 907 908 // Add the values, and shift to only keep 8 significant bits per colors 909 int16x8_t rAG = vaddq_s16(topAG, bottomAG); 910 rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8)); 911 vst1q_s16((int16_t*)(&intermediate_buffer[1][f]), rAG); 912 int16x8_t rRB = vaddq_s16(topRB, bottomRB); 913 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); 914 vst1q_s16((int16_t*)(&intermediate_buffer[0][f]), rRB); 915 } 916 #endif 917 } 918 for (; f < count; f++) { // Same as above but without sse2 919 if (blendType == BlendTransformedBilinearTiled) { 920 if (x >= image_width) x -= image_width; 921 } else { 922 x = qMin(x, image_x2); 923 } 924 925 uint t = fetch(s1, x, data->texture.colorTable); 926 uint b = fetch(s2, x, data->texture.colorTable); 927 928 intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; 929 intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff; 930 x++; 931 } 932 // Now interpolate the values from the intermediate_buffer to get the final result. 933 fx &= fixed_scale - 1; 934 Q_ASSERT((fx >> 16) == 0); 935 while (b < end) { 936 register int x1 = (fx >> 16); 937 register int x2 = x1 + 1; 938 Q_ASSERT(x1 >= 0); 939 Q_ASSERT(x2 < count); 940 941 register int distx = (fx & 0x0000ffff) >> 8; 942 register int idistx = 256 - distx; 943 int rb = ((intermediate_buffer[0][x1] * idistx + intermediate_buffer[0][x2] * distx) >> 8) & 0xff00ff; 944 int ag = (intermediate_buffer[1][x1] * idistx + intermediate_buffer[1][x2] * distx) & 0xff00ff00; 945 *b = rb | ag; 946 b++; 947 fx += fdx; 948 } 949 } else if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x 950 int y1 = (fy >> 16); 951 int y2; 952 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 953 const uchar *s1 = data->texture.scanLine(y1); 954 const uchar *s2 = data->texture.scanLine(y2); 955 int disty = (fy & 0x0000ffff) >> 8; 956 int idisty = 256 - disty; 957 while (b < end) { 958 int x1 = (fx >> 16); 959 int x2; 960 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 961 uint tl = fetch(s1, x1, data->texture.colorTable); 962 uint tr = fetch(s1, x2, data->texture.colorTable); 963 uint bl = fetch(s2, x1, data->texture.colorTable); 964 uint br = fetch(s2, x2, data->texture.colorTable); 965 966 int distx = (fx & 0x0000ffff) >> 8; 967 int idistx = 256 - distx; 968 969 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); 970 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); 971 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); 972 973 fx += fdx; 974 ++b; 975 } 976 } else { //scale down 977 int y1 = (fy >> 16); 978 int y2; 979 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 980 const uchar *s1 = data->texture.scanLine(y1); 981 const uchar *s2 = data->texture.scanLine(y2); 982 int disty = (fy & 0x0000ffff) >> 12; 983 984 if (blendType != BlendTransformedBilinearTiled && 985 (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { 986 987 #define BILINEAR_DOWNSCALE_BOUNDS_PROLOG \ 988 while (b < end) { \ 989 int x1 = (fx >> 16); \ 990 int x2; \ 991 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); \ 992 if (x1 != x2) \ 993 break; \ 994 uint tl = fetch(s1, x1, data->texture.colorTable); \ 995 uint tr = fetch(s1, x2, data->texture.colorTable); \ 996 uint bl = fetch(s2, x1, data->texture.colorTable); \ 997 uint br = fetch(s2, x2, data->texture.colorTable); \ 998 int distx = (fx & 0x0000ffff) >> 12; \ 999 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \ 1000 fx += fdx; \ 1001 ++b; \ 1002 } \ 1003 uint *boundedEnd; \ 1004 if (fdx > 0) \ 1005 boundedEnd = qMin(end, buffer + uint((image_x2 - (fx >> 16)) / data->m11)); \ 1006 else \ 1007 boundedEnd = qMin(end, buffer + uint((image_x1 - (fx >> 16)) / data->m11)); \ 1008 boundedEnd -= 3; 1009 1010 #if defined(QT_ALWAYS_HAVE_SSE2) 1011 BILINEAR_DOWNSCALE_BOUNDS_PROLOG 1012 1013 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 1014 const __m128i v_256 = _mm_set1_epi16(256); 1015 const __m128i v_disty = _mm_set1_epi16(disty); 1016 __m128i v_fdx = _mm_set1_epi32(fdx*4); 1017 1018 ptrdiff_t secondLine = reinterpret_cast<const uint *>(s2) - reinterpret_cast<const uint *>(s1); 1019 1020 union Vect_buffer { __m128i vect; quint32 i[4]; }; 1021 Vect_buffer v_fx; 1022 1023 for (int i = 0; i < 4; i++) { 1024 v_fx.i[i] = fx; 1025 fx += fdx; 1026 } 1027 1028 while (b < boundedEnd) { 1029 1030 Vect_buffer tl, tr, bl, br; 1031 1032 for (int i = 0; i < 4; i++) { 1033 int x1 = v_fx.i[i] >> 16; 1034 const uint *addr_tl = reinterpret_cast<const uint *>(s1) + x1; 1035 const uint *addr_tr = addr_tl + 1; 1036 tl.i[i] = *addr_tl; 1037 tr.i[i] = *addr_tr; 1038 bl.i[i] = *(addr_tl+secondLine); 1039 br.i[i] = *(addr_tr+secondLine); 1040 } 1041 __m128i v_distx = _mm_srli_epi16(v_fx.vect, 12); 1042 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0)); 1043 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0)); 1044 1045 interpolate_4_pixels_16_sse2(tl.vect, tr.vect, bl.vect, br.vect, v_distx, v_disty, colorMask, v_256, b); 1046 b+=4; 1047 v_fx.vect = _mm_add_epi32(v_fx.vect, v_fdx); 1048 } 1049 fx = v_fx.i[0]; 1050 #elif defined(QT_ALWAYS_HAVE_NEON) 1051 BILINEAR_DOWNSCALE_BOUNDS_PROLOG 1052 1053 const int16x8_t colorMask = vdupq_n_s16(0x00ff); 1054 const int16x8_t invColorMask = vmvnq_s16(colorMask); 1055 const int16x8_t v_256 = vdupq_n_s16(256); 1056 const int16x8_t v_disty = vdupq_n_s16(disty); 1057 const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4); 1058 int32x4_t v_fdx = vdupq_n_s32(fdx*4); 1059 1060 ptrdiff_t secondLine = reinterpret_cast<const uint *>(s2) - reinterpret_cast<const uint *>(s1); 1061 1062 union Vect_buffer { int32x4_t vect; quint32 i[4]; }; 1063 Vect_buffer v_fx; 1064 1065 for (int i = 0; i < 4; i++) { 1066 v_fx.i[i] = fx; 1067 fx += fdx; 1068 } 1069 1070 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff); 1071 1072 while (b < boundedEnd) { 1073 1074 Vect_buffer tl, tr, bl, br; 1075 1076 Vect_buffer v_fx_shifted; 1077 v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16); 1078 1079 int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12); 1080 1081 for (int i = 0; i < 4; i++) { 1082 int x1 = v_fx_shifted.i[i]; 1083 const uint *addr_tl = reinterpret_cast<const uint *>(s1) + x1; 1084 const uint *addr_tr = addr_tl + 1; 1085 tl.i[i] = *addr_tl; 1086 tr.i[i] = *addr_tr; 1087 bl.i[i] = *(addr_tl+secondLine); 1088 br.i[i] = *(addr_tr+secondLine); 1089 } 1090 1091 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16)); 1092 1093 interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b); 1094 b+=4; 1095 v_fx.vect = vaddq_s32(v_fx.vect, v_fdx); 1096 } 1097 fx = v_fx.i[0]; 1098 #endif 1099 } 1100 1101 while (b < end) { 1102 int x1 = (fx >> 16); 1103 int x2; 1104 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1105 uint tl = fetch(s1, x1, data->texture.colorTable); 1106 uint tr = fetch(s1, x2, data->texture.colorTable); 1107 uint bl = fetch(s2, x1, data->texture.colorTable); 1108 uint br = fetch(s2, x2, data->texture.colorTable); 1109 int distx = (fx & 0x0000ffff) >> 12; 1110 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); 1111 fx += fdx; 1112 ++b; 1113 } 1114 } 1115 } else { //rotation 1116 if (fabs(data->m11) > 8 || fabs(data->m22) > 8) { 1117 //if we are zooming more than 8 times, we use 8bit precision for the position. 1118 while (b < end) { 1119 int x1 = (fx >> 16); 1120 int x2; 1121 int y1 = (fy >> 16); 1122 int y2; 1123 1124 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1125 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 1126 1127 const uchar *s1 = data->texture.scanLine(y1); 1128 const uchar *s2 = data->texture.scanLine(y2); 1129 1130 uint tl = fetch(s1, x1, data->texture.colorTable); 1131 uint tr = fetch(s1, x2, data->texture.colorTable); 1132 uint bl = fetch(s2, x1, data->texture.colorTable); 1133 uint br = fetch(s2, x2, data->texture.colorTable); 1134 1135 int distx = (fx & 0x0000ffff) >> 8; 1136 int disty = (fy & 0x0000ffff) >> 8; 1137 int idistx = 256 - distx; 1138 int idisty = 256 - disty; 1139 1140 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); 1141 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); 1142 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); 1143 1144 fx += fdx; 1145 fy += fdy; 1146 ++b; 1147 } 1148 } else { 1149 //we are zooming less than 8x, use 4bit precision 1150 while (b < end) { 1151 int x1 = (fx >> 16); 1152 int x2; 1153 int y1 = (fy >> 16); 1154 int y2; 1155 1156 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1157 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 1158 1159 const uchar *s1 = data->texture.scanLine(y1); 1160 const uchar *s2 = data->texture.scanLine(y2); 1161 1162 uint tl = fetch(s1, x1, data->texture.colorTable); 1163 uint tr = fetch(s1, x2, data->texture.colorTable); 1164 uint bl = fetch(s2, x1, data->texture.colorTable); 1165 uint br = fetch(s2, x2, data->texture.colorTable); 1166 1167 int distx = (fx & 0x0000ffff) >> 12; 1168 int disty = (fy & 0x0000ffff) >> 12; 1169 1170 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); 1171 1172 fx += fdx; 1173 fy += fdy; 1174 ++b; 1175 } 1176 } 739 1177 } 740 1178 } else { … … 753 1191 754 1192 int x1 = int(px) - (px < 0); 755 int x2 = x1 + 1;1193 int x2; 756 1194 int y1 = int(py) - (py < 0); 757 int y2 = y1 + 1;1195 int y2; 758 1196 759 1197 int distx = int((px - x1) * 256); … … 762 1200 int idisty = 256 - disty; 763 1201 764 if (blendType == BlendTransformedBilinearTiled) { 765 x1 %= image_width; 766 x2 %= image_width; 767 y1 %= image_height; 768 y2 %= image_height; 769 770 if (x1 < 0) x1 += image_width; 771 if (x2 < 0) x2 += image_width; 772 if (y1 < 0) y1 += image_height; 773 if (y2 < 0) y2 += image_height; 774 775 Q_ASSERT(x1 >= 0 && x1 < image_width); 776 Q_ASSERT(x2 >= 0 && x2 < image_width); 777 Q_ASSERT(y1 >= 0 && y1 < image_height); 778 Q_ASSERT(y2 >= 0 && y2 < image_height); 779 } else { 780 x1 = qBound(0, x1, image_width - 1); 781 x2 = qBound(0, x2, image_width - 1); 782 y1 = qBound(0, y1, image_height - 1); 783 y2 = qBound(0, y2, image_height - 1); 784 } 1202 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1203 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 785 1204 786 1205 const uchar *s1 = data->texture.scanLine(y1); … … 1282 1701 } 1283 1702 1284 staticvoid QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)1703 void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) 1285 1704 { 1286 1705 comp_func_Clear_impl(dest, length, const_alpha); 1287 1706 } 1288 1707 1289 staticvoid QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)1708 void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) 1290 1709 { 1291 1710 comp_func_Clear_impl(dest, length, const_alpha); … … 1296 1715 dest = s * ca + d * cia 1297 1716 */ 1298 staticvoid QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)1717 void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha) 1299 1718 { 1300 1719 if (const_alpha == 255) { … … 1311 1730 } 1312 1731 1313 staticvoid QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)1732 void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha) 1314 1733 { 1315 1734 if (const_alpha == 255) { … … 1325 1744 } 1326 1745 1327 staticvoid QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)1328 { 1329 } 1330 1331 staticvoid QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)1746 void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint) 1747 { 1748 } 1749 1750 void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint) 1332 1751 { 1333 1752 } … … 1339 1758 = s * ca + d * (1 - sa*ca) 1340 1759 */ 1341 staticvoid QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)1760 void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha) 1342 1761 { 1343 1762 if ((const_alpha & qAlpha(color)) == 255) { … … 1354 1773 } 1355 1774 1356 staticvoid QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)1775 void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha) 1357 1776 { 1358 1777 PRELOAD_INIT2(dest, src) … … 1380 1799 = d + s * dia * ca 1381 1800 */ 1382 staticvoid QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)1801 void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha) 1383 1802 { 1384 1803 if (const_alpha != 255) … … 1392 1811 } 1393 1812 1394 staticvoid QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)1813 void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha) 1395 1814 { 1396 1815 PRELOAD_INIT2(dest, src) … … 1415 1834 dest = s * da * ca + d * cia 1416 1835 */ 1417 staticvoid QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)1836 void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha) 1418 1837 { 1419 1838 PRELOAD_INIT(dest) … … 1434 1853 } 1435 1854 1436 staticvoid QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)1855 void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha) 1437 1856 { 1438 1857 PRELOAD_INIT2(dest, src) … … 1458 1877 = d * (sa * ca + cia) 1459 1878 */ 1460 staticvoid QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)1879 void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha) 1461 1880 { 1462 1881 uint a = qAlpha(color); … … 1471 1890 } 1472 1891 1473 staticvoid QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)1892 void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha) 1474 1893 { 1475 1894 PRELOAD_INIT2(dest, src) … … 1494 1913 */ 1495 1914 1496 staticvoid QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)1915 void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha) 1497 1916 { 1498 1917 PRELOAD_INIT(dest) … … 1513 1932 } 1514 1933 1515 staticvoid QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)1934 void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha) 1516 1935 { 1517 1936 PRELOAD_INIT2(dest, src) … … 1537 1956 = d * (sia * ca + cia) 1538 1957 */ 1539 staticvoid QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)1958 void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha) 1540 1959 { 1541 1960 uint a = qAlpha(~color); … … 1549 1968 } 1550 1969 1551 staticvoid QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)1970 void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha) 1552 1971 { 1553 1972 PRELOAD_INIT2(dest, src) … … 1573 1992 = s*ca * da + d * (1 - sa*ca) 1574 1993 */ 1575 staticvoid QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)1994 void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha) 1576 1995 { 1577 1996 if (const_alpha != 255) { … … 1586 2005 } 1587 2006 1588 staticvoid QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)2007 void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha) 1589 2008 { 1590 2009 PRELOAD_INIT2(dest, src) … … 1611 2030 = s*ca * dia + d * (sa*ca + cia) 1612 2031 */ 1613 staticvoid QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)2032 void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha) 1614 2033 { 1615 2034 uint a = qAlpha(color); … … 1626 2045 } 1627 2046 1628 staticvoid QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)2047 void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha) 1629 2048 { 1630 2049 PRELOAD_INIT2(dest, src) … … 1654 2073 = s*ca * dia + d * (1 - sa*ca) 1655 2074 */ 1656 staticvoid QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)2075 void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha) 1657 2076 { 1658 2077 if (const_alpha != 255) … … 1668 2087 } 1669 2088 1670 staticvoid QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)2089 void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha) 1671 2090 { 1672 2091 PRELOAD_INIT2(dest, src) … … 1688 2107 } 1689 2108 1690 static const uint AMASK = 0xff000000;1691 static const uint RMASK = 0x00ff0000;1692 static const uint GMASK = 0x0000ff00;1693 static const uint BMASK = 0x000000ff;1694 1695 2109 struct QFullCoverage { 1696 2110 inline void store(uint *dest, const uint src) const … … 1735 2149 PRELOAD_COND(dest) 1736 2150 uint d = dest[i]; 1737 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) 1738 d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); 1739 #undef MIX 2151 d = comp_func_Plus_one_pixel(d, s); 1740 2152 coverage.store(&dest[i], d); 1741 2153 } 1742 2154 } 1743 2155 1744 staticvoid QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)2156 void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha) 1745 2157 { 1746 2158 if (const_alpha == 255) … … 1759 2171 uint s = src[i]; 1760 2172 1761 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) 1762 d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); 1763 #undef MIX 2173 d = comp_func_Plus_one_pixel(d, s); 1764 2174 1765 2175 coverage.store(&dest[i], d); … … 1767 2177 } 1768 2178 1769 staticvoid QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)2179 void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha) 1770 2180 { 1771 2181 if (const_alpha == 255) … … 1808 2218 } 1809 2219 1810 staticvoid QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)2220 void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha) 1811 2221 { 1812 2222 if (const_alpha == 255) … … 1839 2249 } 1840 2250 1841 staticvoid QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)2251 void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha) 1842 2252 { 1843 2253 if (const_alpha == 255) … … 1876 2286 } 1877 2287 1878 staticvoid QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)2288 void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha) 1879 2289 { 1880 2290 if (const_alpha == 255) … … 1907 2317 } 1908 2318 1909 staticvoid QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)2319 void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha) 1910 2320 { 1911 2321 if (const_alpha == 255) … … 1955 2365 } 1956 2366 1957 staticvoid QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)2367 void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha) 1958 2368 { 1959 2369 if (const_alpha == 255) … … 1986 2396 } 1987 2397 1988 staticvoid QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)2398 void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha) 1989 2399 { 1990 2400 if (const_alpha == 255) … … 2028 2438 } 2029 2439 2030 staticvoid QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)2440 void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha) 2031 2441 { 2032 2442 if (const_alpha == 255) … … 2059 2469 } 2060 2470 2061 staticvoid QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)2471 void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha) 2062 2472 { 2063 2473 if (const_alpha == 255) … … 2101 2511 } 2102 2512 2103 staticvoid QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)2513 void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha) 2104 2514 { 2105 2515 if (const_alpha == 255) … … 2132 2542 } 2133 2543 2134 staticvoid QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)2544 void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha) 2135 2545 { 2136 2546 if (const_alpha == 255) … … 2184 2594 } 2185 2595 2186 staticvoid QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)2596 void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha) 2187 2597 { 2188 2598 if (const_alpha == 255) … … 2215 2625 } 2216 2626 2217 staticvoid QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)2627 void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha) 2218 2628 { 2219 2629 if (const_alpha == 255) … … 2267 2677 } 2268 2678 2269 staticvoid QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)2679 void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha) 2270 2680 { 2271 2681 if (const_alpha == 255) … … 2298 2708 } 2299 2709 2300 staticvoid QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)2710 void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha) 2301 2711 { 2302 2712 if (const_alpha == 255) … … 2347 2757 } 2348 2758 2349 staticvoid QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)2759 void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha) 2350 2760 { 2351 2761 if (const_alpha == 255) … … 2378 2788 } 2379 2789 2380 staticvoid QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)2790 void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha) 2381 2791 { 2382 2792 if (const_alpha == 255) … … 2438 2848 } 2439 2849 2440 staticvoid QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)2850 void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha) 2441 2851 { 2442 2852 if (const_alpha == 255) … … 2469 2879 } 2470 2880 2471 staticvoid QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)2881 void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha) 2472 2882 { 2473 2883 if (const_alpha == 255) … … 2511 2921 } 2512 2922 2513 staticvoid QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)2923 void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha) 2514 2924 { 2515 2925 if (const_alpha == 255) … … 2542 2952 } 2543 2953 2544 staticvoid QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)2954 void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha) 2545 2955 { 2546 2956 if (const_alpha == 255) … … 2578 2988 } 2579 2989 2580 staticvoid QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)2990 void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha) 2581 2991 { 2582 2992 if (const_alpha == 255) … … 2609 3019 } 2610 3020 2611 staticvoid QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)3021 void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha) 2612 3022 { 2613 3023 if (const_alpha == 255) … … 2622 3032 #endif 2623 3033 2624 staticvoid QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,2625 2626 2627 3034 void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, 3035 int length, 3036 uint color, 3037 uint const_alpha) 2628 3038 { 2629 3039 Q_UNUSED(const_alpha); … … 2632 3042 } 2633 3043 2634 staticvoid QT_FASTCALL rasterop_SourceOrDestination(uint *dest,2635 2636 2637 3044 void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, 3045 const uint *src, 3046 int length, 3047 uint const_alpha) 2638 3048 { 2639 3049 Q_UNUSED(const_alpha); … … 2642 3052 } 2643 3053 2644 staticvoid QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,2645 2646 2647 3054 void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest, 3055 int length, 3056 uint color, 3057 uint const_alpha) 2648 3058 { 2649 3059 Q_UNUSED(const_alpha); … … 2653 3063 } 2654 3064 2655 staticvoid QT_FASTCALL rasterop_SourceAndDestination(uint *dest,2656 2657 2658 3065 void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, 3066 const uint *src, 3067 int length, 3068 uint const_alpha) 2659 3069 { 2660 3070 Q_UNUSED(const_alpha); … … 2665 3075 } 2666 3076 2667 staticvoid QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,2668 2669 2670 3077 void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest, 3078 int length, 3079 uint color, 3080 uint const_alpha) 2671 3081 { 2672 3082 Q_UNUSED(const_alpha); … … 2676 3086 } 2677 3087 2678 staticvoid QT_FASTCALL rasterop_SourceXorDestination(uint *dest,2679 2680 2681 3088 void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, 3089 const uint *src, 3090 int length, 3091 uint const_alpha) 2682 3092 { 2683 3093 Q_UNUSED(const_alpha); … … 2688 3098 } 2689 3099 2690 staticvoid QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,2691 2692 2693 3100 void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest, 3101 int length, 3102 uint color, 3103 uint const_alpha) 2694 3104 { 2695 3105 Q_UNUSED(const_alpha); … … 2701 3111 } 2702 3112 2703 staticvoid QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,2704 2705 2706 3113 void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, 3114 const uint *src, 3115 int length, 3116 uint const_alpha) 2707 3117 { 2708 3118 Q_UNUSED(const_alpha); … … 2713 3123 } 2714 3124 2715 staticvoid QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,2716 2717 2718 3125 void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest, 3126 int length, 3127 uint color, 3128 uint const_alpha) 2719 3129 { 2720 3130 Q_UNUSED(const_alpha); … … 2726 3136 } 2727 3137 2728 staticvoid QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,2729 2730 2731 3138 void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, 3139 const uint *src, 3140 int length, 3141 uint const_alpha) 2732 3142 { 2733 3143 Q_UNUSED(const_alpha); … … 2738 3148 } 2739 3149 2740 staticvoid QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,2741 2742 2743 3150 void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest, 3151 int length, 3152 uint color, 3153 uint const_alpha) 2744 3154 { 2745 3155 Q_UNUSED(const_alpha); … … 2751 3161 } 2752 3162 2753 staticvoid QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,2754 2755 2756 3163 void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, 3164 const uint *src, 3165 int length, 3166 uint const_alpha) 2757 3167 { 2758 3168 Q_UNUSED(const_alpha); … … 2763 3173 } 2764 3174 2765 staticvoid QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,2766 3175 void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, 3176 uint color, uint const_alpha) 2767 3177 { 2768 3178 Q_UNUSED(const_alpha); … … 2770 3180 } 2771 3181 2772 staticvoid QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,2773 3182 void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, 3183 int length, uint const_alpha) 2774 3184 { 2775 3185 Q_UNUSED(const_alpha); … … 2778 3188 } 2779 3189 2780 staticvoid QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,2781 2782 2783 3190 void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, 3191 int length, 3192 uint color, 3193 uint const_alpha) 2784 3194 { 2785 3195 Q_UNUSED(const_alpha); … … 2791 3201 } 2792 3202 2793 staticvoid QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,2794 2795 2796 3203 void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, 3204 const uint *src, 3205 int length, 3206 uint const_alpha) 2797 3207 { 2798 3208 Q_UNUSED(const_alpha); … … 2803 3213 } 2804 3214 2805 staticvoid QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,2806 2807 2808 3215 void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, 3216 int length, 3217 uint color, 3218 uint const_alpha) 2809 3219 { 2810 3220 Q_UNUSED(const_alpha); … … 2815 3225 } 2816 3226 2817 staticvoid QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,2818 2819 2820 3227 void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, 3228 const uint *src, 3229 int length, 3230 uint const_alpha) 2821 3231 { 2822 3232 Q_UNUSED(const_alpha); … … 2827 3237 } 2828 3238 2829 static constCompositionFunctionSolid functionForModeSolid_C[] = {3239 static CompositionFunctionSolid functionForModeSolid_C[] = { 2830 3240 comp_func_solid_SourceOver, 2831 3241 comp_func_solid_DestinationOver, … … 2865 3275 static const CompositionFunctionSolid *functionForModeSolid = functionForModeSolid_C; 2866 3276 2867 static constCompositionFunction functionForMode_C[] = {3277 static CompositionFunction functionForMode_C[] = { 2868 3278 comp_func_SourceOver, 2869 3279 comp_func_DestinationOver, … … 3701 4111 inline quint32 alpha_4(const qargb8555 *src) 3702 4112 { 3703 Q_ASSERT(( long(src) & 0x3) == 0);4113 Q_ASSERT((quintptr(src) & 0x3) == 0); 3704 4114 const quint8 *src8 = reinterpret_cast<const quint8*>(src); 3705 4115 return src8[0] << 24 | src8[3] << 16 | src8[6] << 8 | src8[9]; … … 3884 4294 inline void interpolate_pixel_2(DST *dest, const SRC *src, quint16 alpha) 3885 4295 { 3886 Q_ASSERT(( long(dest) & 0x3) == 0);3887 Q_ASSERT(( long(src) & 0x3) == 0);4296 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4297 Q_ASSERT((quintptr(src) & 0x3) == 0); 3888 4298 3889 4299 const quint16 a = eff_alpha_2(alpha, dest); … … 3958 4368 const SRC *src, quint8 b) 3959 4369 { 3960 Q_ASSERT(( long(dest) & 0x3) == 0);3961 Q_ASSERT(( long(src) & 0x3) == 0);4370 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4371 Q_ASSERT((quintptr(src) & 0x3) == 0); 3962 4372 3963 4373 Q_ASSERT(!SRC::hasAlpha()); … … 4007 4417 inline void interpolate_pixel_4(DST *dest, const SRC *src, quint32 alpha) 4008 4418 { 4009 Q_ASSERT(( long(dest) & 0x3) == 0);4010 Q_ASSERT(( long(src) & 0x3) == 0);4419 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4420 Q_ASSERT((quintptr(src) & 0x3) == 0); 4011 4421 4012 4422 const quint32 a = eff_alpha_4(alpha, dest); … … 4027 4437 quint32 alpha) 4028 4438 { 4029 Q_ASSERT(( long(dest) & 0x3) == 0);4030 Q_ASSERT(( long(src) & 0x3) == 0);4439 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4440 Q_ASSERT((quintptr(src) & 0x3) == 0); 4031 4441 4032 4442 const quint32 a = eff_alpha_4(alpha, dest); … … 4123 4533 quint32 alpha) 4124 4534 { 4125 Q_ASSERT(( long(dest) & 0x3) == 0);4126 Q_ASSERT(( long(src) & 0x3) == 0);4535 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4536 Q_ASSERT((quintptr(src) & 0x3) == 0); 4127 4537 4128 4538 … … 4219 4629 quint32 alpha) 4220 4630 { 4221 Q_ASSERT(( long(dest) & 0x3) == 0);4222 Q_ASSERT(( long(src) & 0x3) == 0);4631 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4632 Q_ASSERT((quintptr(src) & 0x3) == 0); 4223 4633 4224 4634 const quint32 a = eff_alpha_4(alpha, dest); … … 4292 4702 const SRC *src, quint8 b) 4293 4703 { 4294 Q_ASSERT(( long(dest) & 0x3) == 0);4295 Q_ASSERT(( long(src) & 0x3) == 0);4704 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4705 Q_ASSERT((quintptr(src) & 0x3) == 0); 4296 4706 4297 4707 dest[0] = dest[0].byte_mul(a) + DST(src[0]).byte_mul(b); … … 4304 4714 inline void blend_sourceOver_4(DST *dest, const SRC *src) 4305 4715 { 4306 Q_ASSERT(( long(dest) & 0x3) == 0);4307 Q_ASSERT(( long(src) & 0x3) == 0);4716 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4717 Q_ASSERT((quintptr(src) & 0x3) == 0); 4308 4718 4309 4719 const quint32 a = alpha_4(src); … … 4320 4730 inline void blend_sourceOver_4(qargb8565 *dest, const qargb8565 *src) 4321 4731 { 4322 Q_ASSERT(( long(dest) & 0x3) == 0);4323 Q_ASSERT(( long(src) & 0x3) == 0);4732 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4733 Q_ASSERT((quintptr(src) & 0x3) == 0); 4324 4734 4325 4735 const quint32 a = alpha_4(src); … … 4334 4744 inline void blend_sourceOver_4(qargb8555 *dest, const qargb8555 *src) 4335 4745 { 4336 Q_ASSERT(( long(dest) & 0x3) == 0);4337 Q_ASSERT(( long(src) & 0x3) == 0);4746 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4747 Q_ASSERT((quintptr(src) & 0x3) == 0); 4338 4748 4339 4749 const quint32 a = alpha_4(src); … … 4348 4758 inline void blend_sourceOver_4(qargb6666 *dest, const qargb6666 *src) 4349 4759 { 4350 Q_ASSERT(( long(dest) & 0x3) == 0);4351 Q_ASSERT(( long(src) & 0x3) == 0);4760 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4761 Q_ASSERT((quintptr(src) & 0x3) == 0); 4352 4762 4353 4763 const quint32 a = alpha_4(src); … … 4411 4821 Q_ASSERT(sizeof(DST) == 2); 4412 4822 Q_ASSERT(sizeof(SRC) == 2); 4413 Q_ASSERT(( long(dest) & 0x3) == (long(src) & 0x3));4823 Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); 4414 4824 Q_ASSERT(coverage > 0); 4415 4825 … … 4479 4889 4480 4890 while (length >= 2) { 4481 Q_ASSERT(( long(dest) & 3) == 0);4482 Q_ASSERT(( long(src) & 3) == 0);4891 Q_ASSERT((quintptr(dest) & 3) == 0); 4892 Q_ASSERT((quintptr(src) & 3) == 0); 4483 4893 4484 4894 const quint16 a = alpha_2(src); … … 4511 4921 quint8 coverage, int length) 4512 4922 { 4513 Q_ASSERT(( long(dest) & 0x3) == (long(src) & 0x3));4923 Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); 4514 4924 Q_ASSERT(sizeof(DST) == 3); 4515 4925 Q_ASSERT(coverage > 0); … … 4536 4946 if (SRC::hasAlpha()) { 4537 4947 while (length >= 4) { 4538 const quint32 alpha = BYTE_MUL(uint(alpha_4(src)), uint(coverage));4948 const quint32 alpha = QT_PREPEND_NAMESPACE(BYTE_MUL)(uint(alpha_4(src)), uint(coverage)); 4539 4949 if (alpha) 4540 4950 interpolate_pixel_4(dest, src, alpha); … … 4734 5144 void *userData) 4735 5145 { 4736 #if defined(QT_QWS_DEPTH_16)5146 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 4737 5147 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 4738 5148 … … 4987 5397 copy_image_width *= 2; 4988 5398 } 4989 qt_memconvert(dest, src, length); 5399 if (length > 0) 5400 qt_memconvert(dest, src, length); 4990 5401 } else { 4991 5402 while (length) { … … 5072 5483 static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) 5073 5484 { 5074 #if defined(QT_QWS_DEPTH_16)5485 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 5075 5486 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 5076 5487 … … 5138 5549 #endif 5139 5550 blend_tiled_generic<RegularSpans>(count, spans, userData); 5140 }5141 5142 5143 template <SpanMethod spanMethod>5144 Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData)5145 {5146 QSpanData *data = reinterpret_cast<QSpanData *>(userData);5147 if (data->texture.format != QImage::Format_ARGB32_Premultiplied5148 && data->texture.format != QImage::Format_RGB32) {5149 blend_src_generic<spanMethod>(count, spans, userData);5150 return;5151 }5152 5153 CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];5154 uint buffer[buffer_size];5155 5156 int image_x1 = data->texture.x1;5157 int image_y1 = data->texture.y1;5158 int image_x2 = data->texture.x2;5159 int image_y2 = data->texture.y2;5160 const int scanline_offset = data->texture.bytesPerLine / 4;5161 5162 if (data->fast_matrix) {5163 // The increment pr x in the scanline5164 int fdx = (int)(data->m11 * fixed_scale);5165 int fdy = (int)(data->m12 * fixed_scale);5166 5167 while (count--) {5168 void *t = data->rasterBuffer->scanLine(spans->y);5169 5170 uint *target = ((uint *)t) + spans->x;5171 uint *image_bits = (uint *)data->texture.imageData;5172 5173 const qreal cx = spans->x + 0.5;5174 const qreal cy = spans->y + 0.5;5175 5176 int x = int((data->m21 * cy5177 + data->m11 * cx + data->dx) * fixed_scale) - half_point;5178 int y = int((data->m22 * cy5179 + data->m12 * cx + data->dy) * fixed_scale) - half_point;5180 5181 int length = spans->len;5182 const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;5183 while (length) {5184 int l = qMin(length, buffer_size);5185 const uint *end = buffer + l;5186 uint *b = buffer;5187 while (b < end) {5188 int x1 = (x >> 16);5189 int x2 = x1 + 1;5190 int y1 = (y >> 16);5191 int y2 = y1 + 1;5192 5193 int distx = ((x - (x1 << 16)) >> 8);5194 int disty = ((y - (y1 << 16)) >> 8);5195 int idistx = 256 - distx;5196 int idisty = 256 - disty;5197 5198 x1 = qBound(image_x1, x1, image_x2 - 1);5199 x2 = qBound(image_x1, x2, image_x2 - 1);5200 y1 = qBound(image_y1, y1, image_y2 - 1);5201 y2 = qBound(image_y1, y2, image_y2 - 1);5202 5203 int y1_offset = y1 * scanline_offset;5204 int y2_offset = y2 * scanline_offset;5205 5206 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5207 uint tl = gccBug(image_bits[y1_offset + x1]);5208 uint tr = gccBug(image_bits[y1_offset + x2]);5209 uint bl = gccBug(image_bits[y2_offset + x1]);5210 uint br = gccBug(image_bits[y2_offset + x2]);5211 #else5212 uint tl = image_bits[y1_offset + x1];5213 uint tr = image_bits[y1_offset + x2];5214 uint bl = image_bits[y2_offset + x1];5215 uint br = image_bits[y2_offset + x2];5216 #endif5217 5218 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5219 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5220 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5221 ++b;5222 5223 x += fdx;5224 y += fdy;5225 }5226 if (spanMethod == RegularSpans)5227 func(target, buffer, l, coverage);5228 else5229 drawBufferSpan(data, buffer, buffer_size,5230 spans->x + spans->len - length,5231 spans->y, l, coverage);5232 target += l;5233 length -= l;5234 }5235 ++spans;5236 }5237 } else {5238 const qreal fdx = data->m11;5239 const qreal fdy = data->m12;5240 const qreal fdw = data->m13;5241 5242 while (count--) {5243 void *t = data->rasterBuffer->scanLine(spans->y);5244 5245 uint *target = ((uint *)t) + spans->x;5246 uint *image_bits = (uint *)data->texture.imageData;5247 5248 const qreal cx = spans->x + 0.5;5249 const qreal cy = spans->y + 0.5;5250 5251 qreal x = data->m21 * cy + data->m11 * cx + data->dx;5252 qreal y = data->m22 * cy + data->m12 * cx + data->dy;5253 qreal w = data->m23 * cy + data->m13 * cx + data->m33;5254 5255 int length = spans->len;5256 const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;5257 while (length) {5258 int l = qMin(length, buffer_size);5259 const uint *end = buffer + l;5260 uint *b = buffer;5261 while (b < end) {5262 const qreal iw = w == 0 ? 1 : 1 / w;5263 const qreal px = x * iw - 0.5;5264 const qreal py = y * iw - 0.5;5265 5266 int x1 = int(px) - (px < 0);5267 int x2 = x1 + 1;5268 int y1 = int(py) - (py < 0);5269 int y2 = y1 + 1;5270 5271 int distx = int((px - x1) * 256);5272 int disty = int((py - y1) * 256);5273 int idistx = 256 - distx;5274 int idisty = 256 - disty;5275 5276 x1 = qBound(image_x1, x1, image_x2 - 1);5277 x2 = qBound(image_x1, x2, image_x2 - 1);5278 y1 = qBound(image_y1, y1, image_y2 - 1);5279 y2 = qBound(image_y1, y2, image_y2 - 1);5280 5281 int y1_offset = y1 * scanline_offset;5282 int y2_offset = y2 * scanline_offset;5283 5284 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5285 uint tl = gccBug(image_bits[y1_offset + x1]);5286 uint tr = gccBug(image_bits[y1_offset + x2]);5287 uint bl = gccBug(image_bits[y2_offset + x1]);5288 uint br = gccBug(image_bits[y2_offset + x2]);5289 #else5290 uint tl = image_bits[y1_offset + x1];5291 uint tr = image_bits[y1_offset + x2];5292 uint bl = image_bits[y2_offset + x1];5293 uint br = image_bits[y2_offset + x2];5294 #endif5295 5296 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5297 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5298 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5299 ++b;5300 5301 x += fdx;5302 y += fdy;5303 w += fdw;5304 }5305 if (spanMethod == RegularSpans)5306 func(target, buffer, l, coverage);5307 else5308 drawBufferSpan(data, buffer, buffer_size,5309 spans->x + spans->len - length,5310 spans->y, l, coverage);5311 target += l;5312 length -= l;5313 }5314 ++spans;5315 }5316 }5317 5551 } 5318 5552 … … 5366 5600 while (b < end) { 5367 5601 int x1 = (x >> 16); 5368 int x2 = x1 + 1;5602 int x2; 5369 5603 int y1 = (y >> 16); 5370 int y2 = y1 + 1; 5371 5372 const int distx = ((x - (x1 << 16)) >> 8); 5373 const int disty = ((y - (y1 << 16)) >> 8); 5374 x1 = qBound(src_minx, x1, src_maxx); 5375 x2 = qBound(src_minx, x2, src_maxx); 5376 y1 = qBound(src_miny, y1, src_maxy); 5377 y2 = qBound(src_miny, y2, src_maxy); 5378 5604 int y2; 5605 5606 const int distx = (x & 0x0000ffff) >> 8; 5607 const int disty = (y & 0x0000ffff) >> 8; 5608 5609 if (x1 < src_minx) { 5610 x2 = x1 = src_minx; 5611 } else if (x1 >= src_maxx) { 5612 x2 = x1 = src_maxx; 5613 } else { 5614 x2 = x1 + 1; 5615 } 5616 if (y1 < src_miny) { 5617 y2 = y1 = src_miny; 5618 } else if (y1 >= src_maxy) { 5619 y2 = y1 = src_maxy; 5620 } else { 5621 y2 = y1 + 1; 5622 } 5379 5623 #if 0 5380 5624 if (x1 == x2) { … … 5467 5711 5468 5712 int x1 = int(px) - (px < 0); 5469 int x2 = x1 + 1;5713 int x2; 5470 5714 int y1 = int(py) - (py < 0); 5471 int y2 = y1 + 1;5715 int y2; 5472 5716 5473 5717 const int distx = int((px - x1) * 256); 5474 5718 const int disty = int((py - y1) * 256); 5475 5719 5476 x1 = qBound(src_minx, x1, src_maxx); 5477 x2 = qBound(src_minx, x2, src_maxx); 5478 y1 = qBound(src_miny, y1, src_maxy); 5479 y2 = qBound(src_miny, y2, src_maxy); 5720 if (x1 < src_minx) { 5721 x2 = x1 = src_minx; 5722 } else if (x1 >= src_maxx) { 5723 x2 = x1 = src_maxx; 5724 } else { 5725 x2 = x1 + 1; 5726 } 5727 if (y1 < src_miny) { 5728 y2 = y1 = src_miny; 5729 } else if (y1 >= src_maxy) { 5730 y2 = y1 = src_maxy; 5731 } else { 5732 y2 = y1 + 1; 5733 } 5480 5734 5481 5735 const SRC *src1 = (SRC*)data->texture.scanLine(y1); … … 5577 5831 void *userData) 5578 5832 { 5579 #if defined(QT_QWS_DEPTH_16)5833 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 5580 5834 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 5581 5835 … … 5643 5897 #endif 5644 5898 blend_src_generic<RegularSpans>(count, spans, userData); 5645 }5646 5647 template <SpanMethod spanMethod>5648 Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData)5649 {5650 QSpanData *data = reinterpret_cast<QSpanData *>(userData);5651 if (data->texture.format != QImage::Format_ARGB32_Premultiplied5652 && data->texture.format != QImage::Format_RGB32) {5653 blend_src_generic<spanMethod>(count, spans, userData);5654 return;5655 }5656 5657 CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];5658 uint buffer[buffer_size];5659 5660 int image_width = data->texture.width;5661 int image_height = data->texture.height;5662 const int scanline_offset = data->texture.bytesPerLine / 4;5663 5664 if (data->fast_matrix) {5665 // The increment pr x in the scanline5666 int fdx = (int)(data->m11 * fixed_scale);5667 int fdy = (int)(data->m12 * fixed_scale);5668 5669 while (count--) {5670 void *t = data->rasterBuffer->scanLine(spans->y);5671 5672 uint *target = ((uint *)t) + spans->x;5673 uint *image_bits = (uint *)data->texture.imageData;5674 5675 const qreal cx = spans->x + 0.5;5676 const qreal cy = spans->y + 0.5;5677 5678 int x = int((data->m21 * cy5679 + data->m11 * cx + data->dx) * fixed_scale) - half_point;5680 int y = int((data->m22 * cy5681 + data->m12 * cx + data->dy) * fixed_scale) - half_point;5682 5683 int length = spans->len;5684 const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;5685 while (length) {5686 int l = qMin(length, buffer_size);5687 const uint *end = buffer + l;5688 uint *b = buffer;5689 while (b < end) {5690 int x1 = (x >> 16);5691 int x2 = (x1 + 1);5692 int y1 = (y >> 16);5693 int y2 = (y1 + 1);5694 5695 int distx = ((x - (x1 << 16)) >> 8);5696 int disty = ((y - (y1 << 16)) >> 8);5697 int idistx = 256 - distx;5698 int idisty = 256 - disty;5699 5700 x1 %= image_width;5701 x2 %= image_width;5702 y1 %= image_height;5703 y2 %= image_height;5704 5705 if (x1 < 0) x1 += image_width;5706 if (x2 < 0) x2 += image_width;5707 if (y1 < 0) y1 += image_height;5708 if (y2 < 0) y2 += image_height;5709 5710 Q_ASSERT(x1 >= 0 && x1 < image_width);5711 Q_ASSERT(x2 >= 0 && x2 < image_width);5712 Q_ASSERT(y1 >= 0 && y1 < image_height);5713 Q_ASSERT(y2 >= 0 && y2 < image_height);5714 5715 int y1_offset = y1 * scanline_offset;5716 int y2_offset = y2 * scanline_offset;5717 5718 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5719 uint tl = gccBug(image_bits[y1_offset + x1]);5720 uint tr = gccBug(image_bits[y1_offset + x2]);5721 uint bl = gccBug(image_bits[y2_offset + x1]);5722 uint br = gccBug(image_bits[y2_offset + x2]);5723 #else5724 uint tl = image_bits[y1_offset + x1];5725 uint tr = image_bits[y1_offset + x2];5726 uint bl = image_bits[y2_offset + x1];5727 uint br = image_bits[y2_offset + x2];5728 #endif5729 5730 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5731 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5732 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5733 ++b;5734 x += fdx;5735 y += fdy;5736 }5737 if (spanMethod == RegularSpans)5738 func(target, buffer, l, coverage);5739 else5740 drawBufferSpan(data, buffer, buffer_size,5741 spans->x + spans->len - length,5742 spans->y, l, coverage);5743 target += l;5744 length -= l;5745 }5746 ++spans;5747 }5748 } else {5749 const qreal fdx = data->m11;5750 const qreal fdy = data->m12;5751 const qreal fdw = data->m13;5752 while (count--) {5753 void *t = data->rasterBuffer->scanLine(spans->y);5754 5755 uint *target = ((uint *)t) + spans->x;5756 uint *image_bits = (uint *)data->texture.imageData;5757 5758 const qreal cx = spans->x + 0.5;5759 const qreal cy = spans->y + 0.5;5760 5761 qreal x = data->m21 * cy + data->m11 * cx + data->dx;5762 qreal y = data->m22 * cy + data->m12 * cx + data->dy;5763 qreal w = data->m23 * cy + data->m13 * cx + data->m33;5764 5765 int length = spans->len;5766 const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;5767 while (length) {5768 int l = qMin(length, buffer_size);5769 const uint *end = buffer + l;5770 uint *b = buffer;5771 while (b < end) {5772 const qreal iw = w == 0 ? 1 : 1 / w;5773 const qreal px = x * iw - 0.5;5774 const qreal py = y * iw - 0.5;5775 5776 int x1 = int(px) - (px < 0);5777 int x2 = x1 + 1;5778 int y1 = int(py) - (py < 0);5779 int y2 = y1 + 1;5780 5781 int distx = int((px - x1) * 256);5782 int disty = int((py - y1) * 256);5783 int idistx = 256 - distx;5784 int idisty = 256 - disty;5785 5786 x1 %= image_width;5787 x2 %= image_width;5788 y1 %= image_height;5789 y2 %= image_height;5790 5791 if (x1 < 0) x1 += image_width;5792 if (x2 < 0) x2 += image_width;5793 if (y1 < 0) y1 += image_height;5794 if (y2 < 0) y2 += image_height;5795 5796 Q_ASSERT(x1 >= 0 && x1 < image_width);5797 Q_ASSERT(x2 >= 0 && x2 < image_width);5798 Q_ASSERT(y1 >= 0 && y1 < image_height);5799 Q_ASSERT(y2 >= 0 && y2 < image_height);5800 5801 int y1_offset = y1 * scanline_offset;5802 int y2_offset = y2 * scanline_offset;5803 5804 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5805 uint tl = gccBug(image_bits[y1_offset + x1]);5806 uint tr = gccBug(image_bits[y1_offset + x2]);5807 uint bl = gccBug(image_bits[y2_offset + x1]);5808 uint br = gccBug(image_bits[y2_offset + x2]);5809 #else5810 uint tl = image_bits[y1_offset + x1];5811 uint tr = image_bits[y1_offset + x2];5812 uint bl = image_bits[y2_offset + x1];5813 uint br = image_bits[y2_offset + x2];5814 #endif5815 5816 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5817 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5818 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5819 ++b;5820 x += fdx;5821 y += fdy;5822 w += fdw;5823 }5824 if (spanMethod == RegularSpans)5825 func(target, buffer, l, coverage);5826 else5827 drawBufferSpan(data, buffer, buffer_size,5828 spans->x + spans->len - length,5829 spans->y, l, coverage);5830 target += l;5831 length -= l;5832 }5833 ++spans;5834 }5835 }5836 5899 } 5837 5900 … … 6164 6227 void *userData) 6165 6228 { 6166 #if defined(QT_QWS_DEPTH_16)6229 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 6167 6230 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 6168 6231 … … 6480 6543 int py = int(ty) - (ty < 0); 6481 6544 6545 px %= image_width; 6546 py %= image_height; 6482 6547 if (px < 0) 6483 6548 px += image_width; … … 6577 6642 void *userData) 6578 6643 { 6579 #if defined(QT_QWS_DEPTH_16)6644 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 6580 6645 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 6581 6646 … … 6738 6803 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 6739 6804 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 6740 SPANFUNC_POINTER(blend_ transformed_bilinear_argb, RegularSpans), // ARGB32_Premultiplied6805 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied 6741 6806 blend_transformed_bilinear_rgb565, 6742 6807 blend_transformed_bilinear_argb8565, … … 6757 6822 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 6758 6823 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 6759 SPANFUNC_POINTER(blend_ transformed_bilinear_tiled_argb, RegularSpans), // ARGB32_Premultiplied6824 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied 6760 6825 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16 6761 6826 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied … … 6856 6921 blend_src_generic<CallbackSpans>, // RGB32 6857 6922 blend_src_generic<CallbackSpans>, // ARGB32 6858 blend_ transformed_bilinear_argb<CallbackSpans>, // ARGB32_Premultiplied6923 blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied 6859 6924 blend_src_generic<CallbackSpans>, // RGB16 6860 6925 blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied … … 6875 6940 blend_src_generic<CallbackSpans>, // RGB32 6876 6941 blend_src_generic<CallbackSpans>, // ARGB32 6877 blend_ transformed_bilinear_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied6942 blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied 6878 6943 blend_src_generic<CallbackSpans>, // RGB16 6879 6944 blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied … … 7135 7200 if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) 7136 7201 smoothing = winSmooth / 1000.0; 7202 7203 // Safeguard ourselves against corrupt registry values... 7204 if (smoothing > 5 || smoothing < 1) 7205 smoothing = 1.4; 7206 7137 7207 #endif 7138 7208 … … 7721 7791 qt_memfill16_func qt_memfill16 = qt_memfill16_setup; 7722 7792 7723 enum CPUFeatures {7724 None = 0,7725 MMX = 0x1,7726 MMXEXT = 0x2,7727 MMX3DNOW = 0x4,7728 MMX3DNOWEXT = 0x8,7729 SSE = 0x10,7730 SSE2 = 0x20,7731 CMOV = 0x40,7732 IWMMXT = 0x80,7733 NEON = 0x1007734 };7735 7736 static uint detectCPUFeatures()7737 {7738 #if defined (Q_OS_WINCE)7739 #if defined (ARM)7740 if (IsProcessorFeaturePresent(PF_ARM_INTEL_WMMX))7741 return IWMMXT;7742 #elif defined(_X86_)7743 uint features = 0;7744 #if defined QT_HAVE_MMX7745 if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE))7746 features |= MMX;7747 #endif7748 #if defined QT_HAVE_3DNOW7749 if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE))7750 features |= MMX3DNOW;7751 #endif7752 return features;7753 #endif7754 return 0;7755 #elif defined(QT_HAVE_IWMMXT)7756 // runtime detection only available when running as a previlegied process7757 static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();7758 return doIWMMXT ? IWMMXT : 0;7759 #elif defined(QT_HAVE_NEON)7760 static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();7761 return doNEON ? NEON : 0;7762 #else7763 uint features = 0;7764 #if defined(__x86_64__) || defined(Q_OS_WIN64)7765 features = MMX|SSE|SSE2|CMOV;7766 #elif defined(__ia64__)7767 features = MMX|SSE|SSE2;7768 #elif defined(__i386__) || defined(_M_IX86)7769 unsigned int extended_result = 0;7770 uint result = 0;7771 /* see p. 118 of amd64 instruction set manual Vol3 */7772 #if defined(Q_CC_GNU)7773 asm ("push %%ebx\n"7774 "pushf\n"7775 "pop %%eax\n"7776 "mov %%eax, %%ebx\n"7777 "xor $0x00200000, %%eax\n"7778 "push %%eax\n"7779 "popf\n"7780 "pushf\n"7781 "pop %%eax\n"7782 "xor %%edx, %%edx\n"7783 "xor %%ebx, %%eax\n"7784 "jz 1f\n"7785 7786 "mov $0x00000001, %%eax\n"7787 "cpuid\n"7788 "1:\n"7789 "pop %%ebx\n"7790 "mov %%edx, %0\n"7791 : "=r" (result)7792 :7793 : "%eax", "%ecx", "%edx"7794 );7795 7796 asm ("push %%ebx\n"7797 "pushf\n"7798 "pop %%eax\n"7799 "mov %%eax, %%ebx\n"7800 "xor $0x00200000, %%eax\n"7801 "push %%eax\n"7802 "popf\n"7803 "pushf\n"7804 "pop %%eax\n"7805 "xor %%edx, %%edx\n"7806 "xor %%ebx, %%eax\n"7807 "jz 2f\n"7808 7809 "mov $0x80000000, %%eax\n"7810 "cpuid\n"7811 "cmp $0x80000000, %%eax\n"7812 "jbe 2f\n"7813 "mov $0x80000001, %%eax\n"7814 "cpuid\n"7815 "2:\n"7816 "pop %%ebx\n"7817 "mov %%edx, %0\n"7818 : "=r" (extended_result)7819 :7820 : "%eax", "%ecx", "%edx"7821 );7822 #elif defined (Q_OS_WIN)7823 _asm {7824 push eax7825 push ebx7826 push ecx7827 push edx7828 pushfd7829 pop eax7830 mov ebx, eax7831 xor eax, 00200000h7832 push eax7833 popfd7834 pushfd7835 pop eax7836 mov edx, 07837 xor eax, ebx7838 jz skip7839 7840 mov eax, 17841 cpuid7842 mov result, edx7843 skip:7844 pop edx7845 pop ecx7846 pop ebx7847 pop eax7848 }7849 7850 _asm {7851 push eax7852 push ebx7853 push ecx7854 push edx7855 pushfd7856 pop eax7857 mov ebx, eax7858 xor eax, 00200000h7859 push eax7860 popfd7861 pushfd7862 pop eax7863 mov edx, 07864 xor eax, ebx7865 jz skip27866 7867 mov eax, 80000000h7868 cpuid7869 cmp eax, 80000000h7870 jbe skip27871 mov eax, 80000001h7872 cpuid7873 mov extended_result, edx7874 skip2:7875 pop edx7876 pop ecx7877 pop ebx7878 pop eax7879 }7880 #endif7881 7882 // result now contains the standard feature bits7883 if (result & (1u << 15))7884 features |= CMOV;7885 if (result & (1u << 23))7886 features |= MMX;7887 if (extended_result & (1u << 22))7888 features |= MMXEXT;7889 if (extended_result & (1u << 31))7890 features |= MMX3DNOW;7891 if (extended_result & (1u << 30))7892 features |= MMX3DNOWEXT;7893 if (result & (1u << 25))7894 features |= SSE;7895 if (result & (1u << 26))7896 features |= SSE2;7897 #endif // i3867898 7899 if (qgetenv("QT_NO_MMX").toInt())7900 features ^= MMX;7901 if (qgetenv("QT_NO_MMXEXT").toInt())7902 features ^= MMXEXT;7903 if (qgetenv("QT_NO_3DNOW").toInt())7904 features ^= MMX3DNOW;7905 if (qgetenv("QT_NO_3DNOWEXT").toInt())7906 features ^= MMX3DNOWEXT;7907 if (qgetenv("QT_NO_SSE").toInt())7908 features ^= SSE;7909 if (qgetenv("QT_NO_SSE2").toInt())7910 features ^= SSE2;7911 7912 return features;7913 #endif7914 }7915 7916 #if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6)7917 // Move these to qdrawhelper_arm.c when all7918 // functions are implemented using arm assembly.7919 static CompositionFunctionSolid qt_functionForModeSolid_ARMv6[numCompositionFunctions] = {7920 comp_func_solid_SourceOver,7921 comp_func_solid_DestinationOver,7922 comp_func_solid_Clear,7923 comp_func_solid_Source,7924 comp_func_solid_Destination,7925 comp_func_solid_SourceIn,7926 comp_func_solid_DestinationIn,7927 comp_func_solid_SourceOut,7928 comp_func_solid_DestinationOut,7929 comp_func_solid_SourceAtop,7930 comp_func_solid_DestinationAtop,7931 comp_func_solid_XOR,7932 comp_func_solid_Plus,7933 comp_func_solid_Multiply,7934 comp_func_solid_Screen,7935 comp_func_solid_Overlay,7936 comp_func_solid_Darken,7937 comp_func_solid_Lighten,7938 comp_func_solid_ColorDodge,7939 comp_func_solid_ColorBurn,7940 comp_func_solid_HardLight,7941 comp_func_solid_SoftLight,7942 comp_func_solid_Difference,7943 comp_func_solid_Exclusion,7944 rasterop_solid_SourceOrDestination,7945 rasterop_solid_SourceAndDestination,7946 rasterop_solid_SourceXorDestination,7947 rasterop_solid_NotSourceAndNotDestination,7948 rasterop_solid_NotSourceOrNotDestination,7949 rasterop_solid_NotSourceXorDestination,7950 rasterop_solid_NotSource,7951 rasterop_solid_NotSourceAndDestination,7952 rasterop_solid_SourceAndNotDestination7953 };7954 7955 static CompositionFunction qt_functionForMode_ARMv6[numCompositionFunctions] = {7956 comp_func_SourceOver_armv6,7957 comp_func_DestinationOver,7958 comp_func_Clear,7959 comp_func_Source_armv6,7960 comp_func_Destination,7961 comp_func_SourceIn,7962 comp_func_DestinationIn,7963 comp_func_SourceOut,7964 comp_func_DestinationOut,7965 comp_func_SourceAtop,7966 comp_func_DestinationAtop,7967 comp_func_XOR,7968 comp_func_Plus,7969 comp_func_Multiply,7970 comp_func_Screen,7971 comp_func_Overlay,7972 comp_func_Darken,7973 comp_func_Lighten,7974 comp_func_ColorDodge,7975 comp_func_ColorBurn,7976 comp_func_HardLight,7977 comp_func_SoftLight,7978 comp_func_Difference,7979 comp_func_Exclusion,7980 rasterop_SourceOrDestination,7981 rasterop_SourceAndDestination,7982 rasterop_SourceXorDestination,7983 rasterop_NotSourceAndNotDestination,7984 rasterop_NotSourceOrNotDestination,7985 rasterop_NotSourceXorDestination,7986 rasterop_NotSource,7987 rasterop_NotSourceAndDestination,7988 rasterop_SourceAndNotDestination7989 };7990 7991 static void qt_blend_color_argb_armv6(int count, const QSpan *spans, void *userData)7992 {7993 QSpanData *data = reinterpret_cast<QSpanData *>(userData);7994 7995 CompositionFunctionSolid func = qt_functionForModeSolid_ARMv6[data->rasterBuffer->compositionMode];7996 while (count--) {7997 uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;7998 func(target, spans->len, data->solid.color, spans->coverage);7999 ++spans;8000 }8001 }8002 8003 #endif // Q_CC_RVCT && QT_HAVE_ARMV68004 8005 8006 7793 void qInitDrawhelperAsm() 8007 7794 { 8008 static uint features = 0xffffffff;8009 if (features != 0xffffffff)8010 return;8011 features = detectCPUFeatures();8012 7795 8013 7796 qt_memfill32 = qt_memfill_template<quint32, quint32>; … … 8017 7800 CompositionFunctionSolid *functionForModeSolidAsm = 0; 8018 7801 8019 #ifdef QT_NO_DEBUG 7802 const uint features = qDetectCPUFeatures(); 8020 7803 if (false) { 8021 7804 #ifdef QT_HAVE_SSE2 … … 8039 7822 #endif 8040 7823 #endif // SSE 8041 #if defined(QT_HAVE_MMXEXT) && defined(QT_HAVE_SSE)8042 } else if (features & MMXEXT) {8043 qt_memfill32 = qt_memfill32_sse;8044 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse;8045 # ifdef QT_HAVE_3DNOW8046 if (features & MMX3DNOW) {8047 qt_memfill32 = qt_memfill32_sse3dnow;8048 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse3dnow;8049 }8050 # endif // 3DNOW8051 #endif // MMXEXT8052 7824 } 8053 7825 #ifdef QT_HAVE_MMX 8054 7826 if (features & MMX) { 8055 7827 functionForModeAsm = qt_functionForMode_MMX; 7828 8056 7829 functionForModeSolidAsm = qt_functionForModeSolid_MMX; 8057 7830 qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx; … … 8080 7853 } 8081 7854 #endif // MMX 7855 7856 #ifdef QT_HAVE_SSE 7857 if (features & SSE) { 7858 extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl, 7859 const uchar *srcPixels, int sbpl, 7860 int w, int h, 7861 int const_alpha); 7862 extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl, 7863 const uchar *srcPixels, int sbpl, 7864 int w, int h, 7865 int const_alpha); 7866 7867 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 7868 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 7869 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 7870 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 7871 } 7872 #endif // SSE 7873 7874 #ifdef QT_HAVE_SSE2 7875 if (features & SSE2) { 7876 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, 7877 const uchar *srcPixels, int sbpl, 7878 int w, int h, 7879 int const_alpha); 7880 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, 7881 const uchar *srcPixels, int sbpl, 7882 int w, int h, 7883 int const_alpha); 7884 7885 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 7886 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 7887 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 7888 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 7889 } 7890 7891 #ifdef QT_HAVE_SSSE3 7892 if (features & SSSE3) { 7893 extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, 7894 const uchar *srcPixels, int sbpl, 7895 int w, int h, 7896 int const_alpha); 7897 7898 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; 7899 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; 7900 } 7901 #endif // SSSE3 7902 7903 #endif // SSE2 8082 7904 8083 7905 #ifdef QT_HAVE_SSE … … 8097 7919 #ifdef QT_HAVE_SSE2 8098 7920 if (features & SSE2) { 8099 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, 8100 const uchar *srcPixels, int sbpl, 8101 int w, int h, 8102 int const_alpha); 8103 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, 8104 const uchar *srcPixels, int sbpl, 8105 int w, int h, 8106 int const_alpha); 8107 8108 8109 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 8110 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 8111 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 8112 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 8113 } else 7921 extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, 7922 const uint *srcPixels, 7923 int length, 7924 uint const_alpha); 7925 extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha); 7926 extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha); 7927 extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha); 7928 7929 functionForModeAsm[0] = comp_func_SourceOver_sse2; 7930 functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2; 7931 functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; 7932 functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2; 7933 } 8114 7934 #endif 8115 { 8116 extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl, 8117 const uchar *srcPixels, int sbpl, 8118 int w, int h, 8119 int const_alpha); 8120 extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl, 8121 const uchar *srcPixels, int sbpl, 8122 int w, int h, 8123 int const_alpha); 8124 8125 8126 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 8127 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 8128 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 8129 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 8130 } 8131 } 8132 #endif // SSE 7935 } 7936 #elif defined(QT_HAVE_SSE2) 7937 // this is the special case when SSE2 is usable but MMX/SSE is not usable (e.g.: Windows x64 + visual studio) 7938 if (features & SSE2) { 7939 functionForModeAsm = qt_functionForMode_onlySSE2; 7940 functionForModeSolidAsm = qt_functionForModeSolid_onlySSE2; 7941 } 7942 #endif 8133 7943 8134 7944 #ifdef QT_HAVE_IWMMXT … … 8140 7950 #endif // IWMMXT 8141 7951 8142 #endif // QT_NO_DEBUG 8143 8144 #if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6) 8145 functionForModeAsm = qt_functionForMode_ARMv6; 8146 functionForModeSolidAsm = qt_functionForModeSolid_ARMv6; 8147 8148 qt_memfill32 = qt_memfill32_armv6; 8149 8150 qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_armv6; 8151 8152 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; 8153 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; 8154 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; 8155 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; 7952 #if defined(QT_HAVE_ARM_SIMD) 7953 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; 7954 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; 7955 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; 7956 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; 8156 7957 #elif defined(QT_HAVE_NEON) 8157 if (features & NEON) { 8158 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 8159 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 8160 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 8161 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 8162 } 7958 if (features & NEON) { 7959 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 7960 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 7961 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 7962 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 7963 qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; 7964 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; 7965 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon; 7966 7967 qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; 7968 qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; 7969 7970 qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon; 7971 qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; 7972 7973 qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; 7974 7975 functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon; 7976 functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon; 7977 functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon; 7978 destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; 7979 destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; 7980 7981 qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; 7982 qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; 7983 qt_memfill32 = qt_memfill32_neon; 7984 } 8163 7985 #endif 8164 7986 … … 8174 7996 functionForModeSolid = functionForModeSolidAsm; 8175 7997 } 8176 if (functionForModeAsm) { 8177 const int destinationMode = QPainter::CompositionMode_Destination; 8178 functionForModeAsm[destinationMode] = functionForMode_C[destinationMode]; 8179 8180 // use the default qdrawhelper implementation for the 8181 // extended composition modes 8182 for (int mode = 12; mode < numCompositionFunctions; ++mode) 8183 functionForModeAsm[mode] = functionForMode_C[mode]; 8184 7998 if (functionForModeAsm) 8185 7999 functionForMode = functionForModeAsm; 8186 }8187 8000 8188 8001 qt_build_pow_tables();
Note:
See TracChangeset
for help on using the changeset viewer.