Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include <mmintrin.h>
  2. #include <xmmintrin.h>
  3. #include <emmintrin.h>
  4.  
  5. typedef unsigned int color_t;
  6.  
  7. void px_rect_alu(void *dst_addr, int pitch, int w, int h, color_t src_color)
  8. {
  9.         while (h--)
  10.         {
  11.                 char *tmp = dst_addr;
  12.                 dst_addr = tmp + pitch;
  13.         __asm__ __volatile__(
  14.           "cld; rep stosl\n\t"
  15.           :: "D"(tmp), "a"(src_color), "c"(w)
  16.           : "flags");
  17.         };
  18. };
  19.  
  20. void px_rect_mmx(void *dst_addr, int pitch, int w, int h, color_t src_color)
  21. {
  22.         register __m64 color;
  23.  
  24.         color = _mm_cvtsi32_si64(src_color);
  25.         color = _mm_unpacklo_pi32(color, color);
  26.  
  27.         while (h--)
  28.         {
  29.                 char *tmp = dst_addr;
  30.                 char *end = tmp + w * sizeof(color_t);
  31.                 dst_addr = tmp + pitch;
  32.  
  33.                 int t = (int)tmp;
  34.                 if (t & 4)
  35.                 {
  36.                         *(color_t*)tmp = src_color;
  37.                         tmp += 4;
  38.                 };
  39.  
  40.                 while (tmp + 64 <= end)
  41.                 {
  42.                         __m64 *_tmp = (__m64*)tmp;
  43.                         _tmp[0] = color;
  44.                         _tmp[1] = color;
  45.                         _tmp[2] = color;
  46.                         _tmp[3] = color;
  47.                         _tmp[4] = color;
  48.                         _tmp[5] = color;
  49.                         _tmp[6] = color;
  50.                         _tmp[7] = color;
  51.                         tmp += 64;
  52.                 };
  53.                 if (tmp + 32 <= end)
  54.                 {
  55.                         __m64 *_tmp = (__m64*)tmp;
  56.                         _tmp[0] = color;
  57.                         _tmp[1] = color;
  58.                         _tmp[2] = color;
  59.                         _tmp[3] = color;
  60.                         tmp += 32;
  61.                 };
  62.                 if (tmp + 16 <= end)
  63.                 {
  64.                         __m64 *_tmp = (__m64*)tmp;
  65.                         _tmp[0] = color;
  66.                         _tmp[1] = color;
  67.                         tmp += 16;
  68.                 };
  69.                 if (tmp + 8 <= end)
  70.                 {
  71.                         __m64 *_tmp = (__m64*)tmp;
  72.                         _tmp[0] = color;
  73.                         tmp += 8;
  74.                 };
  75.                 if (tmp < end)
  76.                         *(color_t*)tmp = src_color;
  77.         };
  78.         _mm_empty();
  79. };
  80.  
  81. void px_rect_xmm(void *dst_addr, int pitch, int w, int h, color_t dst_color)
  82. {
  83.         __m128i color;
  84.  
  85.         color = _mm_set_epi32(dst_color, dst_color, dst_color, dst_color);
  86.  
  87.         while (h--)
  88.         {
  89.                 char *tmp = dst_addr;
  90.                 char *end = tmp + w * sizeof(color_t);
  91.                 dst_addr = tmp + pitch;
  92.  
  93.                 if ((int)tmp & 4)
  94.                 {
  95.                         *(color_t*)tmp = dst_color;
  96.                         tmp += 4;
  97.                 };
  98.                 if ((int)tmp & 8)
  99.                 {
  100.                         __m128i *_tmp = (__m128i*)tmp;
  101.                         _mm_storel_epi64(_tmp, color);
  102.                         tmp += 8;
  103.                 };
  104.  
  105.                 while (tmp + 128 <= end)
  106.                 {
  107.                         __m128i *_tmp = (__m128i*)tmp;
  108.                         _mm_store_si128(&_tmp[0], color);
  109.                         _mm_store_si128(&_tmp[1], color);
  110.                         _mm_store_si128(&_tmp[2], color);
  111.                         _mm_store_si128(&_tmp[3], color);
  112.                         _mm_store_si128(&_tmp[4], color);
  113.                         _mm_store_si128(&_tmp[5], color);
  114.                         _mm_store_si128(&_tmp[6], color);
  115.                         _mm_store_si128(&_tmp[7], color);
  116.                         tmp += 128;
  117.                 };
  118.                 if (tmp + 64 <= end)
  119.                 {
  120.                         __m128i *_tmp = (__m128i*)tmp;
  121.                         _mm_store_si128(&_tmp[0], color);
  122.                         _mm_store_si128(&_tmp[1], color);
  123.                         _mm_store_si128(&_tmp[2], color);
  124.                         _mm_store_si128(&_tmp[3], color);
  125.                         tmp += 64;
  126.                 };
  127.                 if (tmp + 32 <= end)
  128.                 {
  129.                         __m128i *_tmp = (__m128i*)tmp;
  130.                         _mm_store_si128(&_tmp[0], color);
  131.                         _mm_store_si128(&_tmp[1], color);
  132.                         tmp += 32;
  133.                 };
  134.                 if (tmp + 16 <= end)
  135.                 {
  136.                         __m128i *_tmp = (__m128i*)tmp;
  137.                         _mm_store_si128(&_tmp[0], color);
  138.                         tmp += 16;
  139.                 };
  140.                 if (tmp + 8 <= end)
  141.                 {
  142.                         __m128i *_tmp = (__m128i*)tmp;
  143.                         _mm_storel_epi64(_tmp, color);
  144.                         tmp += 8;
  145.                 };
  146.                 if (tmp < end)
  147.                         *(color_t*)tmp = dst_color;
  148.         };
  149. }
  150.  
  151. void px_glyph_alu(void *dst_addr, int dst_pitch,const void *src_addr, int src_pitch,
  152.                       int width, int height, color_t src_color)
  153. {
  154.         while (height-- > 0)
  155.         {
  156.                 int w = width;
  157.                 const unsigned char *src = src_addr;
  158.         color_t *dst = dst_addr;
  159.  
  160.         dst_addr = (char*)dst + dst_pitch;
  161.                 src_addr = src + src_pitch;
  162.  
  163.                 while (w-- > 0)
  164.                 {
  165.                         unsigned char a = *src++;
  166.                         color_t dst_color = *(color_t*)dst;
  167.                         unsigned int rb = dst_color & 0xff00ff;
  168.                         unsigned int g = dst_color & 0x00ff00;
  169.  
  170.                         rb += ((src_color & 0xff00ff) - rb) * a >> 8;
  171.                         g += ((src_color & 0x00ff00) - g) * a >> 8;
  172.  
  173.             *dst++ = (src_color & 0xFF000000) | (rb & 0xff00ff) | (g & 0xff00);
  174.                 };
  175.         }
  176. }
  177.  
  178. __m64 m_4x0080 = { 0x00800080, 0x00800080 };
  179. __m64 m_4x0101 = { 0x01010101, 0x01010101 };
  180. __m64 m_4x00FF = { 0x00FF00FF, 0x00FF00FF };
  181. __m64 m_zero   = { 0 };
  182.  
  183. void px_glyph_sse(void *dst_addr, int dst_pitch, const void *src_addr, int src_pitch,
  184.         int width, int height, color_t src_color)
  185. {
  186.     static __m64 m_4x0080 = { 0x00800080, 0x00800080 };
  187.     static __m64 m_4x0101 = { 0x01010101, 0x01010101 };
  188.     static __m64 m_4x00FF = { 0x00FF00FF, 0x00FF00FF };
  189.     static __m64 m_zero   = { 0 };
  190.  
  191.     __m64 color;
  192.  
  193.         color = _mm_cvtsi32_si64(src_color);
  194.         color = _m_punpcklbw(color, m_zero);
  195.         while (height-- > 0)
  196.         {
  197.                 int w = width;
  198.                 const unsigned char *tmpsrc = src_addr;
  199.         color_t *tmpdst = dst_addr;
  200.  
  201.         dst_addr = (char*)tmpdst + dst_pitch;
  202.                 src_addr = tmpsrc + src_pitch;
  203.  
  204.                 while (w-- > 0)
  205.                 {
  206.                         __m64 m_alpha, m_1_minus_alpha;
  207.                         __m64 src_alpha, dst_color;
  208.  
  209.                         unsigned int alpha = *tmpsrc++;
  210.                         m_alpha = _mm_cvtsi32_si64((alpha << 16) | alpha);
  211.                         dst_color = _mm_cvtsi32_si64(*(int*)tmpdst);
  212.  
  213.                         m_alpha = _mm_unpacklo_pi32(m_alpha, m_alpha);
  214.                         m_1_minus_alpha = _m_psubb(m_4x00FF, m_alpha);
  215.                         dst_color = _m_punpcklbw(dst_color, m_zero);
  216.                         src_alpha = _m_pmullw(color, m_alpha);
  217.                         dst_color = _m_pmullw(dst_color, m_1_minus_alpha);
  218.                         dst_color = _m_paddw(src_alpha, dst_color);
  219.                         dst_color = _m_paddw(dst_color, m_4x0080);
  220.                         dst_color = _mm_mulhi_pu16(dst_color, m_4x0101);
  221.                         dst_color = _mm_packs_pu16(dst_color, dst_color);
  222.             *tmpdst++ = _mm_cvtsi64_si32(dst_color);
  223.                 };
  224.         }
  225.         _mm_empty();
  226. };
  227.