|
不是游戏项目,src,dest都是内存里的一块DIB data段。
在我赛扬 EMT64的CPU上(3G MHZ),混合800*600的位图需要时间0.0027 (s),大概370FPS的样子。还是不够快,我希望能达到600-700FPS.
代码如下~~
static unsigned char mask0R0B[]={0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00};
static unsigned char maskA0G0[]={0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};
// 将一个双字扩展为int64
// dest为目标mmx寄存器
// temp为临时mmx寄存器
// opn为一个字,扩展后为 00 val 00 val 00 val 00 val
#define MMX_WORD2Q(dest, temp, val) {_asm movd dest, val} {_asm movq temp, dest} {_asm psllq temp, 16} {_asm por dest, temp} {_asm movq temp, dest} {_asm psllq dest, 32} {_asm por dest, temp}
void MMXMixProvider: oXRGB32Alpha(Bitmap& dest,long destX,long destY,
const Bitmap& src,long srcTop,long srcLeft,long srcWidth,long srcHigh,
unsigned char alphaValue)
{
long destStartX, destStartY;
long srcStartX,srcStartY;
long rowLen, lines;
GetRealRect(dest,destX,destY,
src,srcTop,srcLeft,srcWidth,srcHigh,
destStartX,destStartY,
srcStartX,srcStartY,
rowLen,lines);
if(lines < 1)
return;
const unsigned char* pSrcBuffer = src.GetConstStartPos(srcStartX,srcStartY);
unsigned char* pDestBuffer = dest.GetStartPos(destStartX,destStartY);
long srcScanLine = src.GetScanLineSize();
srcScanLine = srcScanLine - rowLen * 4 ;
long destScanLine = dest.GetScanLineSize();
destScanLine = destScanLine - rowLen * 4 ;
//以上的代码都是作裁减用的
unsigned int trueAlpha = alphaValue;
unsigned int beta = 0xff - alphaValue;
//初始化一些常用数值
MMX_WORD2Q(mm4, mm7,trueAlpha);
MMX_WORD2Q(mm5,mm7,beta);
__asm
{
movq mm6, mask0R0B
movq mm7, maskA0G0
}
int step = rowLen / 2;
__asm
{
mov eax,lines
mov esi, pSrcBuffer
mov edi, pDestBuffer
mov ebx, step
FIRST:
mov ecx, ebx
BEGIN:
;//下列代码努力的进行了指令配对
movq mm0, [esi]
movq mm1, mm0
pand mm0, mm6
pmullw mm0, mm4
movq mm2, [edi]
movq mm3, mm2
pand mm2, mm6
pmullw mm2, mm5
paddusb mm2, mm0
pand mm1, mm7
psrlq mm1, 8
pmullw mm1, mm4
pand mm3, mm7
psrlq mm3, 8
pmullw mm3, mm5
paddusb mm3, mm1
;//合并mm2,mm3
psrlq mm2, 8
pand mm2, mm6
pand mm3, mm7
por mm2, mm3
movq [edi], mm2
add esi, 8
add edi, 8
loop BEGIN
add esi, srcScanLine
add edi, destScanLine
dec eax
jnz FIRST
emms
}
return;
} |
|