CSK.Blog--个人原创Weblog

« 写了个Tiger语言的IDE状态汇报 »

MMX指令优化的32bit AlphaBlend

前一段时间再进行一个目前保密的项目:Prototype A (哈哈,知道的人不要说阿)

其中需要较高的运行效率,所以就写了一个将32bit位图渲染到目标32bit位图的AlphaBlend。支持Alpha通道。

代码指令参照了http://dev.gameres.com/Program/Visual/2D/mmxaddalpha.htm提供的代码,在此表示感谢。由于第一次写汇编优化。所以不知道这样写是不是最高效的。

如果对位深没有要求,可以采用intel提供的16bit的alphablend,网上很多了,这个号称是目前最快的.

参数:

pDest:目标渲染buffer,32bit的,通道情况:ARGB

wlined:pDest的扫描线宽(即横向的像素个数,即实际宽度/4)

hlined:pDest的扫描线行数,可以理解成实际高度

startX:pDest的开始坐标X

startY:pDest的开始坐标Y,采用倒置坐标系

pSrc:要渲染得图片,通道情况:ARGB

wlines,hlines和前面类似

Alpha:对pSrc做得整体alphaBlend,0-255级

返回:

如果图片得到渲染,返回TRUE

用在Prototype A中效果还好,采用GDI渲染一个100*100的图片可以有1000fps*

代码:

BOOL AlphaBlt(BYTE *pDest,DWORD wlined,DWORD hlined,int startX,int startY,BYTE *pSrc,DWORD wlines,DWORD hlines,DWORD Alpha)
{
int Xd,Yd,Xs=0,Ys=0;
int loopH,loopW;
if (startX>=(int)wlined) return FALSE;
if (startY>=(int)hlined) return FALSE;

if (startX + (int)wlines <=0) return FALSE;
if (startY + (int)hlines <=0) return FALSE;

Xd = startX;
Yd = startY;
loopW = (startX + wlines);
loopH = (startY + hlines);
if (loopH>hlined) loopH = hlined;
if (loopW>wlined) loopW = wlined;
if (startX<0)
{
Xd = 0;
Xs = -startX;
}
if (startY<0)
{
Yd = 0;
Ys = -startY;
}

DWORD factorA = hlines-Ys+Yd-1;
for (DWORD j= Yd ; j< loopH ; j++)
{
DWORD dwOffSrc,dwOffDest;
dwOffSrc = (factorA-j)*wlines;

dwOffDest = (hlined-j-1)*wlined;
DWORD srcPosX = Xs;
for (DWORD i = Xd ; i< loopW ; i++)
{

BYTE *BufSrc = pSrc + (dwOffSrc + srcPosX)*4;
DWORD dwSrc =((DWORD)BufSrc[3] << 24) |((DWORD)BufSrc[2] << 16) | ((WORD)BufSrc[1] << 8) | (BufSrc[0]);
DWORD *dwpDest = (DWORD *)pDest + dwOffDest + i;
__asm{
pxor mm2,mm2

mov edx,dwpDest
movd mm0,[edx]
movd mm1,dwSrc
punpcklbw mm0,mm2
punpcklbw mm1,mm2

movq mm3,mm1
punpckhwd mm3,mm3
punpckhdq mm3,mm3

movd mm4,Alpha

punpcklwd mm4,mm4

punpckldq mm4,mm4

pmullw mm3,mm4 //Alpha * SrcAlpha
psrlw mm3,8

movq mm4,mm0

movq mm5,mm1

psubusw mm4,mm1

psubusw mm5,mm0

pmullw mm4,mm3

pmullw mm5,mm3

psrlw mm4,8

psrlw mm5,8

paddusw mm0,mm5

psubusw mm0,mm4

packuswb mm0,mm0


movd [edx],mm0 //保存结果

emms

}


srcPosX++;
}
}
return TRUE;
}

发表评论:

注意:为了有效防止SPAM,任何含有http://字样的消息会被阻止发布同时,本站仅供技术交流,请不要讨论任何政治敏感话题或者低级趣味问题。

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Copyright Shikai Chen 2000-2012. Powered By Z-Blog(CSK Modified)