|

楼主 |
发表于 2012-9-26 17:00:09
|
显示全部楼层
WY的代码,有一段MMX的alphablend
-     __asm
-     {
-         mov            edi, pDstBmp        ; 目的像素
-         mov            esi, pSrcBmp        ; 源像素
-         xor            ebx, ebx            ; 已混合的高度
-         mov            ecx, blend_width    ; 要混合的宽度                                 <-------------------------------ecx记录一行的长度
- BLEND_BEGIN:
-         cmp            dword ptr[esi], 0x00FFFFFF    ; 如果alpha为0,则跳过混合部分
-         jna            BLEND_END
-         movd        mm0, [edi]            ; 把目的像素值移入mm0寄存器的低32位
-         movd        mm1, [esi]            ; 把源像素值移入mm1寄存器的低32位
-         ; Core Begin
-         pxor        mm2, mm2            ; 把MM2清0
-         punpcklbw    mm0, mm2            ; src:8 bit到16 bit以容纳结果,32bit expand to 64 bit
-         punpcklbw    mm1, mm2            ; dst:8 bit到16 bit以容纳结果.32bit expand to 64 bit
-         movq        mm3, mm1            ; 因为要用dst的Alpha值
-         punpckhwd    mm3, mm3            ; 高字移动到双字
-         punpckhdq    mm3, mm3            ; 双字移动到四字,现在有八个像素的Alpha了!
-         movq        mm4, mm0            ; mm4 = dst
-         movq        mm5, mm1            ; mm5 = src
-         psubusw        mm4, mm1            ; dst-src,饱和减,小于0为0
-         psubusw        mm5, mm0            ; src-dst,饱和减,小于0为0
-         pmullw        mm4, mm3            ; Alpha * (src-dst)
-         pmullw        mm5, mm3            ; Alpha * (dst-src)
-         psrlw        mm4, 8                ; 除以256,now mm4 get the result,(src-dst)<0 部分
-         psrlw        mm5, 8                ; 除以256,now mm5 get the result,(dst-src)>0 部分
-         paddusw        mm0, mm5            ; 饱和加到原图象:D=Alpha*(O-S)+S,(src-dst)<0 部分
-         psubusw        mm0, mm4            ; 饱和加到原图象D=S-Alpha*(S-O),(dst-src)>0 部分
-         packuswb    mm0, mm0            ; 紧缩到低32bit
-         ; Core End
-         movd        [edi], mm0            ; 混合结果写进目的像素
- BLEND_END:
-         add            edi, 4
-         add            esi, 4
-         loop        BLEND_BEGIN                ; 循环                                          <--------------------------------------------跳回去循环,前面没有ecx 的cmp,jxx为啥没有死循环哇??
-         add            esi, nextLineOffset_src    ; 加上偏移量,使定位到下行起始处
-         add            edi, nextLineOffset_dst
-         inc            ebx
-         mov            ecx, blend_width
-         cmp            ebx, blend_height        ; 若ebx小于blend_height,则转移到上面继续混合
-         jb            BLEND_BEGIN
-         EMMS                                ; 因为从mm0到mm7,这些寄存器是“借用”浮点寄存器的低64位,所以每次在用完MMX指令后一定要用EMMS指令将寄存器清空
-     }
复制代码 |
|