-
-
код: procedure DrawBitmap_transcolor(BTSource,BTDest:TBitmap; _x,_y:integer; transcolor:TColor);
var SrcBits: pointer; DstBits: pointer;
xTo, sx, YTo, ddx, ddy, sy, w, h, dstw, dsth: integer;
inc1, inc2: integer;
Sfscanline0,Dfscanline0,fbits:pointer;
function DIBBits(BMP: TBitmap): Pointer;
var Section:TDIBSECTION;
begin
BMP.HandleType:=bmDIB;
GetObject(BMP.Handle,sizeof(TDIBSECTION),@Section);
Result:=Section.dsBm.bmBits;
end;
begin
w:=BTSource.Width; h:=BTSource.Height;
dstw:=BTDest.Width; dsth:=BTDest.Height;
XTo:=_x+W-1; YTo:=_y+H-1;
if(_y>=dstH)or(_x>=dstW)or(YTo<0)or(XTo<0) then exit;
asm
xor eax, eax
mov ddx, eax
mov ddy, eax
end;
sx:=W;
sy:=H;
if _x<0 then begin
ddx:=-_x;
inc(sx,_x);
_x:=0;
end;
if _y<0 then begin
ddy:=-_y;
inc(sy,_y);
_y:=0;
end;
if XTo>=dstw then dec(sx,XTo-dstw+1);
if YTo>=dsth then dec(sy,YTo-dsth+1);
if (sx<=0)or(sy<=0) then exit;
inc2:=-(((32*w+31) shr 3) and $FFFFFFFC);
Sfscanline0:=pointer(integer(DIBBits(BTSource))+abs(inc2)*(h-1));
SrcBits:=pointer(integer(Sfscanline0)+inc2*ddy+ddx*4);
inc1:=-(((32*dstw+31) shr 3) and $FFFFFFFC);
Dfscanline0:=pointer(integer(DIBBits(BTDest))+abs(inc1)*(dsth-1));
DstBits:=pointer(integer(Dfscanline0)+inc1*_y+_x*4);
asm
push ebx
push edi
push esi
mov ebx, TransColor
and ebx, $FFFFFF
@outer_loop:
mov edi, DstBits
mov ecx, sx
mov esi, SrcBits
@loop:
mov eax, [esi]
mov edx, [esi]
and eax, $FFFFFF
add esi, 4
cmp eax, ebx
jz @next
mov [edi], edx
@next:
add edi, 4
dec ecx
jnz @loop
@end:
mov ecx, inc1
mov eax, inc2
add DstBits, ecx
add SrcBits, eax
dec sy
jnz @outer_loop
pop esi
pop edi
pop ebx
end;
end; функция быстрого блитинга, затирает альфаканал.
-
ЗЫ понятно дело, что для операций в цикле вычисление адреса первой строки пикселов можно куда нибудь вынести. Но в циклах гонялись битмапы 1600*1200, основная нагрузка идет в асме.
-
and ebx, $FFFFFF А нужно ли затирание верхнего байта там, где он не используется? Нафик ету строчку :)
mov eax, [esi] mov edx, [esi] Чтобы не "дёргать" память дважды, можно заменить последнюю строчку на mov edx, eax. Правда, прирост производительности при этом мизерный, но етож всётки цикл :)
А вообще занятный алгоритм. Щас вот думаю, как повязать SrcBits и DstBits на EBP и ESP.
-
Можно попробовать CMOV. Но по моему опыту (на другом алгоритме), толку от неё чуть. А если без спец. инструкций - то и asm необязателен, компилятор вполне справляется. Ну будет разница процентов 5, и то не факт, что в пользу "рукописного" варианта.
-
мне на асме проще )
-
Draw alpha with a: 2,8802308673309 Draw alpha: 1,64891236176665 Draw alpha MMX: 1,54101373219222 Draw transparent color: 1,17464649836781 Draw tr. color opacity MMX: 1,5966358852871 Draw rotate alpha: 5,10885266144161
--- Pentium M (1.73 Ghz, 533Mhz FSB, 2MB L2 cache)
-
А если вот так?
push ebx
push edi
push esi
mov ebx, TransColor
and ebx, $FFFFFF
@outer_loop:
mov edi, DstBits
mov ecx, sx
mov esi, SrcBits
@loop:
mov eax, [esi]
mov edx, eax
and eax, $FFFFFF
add esi, 4
xor eax, ebx
jz @next
mov [edi], edx
@next:
add edi, 4
loop @loop
@end:
mov ecx, inc1
mov eax, inc2
add DstBits, ecx
add SrcBits, eax
dec sy
jnz @outer_loop
pop esi
pop edi
pop ebx
Замена на луп дает выйгрыш в 1 байт =). Правда, не проверял, будет работать или нет, но твоя тестилка, модифицированная hiew'ом =), выдает такой результат: Draw alpha with a: 7,32291837279389
Draw alpha: 5,28911366240431
Draw alpha MMX: 1,9601630027934
Draw transparent color: 0,899604913674843
Draw tr. color opacity MMX: 2,22137304124701
Draw rotate alpha: 9,56283062961568 До этого было так: Draw alpha with a: 7,925456581538
Draw alpha: 5,84321204678404
Draw alpha MMX: 2,16867349828345
Draw transparent color: 0,993406174967481
Draw tr. color opacity MMX: 2,45866821997455
Draw rotate alpha: 10,6337005945738
-
> OSokin (15.01.08 18:12) [7]
верни обратно dec ecx и получишь еще медленней :)
-
Тьфу, блин. Перепутал результаты =)
-
кстати) если вставить loop и убрать dec - ошибок нет, все выполняется) вот только блитится ровно половина (слева) битмапа, поэтому очень быстро:)
-
о_О а разве loop @a не равен dec cx / jnz @a ??? А xor вместо cmp дает что-нибудь?
|