Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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"  and
  568.      "source is primary screen or local videomemory"
  569. */
  570.      if( (srv_hw2d != 0) &&
  571.          ( (dst_pixmap == (void*)-1) ||
  572.            ( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) )  &&
  573.          ( (src_pixmap == (void*)-1) ||
  574.            ( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) )
  575.      {
  576.         ioctl_t io;
  577.         pxblit_t *blit = (pxblit_t*)&dst_pixmap;
  578.  
  579.         if((int)dst_pixmap != -1)
  580.         blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle;
  581.  
  582.         if((int)src_pixmap != -1)
  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.      src_clip.xmin = 0;
  709.      src_clip.ymin = 0;
  710.      src_clip.xmax = src_pixmap->width-1;
  711.      src_clip.ymax = src_pixmap->height-1;
  712.  
  713.      dst_clip.xmin = 0;
  714.      dst_clip.ymin = 0;
  715.      dst_clip.xmax = dst_pixmap->width-1;
  716.      dst_clip.ymax = dst_pixmap->height-1;
  717.  
  718.  
  719.      if( !blit_clip(&dst_clip, &dst_x, &dst_y,
  720.                     &src_clip, &src_x, &src_y,
  721.                     &width, &height) )
  722.      {
  723.         __m64 clr_key;
  724.  
  725.         dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ;
  726.         src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ;
  727.  
  728.         color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x];
  729.         color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x];
  730.  
  731.         clr_key = _mm_cvtsi32_si64(key);
  732.         clr_key = _mm_unpacklo_pi32(clr_key, clr_key);
  733.  
  734.         while( height-- )
  735.         {
  736.            int w = width;
  737.            color_t *tmp_src = src_addr;
  738.            color_t *tmp_dst = dst_addr;
  739.  
  740.            src_addr += src_pixmap->pitch/4;
  741.            dst_addr += dst_pixmap->pitch/4;
  742.  
  743.            while( w >= 2)
  744.            {
  745.               __asm__ __volatile__ (
  746.               "movq    %[clr_key], %%mm0      \n\t"
  747.               "pcmpeqd %[src_clr], %%mm0      \n\t"
  748.               "pand    %%mm0,      %[dst_clr] \n\t"
  749.               "pandn   %[src_clr], %%mm0      \n\t"
  750.               "por     %%mm0,      %[dst_clr] \n\t"
  751.               "movq    %[dst_clr], (%0)"
  752.               :: "r" (tmp_dst),
  753.               [src_clr] "y" (*(__m64*)tmp_src),
  754.               [dst_clr] "y" (*(__m64*)tmp_dst),
  755.               [clr_key] "y" (clr_key)
  756.               :"memory","mm0");
  757.  
  758.               w -= 2;
  759.               tmp_src += 2;
  760.               tmp_dst += 2;
  761.            };
  762.            if( w && (*tmp_src != key) )
  763.               *tmp_dst = *tmp_src;
  764.         };
  765.      };
  766.      return ERR_OK;
  767. }
  768.  
  769.  
  770.