00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #include "mmsgui/fb/mmsfbconv.h"
00034 
00035 #ifdef __HAVE_PF_ARGB4444__
00036 
00037 #include "mmstools/mmstools.h"
00038 
00039 void mmsfb_fillrectangle_blend_argb4444(MMSFBSurfacePlanes *dst_planes, int dst_height,
00040                                         int dx, int dy, int dw, int dh, MMSFBColor color) {
00041     
00042     static bool firsttime = true;
00043     if (firsttime) {
00044         printf("DISKO: Using accelerated blend rectangle to ARGB4444.\n");
00045         firsttime = false;
00046     }
00047 
00048     
00049     if (!color.a)
00050         return;
00051 
00052     
00053     unsigned short int *dst = (unsigned short int *)dst_planes->ptr;
00054     int dst_pitch = dst_planes->pitch;
00055 
00056     
00057     int dst_pitch_pix = dst_pitch >> 1;
00058     dst+= dx + dy * dst_pitch_pix;
00059 
00060     unsigned short int OLDDST = (*dst) + 1;
00061     unsigned short int *dst_end = dst + dst_pitch_pix * dh;
00062     int dst_pitch_diff = dst_pitch_pix - dw;
00063     register unsigned short int d;
00064 
00065     
00066     register unsigned short int A = color.a;
00067     register unsigned short int SRC;
00068     SRC =     ((A >> 4) << 12)
00069             | ((color.r >> 4) << 8)
00070             | ((color.g >> 4) << 4)
00071             |  (color.b >> 4);
00072 
00073     if (color.a == 0xff) {
00074         
00075         
00076         while (dst < dst_end) {
00077             
00078 #ifdef __HAVE_SSE__
00079             
00080 
00081             short d0, d1, d2;
00082             __asm__ __volatile__ ( "\tcld\n\trep stosw" \
00083                     : "=&D" (d0), "=&a" (d1), "=&c" (d2) \
00084                     : "0" (dst), "1" (SRC), "2" (dw) \
00085                     : "memory", "cc");
00086 
00087             
00088             dst+= dst_pitch_pix;
00089 #else
00090             unsigned short int *line_end = dst + dw;
00091             while (dst < line_end) {
00092                 *dst = SRC;
00093                 dst++;
00094             }
00095 
00096             
00097             dst+= dst_pitch_diff;
00098 #endif
00099         }
00100 
00101     }
00102     else {
00103         
00104         
00105         while (dst < dst_end) {
00106             
00107             unsigned short int *line_end = dst + dw;
00108             while (dst < line_end) {
00109                 
00110                 register unsigned short int DST = *dst;
00111                 if (DST==OLDDST) {
00112                     
00113                     *dst = d;
00114                     dst++;
00115                     continue;
00116                 }
00117                 OLDDST = DST;
00118 
00119                 register int SA= 0x100 - A;
00120                 unsigned int a = DST >> 12;
00121                 unsigned int r = DST & 0x0f00;
00122                 unsigned int g = DST & 0x00f0;
00123                 unsigned int b = DST & 0x000f;
00124 
00125                 
00126                 a = (SA * a) >> 4;
00127                 r = (SA * r) >> 12;
00128                 g = (SA * g) >> 8;
00129                 b = (SA * b) >> 4;
00130 
00131                 
00132                 a += A;
00133                 r += (SRC & 0x0f00) >> 4;
00134                 g +=  SRC & 0x00f0;
00135                 b += (SRC & 0x000f) << 4;
00136                 d =   ((a >> 8) ? 0xf000 : ((a >> 4) << 12))
00137                     | ((r >> 8) ? 0x0f00 : ((r >> 4) << 8))
00138                     | ((g >> 8) ? 0xf0   : ((g >> 4) << 4))
00139                     | ((b >> 8) ? 0x0f   :  (b >> 4));
00140                 *dst = d;
00141 
00142                 dst++;
00143             }
00144 
00145             
00146             dst+= dst_pitch_diff;
00147         }
00148     }
00149 }
00150 
00151 #endif