?? asl_asm.cpp
字號:
//-----------------------------------------------------------------------------
//
// ____ Azure Star Game Engine 藍星游戲引擎 ____
//
// Copyright (c) 2006, 藍星工作室
// All rights reserved.
//
// 文件名稱: asl_asm.cpp
// 摘 要: MMX加速的圖像處理函數實現(被ASLBitmap, ASLFont類使用)
//
// 當前版本: 1.0
// 作 者: 湯 祺
// 創(chuàng)建日期: 2006-8-7
//
//-----------------------------------------------------------------------------
#include "asl_asm.h"
namespace ASL
{
//-----------------------------------------------------------------------------// 宏名: ALPHABLEND()// 功能: 執(zhí)行4字Alpha混合, 本宏使用所有8個mmx寄存器// 輸入: mm3 - 目的顏色// mm0 - 源顏色// mm7 - 33級alpha值(0~32)// 輸出: mm0 - 結果顏色// 算法: alpha混合公式為: src * alpha + dst * (1 - alpha)// 變形為: (src - dst) * alpha + dst 其中alpha范圍0~1// 對于33級alpha值, 計算前留出5位空白防止溢出, 計算完成后右移5位// 逐行注釋:// movq mm4, mm3 ; g1 mm4 = dst3 dst3 dst1 dst0// movq mm5, mm3 ; b1 mm5 = dst3 dst3 dst1 dst0// movq mm6, mm3 ; r1 mm6 = dst3 dst3 dst1 dst0// psrlw mm3, 5 ; r2 mm3 = dst?: 00000rrrrrgggggg// pand mm4, mask_g ; g2 mm4 = dst?: 00000gggggg00000// pand mm5, mask_b ; b2 mm5 = dst?: 00000000000bbbbb// movq mm1, mm0 ; g3 mm1 = src3 src2 src1 src0// movq mm2, mm0 ; b3 mm2 = src3 src2 src1 src0// psrlw mm0, 5 ; r3 mm0 = src?: 00000rrrrrgggggg// pand mm1, mask_g ; g4 mm1 = src?: 00000gggggg00000// pand mm2, mask_b ; b4 mm2 = src?: 00000000000bbbbb// psubw mm0, mm3 ; r4 mm0 = src? - dst?// psubw mm1, mm4 ; g5 mm1 = src? - dst?// pmullw mm0, mm7 ; r5 mm0 = (src? - dst?) * alpha?// psubw mm2, mm5 ; b5 mm2 = src? - dst?// pmullw mm1, mm7 ; g6 mm1 = (src? - dst?) * alpha?// paddw mm0, mm6 ; r6 mm0 = (src? - dst?) * alpha? + dst?// pmullw mm2, mm7 ; b6 mm2 = (src? - dst?) * alpha?// psrlw mm1, 5 ; g7 mm1右移5位,使alpha值范圍變?yōu)?~1// psrlw mm2, 5 ; b7 mm2右移5位,使alpha值范圍變?yōu)?~1// paddw mm1, mm4 ; g8 mm1 = (src? - dst?) * alpha? + dst?// paddw mm2, mm5 ; b8 mm2 = (src? - dst?) * alpha? + dst?// pand mm0, mask_r ; r7 mm0 = result?: rrrrr00000000000// pand mm1, mask_g ; g9 mm1 = result?: 00000gggggg00000// pand mm2, mask_b ; b9 mm2 = result?: 00000ggggggbbbbb// por mm0, mm1 ; mm0 = result?: rrrrrgggggg00000// por mm0, mm2 ; mm0 = result?: rrrrrggggggbbbbb//-----------------------------------------------------------------------------
#define ALPHABLEND() \
__asm movq mm4, mm3 \ __asm movq mm5, mm3 \ __asm movq mm6, mm3 \ __asm psrlw mm3, 5 \ __asm pand mm4, mask_g \ __asm pand mm5, mask_b \ __asm movq mm1, mm0 \ __asm movq mm2, mm0 \ __asm psrlw mm0, 5 \ __asm pand mm1, mask_g \ __asm pand mm2, mask_b \ __asm psubw mm0, mm3 \ __asm psubw mm1, mm4 \ __asm pmullw mm0, mm7 \ __asm psubw mm2, mm5 \ __asm pmullw mm1, mm7 \ __asm paddw mm0, mm6 \ __asm pmullw mm2, mm7 \ __asm psrlw mm1, 5 \ __asm psrlw mm2, 5 \ __asm paddw mm1, mm4 \ __asm paddw mm2, mm5 \ __asm pand mm0, mask_r \ __asm pand mm1, mask_g \ __asm pand mm2, mask_b \ __asm por mm0, mm1 \ __asm por mm0, mm2
//-----------------------------------------------------------------------------
// 宏名: ADDITIVE()// 功能: 執(zhí)行4字色飽和處理, 本宏使用寄存器: mm0, mm1, mm2, mm3, mm6, mm7// 輸入: mm0 - 源顏色// mm2 - 目的顏色// mm6 - 綠掩碼// mm7 - 紅藍掩碼// 輸出: mm0 - 結果顏色// 算法: // 逐行注釋:
//-----------------------------------------------------------------------------
#define ADDITIVE() \
__asm movq mm1, mm0 \
__asm movq mm3, mm2 \
__asm pand mm0, mm7 \
__asm por mm2, mm6 \
__asm pand mm1, mm6 \
__asm por mm3, mm7 \
__asm paddusb mm0, mm2 \
__asm paddusw mm1, mm3 \
__asm pand mm0, mm1
// 全局常量定義
const __int64 mask_r = 0xF800F800F800F800; // 紅色掩碼
const __int64 mask_g = 0x07E007E007E007E0; // 綠色掩碼
const __int64 mask_b = 0x001F001F001F001F; // 藍色掩碼
//-----------------------------------------------------------------------------
// 函數名: asmDrawPlain()
// 功 能: 普通位圖繪制
// 參 數: [*pSrc] - 源位圖數據
// [*pDst] - 目的位圖數據
// [nWidth] - 待處理寬度
// 返回值: [void] - 無
//-----------------------------------------------------------------------------
void asmDrawPlain(BYTE *pSrc, BYTE *pDst, int nWidth)
{
__asm
{
mov edi, pDst // edi = 目的指針
mov esi, pSrc // esi = 源指針
mov ecx, nWidth // ecx = 寬度
cld
align 4
_nextqword:
sub ecx, 4
jl _residual
movq mm0, [esi] // 從源地址取4象素數據
add esi, 8
movq [edi], mm0 // 直接寫入目的地址
add edi, 8
jmp _nextqword
_residual:
add ecx, 4
jz _done
rep movsw
_done:
emms
}
}
//-----------------------------------------------------------------------------
// 函數名: asmDrawColorkey()
// 功 能: 普通位圖繪制(帶Colorkey處理)
// 參 數: [*pSrc] - 源位圖數據
// [*pDst] - 目的位圖數據
// [nWidth] - 待處理寬度
// [ck64] - 64位顏色鍵
// 返回值: [void] - 無
//-----------------------------------------------------------------------------
void asmDrawColorkey(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 ck64)
{
__asm
{
movq mm7, ck64 // 64位顏色鍵
mov edi, pDst // edi = 目的指針
mov esi, pSrc // esi = 源指針
mov ecx, nWidth // ecx = 寬度
movd edx, mm7 // 取32位顏色鍵, 用于剩余處理
cld
align 4
_nextqword:
sub ecx, 4
jl _residual
movq mm0, [esi] // 從源地址取4象素數據
add esi, 8
movq mm1, mm0 // 源數據給mm1
pcmpeqw mm0, mm7 // mm0為透明掩碼
psubusw mm1, mm0 // 源數據透明點置0
pand mm0, [edi] // 目的數據非透明點置0
por mm0, mm1 // 相與得結果數據
movq [edi], mm0 // 結果送目的地址
add edi, 8
jmp _nextqword
_residual: // 剩余處理
add ecx, 4
jz _done
_draw16:
lodsw // 從源地址取1象素數據
cmp ax, dx // 將其與透明色比較
jz _nextone // 相等則跳過
mov [edi], ax // 不等則寫入目的地址
_nextone:
add edi, 2
dec ecx
jnz _draw16
_done:
emms
}
}
//-----------------------------------------------------------------------------
// 函數名: asmAlphaPlain()
// 功 能: 半透明位圖繪制(實際33級透明度)
// 參 數: [*pSrc] - 源位圖數據
// [*pDst] - 目的位圖數據
// [nWidth] - 待處理寬度
// [alpha] - 透明度 0-256
// 返回值: [void] - 無
//-----------------------------------------------------------------------------
void asmAlphaPlain(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 alpha)
{
__asm
{
mov edi, pDst // edi = 目的指針
mov esi, pSrc // esi = 源指針
mov ecx, nWidth // ecx = 寬度
movq mm7, alpha // 透明度
align 4
_nextqword:
sub ecx, 4
jl _residual
movq mm3, [edi] movq mm0, [esi] } // 調用Alpha混合宏 ALPHABLEND() __asm { add esi, 8 movq [edi], mm0 add edi, 8
jmp _nextqword
_residual:
add ecx, 4
jz _done // ecx=0, 已完成
test ecx, 2
jz _onein // ecx=1, 轉單象素處理
movd mm3, [edi] // ecx!=1, 先拷貝2象素
movd mm0, [esi]
test ecx, 1
jz _startres // ecx=2, 開始剩余處理
mov dx, [edi+4] // ecx=3, 再拷貝一個象素
movd mm6, edx
mov dx, [esi+4]
psllq mm6, 32
por mm3, mm6
movd mm6, edx
psllq mm6, 32
por mm0, mm6
jmp _startres
_onein: // 單象素處理
mov dx, [edi]
movd mm3, edx
mov dx, [esi]
movd mm0, edx
_startres:
}
// 調用Alpha混合宏 ALPHABLEND()
__asm
{
test ecx, 2 jz _onepixel movd [edi], mm0 sub ecx, 2 jz _done psrlq mm0, 32 add edi, 4_onepixel: movd edx, mm0 mov [edi], dx
_done:
emms
}
}
//-----------------------------------------------------------------------------
// 函數名: asmAlphaColorkey()
// 功 能: 半透明位圖繪制(帶Colorkey處理)
// 參 數: [*pSrc] - 源位圖數據
// [*pDst] - 目的位圖數據
// [nWidth] - 待處理寬度
// [alpha] - 透明度 0-256
// [ck64] - 64位顏色鍵
// 返回值: [void] - 無
//-----------------------------------------------------------------------------
void asmAlphaColorkey(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 alpha,
__int64 ck64)
{
__asm
{
mov edi, pDst // edi = 目的指針
mov esi, pSrc // esi = 源指針
mov ecx, nWidth // ecx = 寬度
cld
align 4
_nextqword:
sub ecx, 4
jl _residual
movq mm1, ck64
movd eax, mm1
cmp [esi], eax
jnz _notequal
cmp [esi+4], eax
jnz _notequal
jmp _finishone
_notequal:
movq mm3, [edi] movq mm0, [esi] movq mm7, alpha pcmpeqw mm1, mm0 psubusw mm7, mm1 } // 調用Alpha混合宏 ALPHABLEND() __asm { movq [edi], mm0_finishone: add esi,8
add edi,8
jmp _nextqword
_residual:
add ecx, 4
jz _done // ecx=0, 已完成
test ecx, 2
jz _onein // ecx=1, 轉單象素處理
movd mm3, [edi] // ecx!=1, 先拷貝2象素
movd mm0, [esi]
test ecx, 1
jz _startres // ecx=2, 開始剩余處理
mov dx, [edi+4] // ecx=3, 再拷貝一個象素
movd mm6, edx
mov dx, [esi+4]
psllq mm6, 32
por mm3, mm6
movd mm6, edx
psllq mm6, 32
por mm0, mm6
jmp _startres
_onein: // 單象素處理
mov dx, [edi]
movd mm3, edx
mov dx, [esi]
movd mm0, edx
_startres: movq mm1, ck64 movq mm7, alpha pcmpeqw mm1, mm0 psubusw mm7, mm1 } // 調用Alpha混合宏 ALPHABLEND() __asm { test ecx, 2
jz _oneout // ecx為1,則寫入1個象素數據 movd [edi], mm0 // ecx為2或3,先寫入2個象素 sub ecx, 2 jz _done // ecx為2,則結束 psrlq mm0, 32 // ecx為3,再寫入1個象素 add edi, 4_oneout: movd edx, mm0 mov [edi], dx // 寫入一個象素_done:
emms
}
}
//-----------------------------------------------------------------------------
// 函數名: asmFastPlain()
// 功 能: 快速半透明位圖繪制(50%-50%)
// 參 數: [*pSrc] - 源位圖數據
// [*pDst] - 目的位圖數據
// [nWidth] - 待處理寬度
// 返回值: [void] - 無
//-----------------------------------------------------------------------------
void asmFastPlain(BYTE *pSrc, BYTE *pDst, int nWidth)
{
static const __int64 mask = 0x7BEF7BEF7BEF7BEF;
// 算法: 將顏色值全部右移一位, 再與掩碼做且運算, 則三色分量均除以2
// 源數據和目的數據均做上述操作, 再相加即實現半透明
__asm
{
mov edi, pDst // edi = 目的指針
mov esi, pSrc // esi = 源指針
movq mm7, mask // 64位掩碼
mov ecx, nWidth // ecx = 寬度
movd edx, mm7 // 將32位掩碼給edx, 用于剩余處理
cld
align 4
_nextqword:
sub ecx, 4
jl _residual
movq mm0, [esi] // 取源數據到mm0
movq mm1, [edi] // 取目的數據到mm1
psrlq mm0, 1 // src? = 0rrrrrggggggbbbb
psrlq mm1, 1 // dst? = 0rrrrrggggggbbbb
pand mm0, mm7 // src? = 0rrrr0ggggg0bbbb
pand mm1, mm7 // dst? = 0rrrr0ggggg0bbbb
paddw mm0, mm1 // result? = rrrrrggggggbbbbb
add esi, 8
movq [edi], mm0 // 寫回目的地址
add edi, 8
jmp _nextqword
_residual: // 剩余處理
add ecx, 4
jz _done
_alpha16:
lodsw
mov bx, [edi];
shr bx, 1;
shr ax, 1;
and bx, dx;
and ax, dx;
add ax, bx;
stosw
dec ecx
jnz _alpha16
_done:
emms
}
}
//-----------------------------------------------------------------------------
// 函數名: asmFastColorkey()
// 功 能: 快速半透明位圖繪制(帶Colorkey處理)
// 參 數: [*pSrc] - 源位圖數據
// [*pDst] - 目的位圖數據
// [nWidth] - 待處理寬度
// [ck64] - 64位顏色鍵
// 返回值: [void] - 無
//-----------------------------------------------------------------------------
void asmFastColorkey(BYTE *pSrc, BYTE *pDst, int nWidth, __int64 ck64)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -