这里的MMX AlphaBlend的方法与网上流传甚广的MMX混合代码完全不同。
基于同一个公式但是核心代码更少 且作了优化 。
感谢ksni2000修正一处bug。
更新日志
2010-8-6:修正优化后的一个Bug
2010-7-24:根据Intel的手册进行了下MMX代码优化 减少核心时间
2010-6-22:修正Bug
32bit AlphaBlend [2010-7-24 Updated]
{$asmmode intel}
uses
sysutils;
var
src,dst:dword;
s1,s2,s3,s4:qword;
procedure
s;
begin
writeln
(IntToHex(s1,
16
),
' '
,IntToHex(s2,
16
),
' '
,IntToHex(s3,
16
),
' '
,IntToHex(s4,
16
));
end
;
begin
src:=
$80AAAAAA
;
dst:=
$10203040
;
asm
//Initialize
mov eax,
$FF000000
//Alpha mask
mov ebx,
$FFFFFFFF
//255-Alpha mask
pxor mm7,mm7
movd mm5,eax
movd mm6,ebx
punpcklbw mm5,mm7
//mm5=alpha mask
punpcklbw mm6,mm7
//mm6=(255-alpha) mask
//Alpha Blend:
movd mm0,src
//mm0=packed src
punpcklbw mm0,mm7
//mm0=unpacked src
movq mm2,mm0
//mm2=unpacked src
punpckhwd mm0,mm0
movd mm3,dst
//mm3=packed dst
punpckhdq mm0,mm0
//mm0=unpacked src alpha bit
movq mm1,mm6
punpcklbw mm3,mm7
//mm3=dst
psubb mm1,mm0
//mm1=255-src alpha bit
paddusb mm0,mm5
//mm0=current unpacked src alpha bit
pmullw mm2,mm0
//mm2=src*srcAlpha
pmullw mm3,mm1
//mm3=dst*(255-srcAlpha)
paddusw mm3,mm2
//mm3=src*srcAlpha+dst*(255-srcAlpha)
psrlw mm3,
8
//mm3=src*srcAlpha/256+dst*(255-srcAlpha)/256
packuswb mm3,mm7
//mm3=packed dst
movd dst,mm3
//finally
emms
end
;
writeln
(IntToHex(dst,
8
));
end
.