Subversion Repositories Kolibri OS

Rev

Rev 882 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <mmintrin.h>
  3.  
  4.  
  5. static void HLine(char *addr,int width, color_t color)
  6. {
  7.      __m64 dst_color;
  8.  
  9.      dst_color = _mm_cvtsi32_si64(color);
  10.      dst_color = _mm_unpacklo_pi32(dst_color, dst_color);
  11.  
  12.      while (width >= 8)
  13.      {
  14.         __asm__ __volatile__ (
  15.         "movq %[clr],   (%0)\n\t"
  16.         "movq %[clr],  8(%0)\n\t"
  17.         "movq %[clr], 16(%0)\n\t"
  18.         "movq %[clr], 24(%0)\n\t"
  19.         :: "r" (addr), [clr] "y" (dst_color));
  20.         addr += 32;
  21.         width -= 8;
  22.      }
  23.      if (width >= 4)
  24.      {
  25.         __asm__ __volatile__ (
  26.         "movq %[clr],   (%0)\n\t"
  27.         "movq %[clr],  8(%0)\n\t"
  28.         :: "r" (addr), [clr] "y" (dst_color));
  29.         addr += 16;
  30.         width -= 4;
  31.      }
  32.      if (width >= 2)
  33.      {
  34.         __asm__ __volatile__ (
  35.         "movq %[clr],  (%0)\n\t"
  36.         :: "r" (addr), [clr] "y" (dst_color));
  37.         addr += 8;
  38.         width -= 2;
  39.      }
  40.      if ( width )
  41.         __asm__ __volatile__ (
  42.         "movd %[clr],  (%0)\n\t"
  43.         :: "r" (addr), [clr] "y" (dst_color));
  44.  
  45.      _mm_empty();
  46. }
  47.  
  48. static void pxDraw(char *dst_addr, int pitch, int w, int h, color_t dst_color)
  49. {
  50.      __m64 color;
  51.  
  52.      color = _mm_cvtsi32_si64(dst_color);
  53.      color = _mm_unpacklo_pi32(color, color);
  54.  
  55.      while(h--)
  56.      {
  57.         char *tmp_dst =dst_addr;
  58.         int width = w;
  59.         dst_addr += pitch;
  60.  
  61.         while(width >= 8)
  62.         {
  63.            __asm__ __volatile__
  64.            ("movq %[clr],   (%0)\n\t"
  65.             "movq %[clr],  8(%0)\n\t"
  66.             "movq %[clr], 16(%0)\n\t"
  67.             "movq %[clr], 24(%0)\n\t"
  68.             :: "r" (tmp_dst), [clr] "y" (color));
  69.            tmp_dst += 32;
  70.            width -= 8;
  71.         };
  72.         if(width >= 4)
  73.         {
  74.            __asm__ __volatile__
  75.            ("movq %[clr],  (%0)\n\t"
  76.             "movq %[clr], 8(%0)\n\t"
  77.             :: "r" (tmp_dst), [clr] "y" (color));
  78.            tmp_dst += 16;
  79.            width -= 4;
  80.         };
  81.  
  82.         if (width >= 2)
  83.         {
  84.            __asm__ __volatile__
  85.            ("movq %[clr],  (%0)\n\t"
  86.             :: "r" (tmp_dst), [clr] "y" (color));
  87.            tmp_dst += 8;
  88.            width -= 2;
  89.         };
  90.         if(width)
  91.            __asm__ __volatile__
  92.            ("movd %[clr], (%0)\n\t"
  93.             :: "r" (tmp_dst), [clr] "y" (color));
  94.      };
  95.      _mm_empty();
  96. };
  97.  
  98. int ClearPixmap(pixmap_t *pixmap, color_t color)
  99. {
  100.      if( (srv_hw2d != 0) &&
  101.          ( ((int)pixmap == -1) ||
  102.            ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) )
  103.      {
  104.        ioctl_t io;
  105.  
  106.        if((int)pixmap != -1)
  107.           pixmap = (pixmap_t*)pixmap->handle;
  108.  
  109.        io.handle   = srv_hw2d;
  110.        io.io_code  = PX_CLEAR;
  111.        io.input    = &pixmap;
  112.        io.inp_size = 2;
  113.        io.output   = NULL;
  114.        io.out_size = 0;
  115.  
  116.        return call_service(&io);
  117.      }
  118.  
  119.      pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ;
  120.  
  121.      pxDraw(pixmap->mapped, pixmap->pitch,
  122.             pixmap->width, pixmap->height, color);
  123.      return ERR_OK;
  124. };
  125.  
  126. int Line(pixmap_t *pixmap, int x0, int y0, int x1, int y1, color_t color)
  127. {
  128.  
  129.      clip_t clip;
  130.  
  131.      if( (srv_hw2d != 0) &&
  132.          ( (pixmap == (void*)-1) ||
  133.            ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) )
  134.      {
  135.        ioctl_t io;
  136.  
  137.        if((int)pixmap != -1)
  138.           pixmap = (pixmap_t*)pixmap->handle;
  139.  
  140.        io.handle   = srv_hw2d;
  141.        io.io_code  = PX_LINE;
  142.        io.input    = &pixmap;
  143.        io.inp_size = 6;
  144.        io.output   = NULL;
  145.        io.out_size = 0;
  146.  
  147.        return call_service(&io);
  148.      }
  149.  
  150.      pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ;
  151.  
  152.      clip.xmin = 0;
  153.      clip.ymin = 0;
  154.      clip.xmax = pixmap->width-1;
  155.      clip.ymax = pixmap->height-1;
  156.  
  157.      if ( !LineClip( &clip, &x0, &y0, &x1, &y1 ))
  158.      {
  159.         int dx, dy;
  160.         int sx, sy;
  161.         int e, e1, e2, e3;
  162.  
  163.         char *addr;
  164.  
  165.         dx = x1 - x0;
  166.         dy = y1 - y0;
  167.  
  168.         if( dx || dy)
  169.         {
  170.            if( dy == 0 )
  171.            {
  172.               if (dx < 0)
  173.               {
  174.                  dx = -dx;
  175.                  x0 =  x1;
  176.               };
  177.  
  178.               addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  179.               HLine(addr, dx, color);
  180.  
  181.               return ERR_OK;
  182.            };
  183.            if( dx == 0 )
  184.            {
  185.               if (dy < 0)
  186.               {
  187.                  dy = -dy;
  188.                  y0 =  y1;
  189.               };
  190.               addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  191.  
  192.               while ( dy-- )
  193.               {
  194.                  *(color_t*)addr = color;
  195.                  addr += pixmap->pitch;
  196.               }
  197.               return ERR_OK;
  198.            }
  199.  
  200.            sx = 4;
  201.            if ( dx < 0 )
  202.            {
  203.               dx = -dx;
  204.               sx = -sx;
  205.            }
  206.            sy = pixmap->pitch;
  207.            if ( dy < 0 )
  208.            {
  209.               dy = -dy;
  210.               sy = -sy;
  211.            };
  212.  
  213.            addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  214.  
  215.            if (dx > dy)
  216.            {
  217.               e1 = dy << 1;
  218.               e2 = e1 - (dx << 1);
  219.               e  = e1 - dx;
  220.  
  221.               e3 = e2 - e1;
  222.               e  = e - e1;
  223.  
  224.  
  225.               while (dx--)
  226.               {
  227.                  *(color_t*)addr = color;
  228.                  addr += sx;
  229.                  e += e1;
  230.                  if (e >= 0)
  231.                  {
  232.                     addr += sy;
  233.                     e += e3;
  234.                  }
  235.               }
  236.            }
  237.            else
  238.            {
  239.               e1 = dx << 1;
  240.               e2 = e1 - (dy << 1);
  241.               e  = e1 - dy;
  242.               e3 = e2 - e1;
  243.               e  = e - e1;
  244.  
  245.               while (dy--)
  246.               {
  247.                  *(color_t*)addr = color;
  248.                  addr += sy;
  249.                  e += e1;
  250.                  if (e >= 0)
  251.                  {
  252.                     addr += sx;
  253.                     e += e3;
  254.                  }
  255.               }
  256.            }
  257.         }    /*  ( dx || dy ) */
  258.      }
  259.      return ERR_OK;
  260. }
  261.  
  262. int DrawRect(pixmap_t *pixmap, int xorg, int yorg,
  263.                int width, int height,
  264.                color_t dst_color, color_t border)
  265. {
  266.  
  267.      if( ( width <= 0 ) || ( height<=0 ) )
  268.         return ERR_PARAM;
  269.  
  270. /*   if "hardware acceleration present" and
  271.      "destinastion is primary screen or local videomemory"
  272. */
  273.  
  274.      if( (srv_hw2d != 0) &&
  275.          ( (pixmap == (void*)-1) ||
  276.            ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) )
  277.      {
  278.        ioctl_t io;
  279.  
  280.        if((int)pixmap != -1)
  281.           pixmap = (pixmap_t*)pixmap->handle;
  282.  
  283.        io.handle   = srv_hw2d;
  284.        io.io_code  = PX_DRAW_RECT;
  285.        io.input    = &pixmap;
  286.        io.inp_size = 7;
  287.        io.output   = NULL;
  288.        io.out_size = 0;
  289.  
  290.        return call_service(&io);
  291.      }
  292.      else
  293. /*     no acceleration or destination in system memory  */
  294.      {
  295.         clip_t clip;
  296.         int x0, y0, x1, y1, xend, yend;
  297.  
  298.         pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ;
  299.  
  300.         x0 = xorg;
  301.         y0 = yorg;
  302.  
  303.         xend = x1 = x0 + width - 1;
  304.         yend = y1 = y0 + height - 1;
  305.  
  306.         clip.xmin = 0;
  307.         clip.ymin = 0;
  308.         clip.xmax = pixmap->width-1;
  309.         clip.ymax = pixmap->height-1;
  310.  
  311.         if( ! BlockClip( &clip, &x0, &y0, &x1, &y1))
  312.         {
  313.            int w, h;
  314.  
  315.            char *dst_addr;
  316.  
  317.            w = x1 - x0 + 1;
  318.            h = y1 - y0 + 1;
  319.  
  320.            if( (dst_color == border) ||
  321.                ((border & 0xFF000000)==0))
  322.            {
  323.               dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  324.               pxDraw(dst_addr, pixmap->pitch, w, h, dst_color);
  325.            }
  326.            else
  327.            {
  328.               if( y0 == yorg)
  329.               {
  330.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  331.                  HLine(dst_addr, w, border);
  332.                  y0++;
  333.                  h--;
  334.               }
  335.               if( y1 == yend )
  336.               {
  337.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y1 + x0*4];
  338.                  HLine(dst_addr, w, border);
  339.                  h--;
  340.               }
  341.               if( (h > 0) && (x0 == xorg))
  342.               {
  343.                  int dy = h;
  344.  
  345.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  346.  
  347.                  while ( dy-- )
  348.                  {
  349.                     *(color_t*)dst_addr = border;
  350.                     dst_addr += pixmap->pitch;
  351.                  }
  352.                  x0++;
  353.                  w--;
  354.               }
  355.               if( (h > 0) && (x1 == xend))
  356.               {
  357.                  int dy = h;
  358.  
  359.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x1*4];
  360.  
  361.                  while ( dy-- )
  362.                  {
  363.                     *(color_t*)dst_addr = border;
  364.                     dst_addr += pixmap->pitch;
  365.                  }
  366.                  w--;
  367.               }
  368.               if( (w > 0) && (h > 0) )
  369.               {
  370.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  371.                  pxDraw(dst_addr, pixmap->pitch, w, h, dst_color);
  372.               }
  373.            }
  374.         };
  375.      };
  376.      return ERR_OK;
  377. };
  378.  
  379. int FillRect(pixmap_t *pixmap, int xorg, int yorg,
  380.                int width, int height,
  381.                brush_t *dst_brush, color_t border)
  382. {
  383.      if( ( width <= 0 ) || ( height<=0 ) )
  384.         return ERR_PARAM;
  385.  
  386. /*   if "hardware acceleration present" and
  387.      "destinastion is primary screen or local videomemory"
  388. */
  389.  
  390.      if( (srv_hw2d != 0) &&
  391.          ( (pixmap == (void*)-1) ||
  392.            ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) )
  393.      {
  394.         fill_t fill;
  395.         ioctl_t io;
  396.  
  397.         fill.dstpix = ((int)pixmap == -1) ? (pixmap_t*)-1 : (pixmap_t*)pixmap->handle;
  398.         fill.x = xorg;
  399.         fill.y = yorg;
  400.         fill.w = width;
  401.         fill.h = height;
  402.         fill.bkcolor = dst_brush->bkcolor;
  403.         fill.fcolor  = dst_brush->fcolor;
  404.         fill.bmp0 = dst_brush->bmp[0];
  405.         fill.bmp1 = dst_brush->bmp[1];
  406.         fill.border = border;
  407.  
  408.         io.handle   = srv_hw2d;
  409.         io.io_code  = PX_FILL_RECT;
  410.         io.input    = &fill;
  411.         io.inp_size = 10;
  412.         io.output   = NULL;
  413.         io.out_size = 0;
  414.  
  415.         return call_service(&io);
  416.      }
  417.      else
  418. /*      no acceleration or destination in system memory  */
  419.      {
  420.         clip_t clip;
  421.         int x0, y0, x1, y1, xend, yend;
  422.  
  423.         pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ;
  424.  
  425.         x0 = xorg;
  426.         y0 = yorg;
  427.         x1 = xend = x0 + width - 1;
  428.         y1 = yend = y0 + height - 1;
  429.  
  430.         clip.xmin = 0;
  431.         clip.ymin = 0;
  432.         clip.xmax = pixmap->width-1;
  433.         clip.ymax = pixmap->height-1;
  434.  
  435.         if( ! BlockClip( &clip, &x0, &y0, &x1, &y1))
  436.         {
  437.            int w, h, bh, bm_y;
  438.  
  439.            __m64 clr_bb, clr_bf, clr_fb, clr_ff;
  440.            char *dst_addr;
  441.  
  442.            clr_bb = _mm_cvtsi32_si64(dst_brush->bkcolor);
  443.            clr_ff = _mm_cvtsi32_si64(dst_brush->fcolor);
  444.  
  445.            clr_bb = _mm_unpacklo_pi32(clr_bb, clr_bb);
  446.            clr_ff = _mm_unpacklo_pi32(clr_ff, clr_ff);
  447.  
  448.            clr_bf = _mm_unpacklo_pi32(clr_ff, clr_bb);
  449.            clr_fb = _mm_unpacklo_pi32(clr_bb, clr_ff);
  450.  
  451.            w = x1 -x0 + 1;
  452.            bh = h = y1 -y0 + 1;
  453.  
  454.            dst_addr  = & ((char*)(pixmap->mapped))[pixmap->pitch*y0+x0*4];
  455.  
  456.            bm_y = y0 & 7;
  457.  
  458.            while(h--)
  459.            {
  460.               u8_t mask = dst_brush->bits[bm_y];
  461.  
  462.               char *tmp_dst = dst_addr;
  463.               int width = w;
  464.               dst_addr += pixmap->pitch;
  465.               bm_y = (bm_y+1) & 7;
  466.  
  467.               while(width>=2)
  468.               {
  469.                  __asm__ __volatile__
  470.                  ("rolb $2, %0 \n\t"
  471.                   :"+g" (mask):"g"(mask)
  472.                   :"cc");
  473.  
  474.                  switch( mask & 3 )
  475.                  {
  476.                     case 0:
  477.                        __asm__ __volatile__
  478.                        ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bb));
  479.                        break;
  480.  
  481.                     case 1:
  482.                        __asm__ __volatile__
  483.                        ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_fb));
  484.                        break;
  485.  
  486.                     case 2:
  487.                        __asm__ __volatile__
  488.                        ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bf));
  489.                        break;
  490.  
  491.                     case 3:
  492.                        __asm__ __volatile__
  493.                        ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_ff));
  494.                        break;
  495.                  }
  496.                  width   -=2;
  497.                  tmp_dst +=8;
  498.               }
  499.               if( width )
  500.                  if( mask & 1 )
  501.                     __asm__ __volatile__
  502.                     ("movd %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_ff));
  503.                  else
  504.                     __asm__ __volatile__
  505.                     ("movd %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bb));
  506.            };
  507.  
  508.            if( (border & 0xFF000000) != 0)
  509.            {
  510.               if( y0 == yorg)
  511.               {
  512.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  513.                  HLine(dst_addr, w, border);
  514.                  y0++;
  515.                  bh--;
  516.               }
  517.               if( y1 == yend )
  518.               {
  519.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y1 + x0*4];
  520.                  HLine(dst_addr, w, border);
  521.                  bh--;
  522.               }
  523.               if( (bh > 0) && (x0 == xorg))
  524.               {
  525.                  int dy = bh;
  526.  
  527.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4];
  528.  
  529.                  while ( dy-- )
  530.                  {
  531.                     *(color_t*)dst_addr = border;
  532.                     dst_addr += pixmap->pitch;
  533.                  }
  534.               }
  535.               if( (bh > 0) && (x1 == xend))
  536.               {
  537.                  int dy = bh;
  538.  
  539.                  dst_addr  = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x1*4];
  540.  
  541.                  while ( dy-- )
  542.                  {
  543.                     *(color_t*)dst_addr = border;
  544.                     dst_addr += pixmap->pitch;
  545.                  }
  546.               }
  547.            };
  548.  
  549.            _mm_empty();
  550.         };
  551.      };
  552.      return ERR_OK;
  553. };
  554.  
  555.  
  556. int Blit(pixmap_t *dst_pixmap, int dst_x, int dst_y,
  557.          pixmap_t *src_pixmap, int src_x, int src_y,
  558.          int width, int height)
  559. {
  560.  
  561.     clip_t src_clip, dst_clip;
  562.  
  563.     if( ( width <= 0 ) || ( height<=0 ) )
  564.         return ERR_PARAM;
  565.  
  566. /*  if "hardware acceleration present" and
  567.     "destinastion is primary screen or local videomemory"
  568. */
  569.     if( (srv_hw2d != 0) &&
  570.         ( (dst_pixmap == (void*)-1) ||
  571.            ( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) /* &&
  572.          ( (src_pixmap == (void*)-1) ||
  573.            ( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) */ )
  574.     {
  575.         ioctl_t io;
  576.         pxblit_t *blit = (pxblit_t*)&dst_pixmap;
  577.  
  578.         if((int)dst_pixmap != -1)
  579.             blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle;
  580.  
  581.         if( (int)src_pixmap != -1 &&
  582.             (src_pixmap->flags & PX_MEM_MASK) != PX_MEM_SYSTEM)
  583.             blit->src_pixmap = (pixmap_t*)src_pixmap->handle;
  584.  
  585.         io.handle   = srv_hw2d;
  586.         io.io_code  = PX_BLIT;
  587.         io.input    = blit;
  588.         io.inp_size = 8;
  589.         io.output   = NULL;
  590.         io.out_size = 0;
  591.  
  592.         return call_service(&io);
  593.     }
  594.  
  595.     dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ;
  596.     src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ;
  597.  
  598.     src_clip.xmin = 0;
  599.     src_clip.ymin = 0;
  600.     src_clip.xmax = src_pixmap->width-1;
  601.     src_clip.ymax = src_pixmap->height-1;
  602.  
  603.     dst_clip.xmin = 0;
  604.     dst_clip.ymin = 0;
  605.     dst_clip.xmax = dst_pixmap->width-1;
  606.     dst_clip.ymax = dst_pixmap->height-1;
  607.  
  608.     if( !blit_clip(&dst_clip, &dst_x, &dst_y,
  609.                    &src_clip, &src_x, &src_y,
  610.                    &width, &height) )
  611.     {
  612.         color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x];
  613.         color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x];
  614.  
  615.         while( height-- )
  616.         {
  617.             int w = width;
  618.             color_t *tmp_src = src_addr;
  619.             color_t *tmp_dst = dst_addr;
  620.  
  621.             src_addr += src_pixmap->pitch/4;
  622.             dst_addr += dst_pixmap->pitch/4;
  623.  
  624.             while( w >= 8)
  625.             {
  626.                 __asm__ __volatile__ (
  627.                 "movq     (%0),   %%mm0\n"
  628.                 "movq    8(%0),   %%mm1\n"
  629.                 "movq   16(%0),   %%mm2\n"
  630.                 "movq   24(%0),   %%mm3\n"
  631.                 "movq   %%mm0,    (%1)\n"
  632.                 "movq   %%mm1,   8(%1)\n"
  633.                 "movq   %%mm2,  16(%1)\n"
  634.                 "movq   %%mm3,  24(%1)\n"
  635.                 :: "r" (tmp_src), "r" (tmp_dst)
  636.                 : "memory", "%mm0", "%mm1", "%mm2", "%mm3");
  637.                 w -= 8;
  638.                 tmp_src += 8;
  639.                 tmp_dst += 8;
  640.             };
  641.             if( w >= 4 )
  642.             {
  643.                 __asm__ __volatile__ (
  644.                 "movq     (%0),   %%mm0\n"
  645.                 "movq    8(%0),   %%mm1\n"
  646.                 "movq   %%mm0,    (%1)\n"
  647.                 "movq   %%mm1,   8(%1)\n"
  648.                 :: "r" (tmp_src), "r" (tmp_dst)
  649.                 : "memory", "%mm0", "%mm1");
  650.                 w -= 4;
  651.                 tmp_src += 4;
  652.                 tmp_dst += 4;
  653.             };
  654.             if( w >= 2 )
  655.             {
  656.                 __asm__ __volatile__ (
  657.                 "movq     (%0),   %%mm0\n"
  658.                 "movq   %%mm0,    (%1)\n"
  659.                 :: "r" (tmp_src), "r" (tmp_dst)
  660.                 : "memory", "%mm0");
  661.                 w -= 2;
  662.                 tmp_src += 2;
  663.                 tmp_dst += 2;
  664.             };
  665.             if( w )
  666.                 *tmp_dst = *tmp_src;
  667.         };
  668.     };
  669.     return ERR_OK;
  670. };
  671.  
  672. int TransparentBlit(pixmap_t *dst_pixmap, int dst_x, int dst_y,
  673.          pixmap_t *src_pixmap, int src_x, int src_y,
  674.          int width, int height, color_t key)
  675. {
  676.      clip_t src_clip, dst_clip;
  677.  
  678. /*   if "hardware acceleration present" and
  679.      "destinastion is primary screen or local videomemory"  and
  680.      "source is primary screen or local videomemory"
  681. */
  682.  
  683.      if( (srv_hw2d != 0) &&
  684.          ( (dst_pixmap == (void*)-1) ||
  685.            ( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) )  &&
  686.          ( (src_pixmap == (void*)-1) ||
  687.            ( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) )
  688.      {
  689.         ioctl_t io;
  690.         pxblit_t *blit = (pxblit_t*)&dst_pixmap;
  691.  
  692.         if((int)dst_pixmap != -1)
  693.            blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle;
  694.  
  695.         if((int)src_pixmap != -1)
  696.            blit->src_pixmap = (pixmap_t*)src_pixmap->handle;
  697.  
  698.         io.handle   = srv_hw2d;
  699.         io.io_code  = PX_BLIT_TRANSPARENT;
  700.         io.input    = blit;
  701.         io.inp_size = 9;
  702.         io.output   = NULL;
  703.         io.out_size = 0;
  704.  
  705.         return call_service(&io);
  706.      };
  707.  
  708.      dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ;
  709.      src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ;
  710.  
  711.      src_clip.xmin = 0;
  712.      src_clip.ymin = 0;
  713.      src_clip.xmax = src_pixmap->width-1;
  714.      src_clip.ymax = src_pixmap->height-1;
  715.  
  716.      dst_clip.xmin = 0;
  717.      dst_clip.ymin = 0;
  718.      dst_clip.xmax = dst_pixmap->width-1;
  719.      dst_clip.ymax = dst_pixmap->height-1;
  720.  
  721.  
  722.      if( !blit_clip(&dst_clip, &dst_x, &dst_y,
  723.                     &src_clip, &src_x, &src_y,
  724.                     &width, &height) )
  725.      {
  726.         __m64 clr_key;
  727.  
  728.  
  729.         color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x];
  730.         color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x];
  731.  
  732.         clr_key = _mm_cvtsi32_si64(key);
  733.         clr_key = _mm_unpacklo_pi32(clr_key, clr_key);
  734.  
  735.         while( height-- )
  736.         {
  737.            int w = width;
  738.            color_t *tmp_src = src_addr;
  739.            color_t *tmp_dst = dst_addr;
  740.  
  741.            src_addr += src_pixmap->pitch/4;
  742.            dst_addr += dst_pixmap->pitch/4;
  743.  
  744.            while( w >= 2)
  745.            {
  746.               __asm__ __volatile__ (
  747.               "movq    %[clr_key], %%mm0      \n\t"
  748.               "pcmpeqd %[src_clr], %%mm0      \n\t"
  749.               "pand    %%mm0,      %[dst_clr] \n\t"
  750.               "pandn   %[src_clr], %%mm0      \n\t"
  751.               "por     %%mm0,      %[dst_clr] \n\t"
  752.               "movq    %[dst_clr], (%0)"
  753.               :: "r" (tmp_dst),
  754.               [src_clr] "y" (*(__m64*)tmp_src),
  755.               [dst_clr] "y" (*(__m64*)tmp_dst),
  756.               [clr_key] "y" (clr_key)
  757.               :"memory","mm0");
  758.  
  759.               w -= 2;
  760.               tmp_src += 2;
  761.               tmp_dst += 2;
  762.            };
  763.            if( w && (*tmp_src != key) )
  764.               *tmp_dst = *tmp_src;
  765.         };
  766.      };
  767.      return ERR_OK;
  768. }
  769.  
  770. unsigned long long m_0080 = 0x0080008000800080ULL;
  771.  
  772. int BlitAlpha(pixmap_t *dst_pixmap, int dst_x, int dst_y,
  773.               pixmap_t *src_pixmap, int src_x, int src_y,
  774.               int width, int height, u32_t alpha)
  775. {
  776.      clip_t src_clip, dst_clip;
  777.  
  778.      if( (srv_hw2d != 0) &&
  779.          ( (dst_pixmap == (void*)-1) ||
  780.            ( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) )  &&
  781.          ( (src_pixmap == (void*)-1) ||
  782.            ( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) )
  783.      {
  784.         ioctl_t io;
  785.         pxblit_t *blit = (pxblit_t*)&dst_pixmap;
  786.  
  787.         if((int)dst_pixmap != -1)
  788.            blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle;
  789.  
  790.         if((int)src_pixmap != -1)
  791.            blit->src_pixmap = (pixmap_t*)src_pixmap->handle;
  792.  
  793.         io.handle   = srv_hw2d;
  794.         io.io_code  = PX_BLIT_ALPHA;
  795.         io.input    = blit;
  796.         io.inp_size = 9;
  797.         io.output   = NULL;
  798.         io.out_size = 0;
  799.  
  800.         return call_service(&io);
  801.      };
  802.  
  803.      dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ;
  804.      src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ;
  805.  
  806.      src_clip.xmin = 0;
  807.      src_clip.ymin = 0;
  808.      src_clip.xmax = src_pixmap->width-1;
  809.      src_clip.ymax = src_pixmap->height-1;
  810.  
  811.      dst_clip.xmin = 0;
  812.      dst_clip.ymin = 0;
  813.      dst_clip.xmax = dst_pixmap->width-1;
  814.      dst_clip.ymax = dst_pixmap->height-1;
  815.  
  816.  
  817.      if( !blit_clip(&dst_clip, &dst_x, &dst_y,
  818.                     &src_clip, &src_x, &src_y,
  819.                     &width, &height) )
  820.      {
  821.         __m64 m_alpha;
  822.         __m64 m_one_alpha;
  823.  
  824.         color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x];
  825.         color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x];
  826.  
  827.         m_alpha = _mm_cvtsi32_si64((alpha << 16) | alpha);
  828.         m_alpha = _mm_unpacklo_pi32(m_alpha, m_alpha);
  829.         m_one_alpha = _mm_subs_pu16((__m64)0x00FF00FF00FF00FFULL, m_alpha);
  830.  
  831.         while( height-- )
  832.         {
  833.            int w = width;
  834.            color_t *tmp_src = src_addr;
  835.            color_t *tmp_dst = dst_addr;
  836.  
  837.            src_addr += src_pixmap->pitch/4;
  838.            dst_addr += dst_pixmap->pitch/4;
  839.  
  840.            while( w-- )
  841.            {
  842.               __asm__ __volatile__ (
  843.               "movd (%0), %%mm0               \n\t"
  844.               "pxor    %%mm1, %%mm1           \n\t"
  845.               "punpcklbw  %%mm1, %%mm0        \n\t"
  846.               "pmullw  %[clr_key], %%mm0       \n\t"
  847.        //       "paddw   %[m_0080], %%mm0       \n\t"
  848.  
  849.               "movd (%1), %%mm2               \n\t"
  850.               "punpcklbw  %%mm1, %%mm2        \n\t"
  851.               "pmullw  %[m_one_alpha], %%mm2  \n\t"
  852.        //       "paddw   %[m_0080], %%mm2       \n\t"
  853.  
  854.               "paddw   %%mm2, %%mm0           \n\t"
  855.               "psrlw   $8, %%mm0              \n\t"
  856.               "packuswb %%mm0, %%mm0          \n\t"
  857.               "movd    %%mm0, (%1)"
  858.               :: "r" (tmp_src),
  859.                  "r" (tmp_dst),
  860.               [clr_key] "y" (m_alpha),
  861.               [m_one_alpha] "y" (m_one_alpha)
  862.               :"memory","mm0", "mm1", "mm2");
  863.  
  864.               tmp_src++;
  865.               tmp_dst++;
  866.            };
  867. //           if( w && (*tmp_src != alpha) )
  868. //              *tmp_dst = *tmp_src;
  869.         };
  870.      };
  871.      return ERR_OK;
  872. }
  873.