Форум: "Media";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];
ВнизБыстрое копирование битмапов Найти похожие ветки
← →
antonn © (2008-01-12 18:04) [0]Пересечение веток:
http://delphimaster.net/view/8-1192964708/
http://delphimaster.net/view/8-1192964708/
и теста http://delphimaster.net/view/8-1192964708/
Собсно, есть код блитинга битмапов (TBitmap, 32bit), который почему то медленно выполняется на АМД (медленно относительно оппонентов от Интел, я понимаю, что может там мега процы начали делать, но не настолько же круто). Помогите дооптимизировать его :)
← →
antonn © (2008-01-12 18:05) [1]код:
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;
функция быстрого блитинга, затирает альфаканал.
← →
antonn © (2008-01-12 18:07) [2]ЗЫ понятно дело, что для операций в цикле вычисление адреса первой строки пикселов можно куда нибудь вынести. Но в циклах гонялись битмапы 1600*1200, основная нагрузка идет в асме.
← →
Dib@zol © (2008-01-13 18:45) [3]and ebx, $FFFFFF
А нужно ли затирание верхнего байта там, где он не используется? Нафик ету строчку :)
mov eax, [esi]
mov edx, [esi]
Чтобы не "дёргать" память дважды, можно заменить последнюю строчку на mov edx, eax. Правда, прирост производительности при этом мизерный, но етож всётки цикл :)
А вообще занятный алгоритм. Щас вот думаю, как повязать SrcBits и DstBits на EBP и ESP.
← →
Sapersky (2008-01-13 19:55) [4]Можно попробовать CMOV. Но по моему опыту (на другом алгоритме), толку от неё чуть.
А если без спец. инструкций - то и asm необязателен, компилятор вполне справляется. Ну будет разница процентов 5, и то не факт, что в пользу "рукописного" варианта.
← →
antonn [work) (2008-01-13 21:53) [5]мне на асме проще )
← →
Kenny (2008-01-13 22:36) [6]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)
← →
OSokin (2008-01-15 18:12) [7]А если вот так?
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
← →
antonn © (2008-01-15 18:28) [8]
> OSokin (15.01.08 18:12) [7]
верни обратноdec ecx
и получишь еще медленней :)
← →
OSokin (2008-01-15 18:32) [9]Тьфу, блин. Перепутал результаты =)
← →
antonn © (2008-01-15 18:34) [10]кстати) если вставить loop и убрать dec - ошибок нет, все выполняется) вот только блитится ровно половина (слева) битмапа, поэтому очень быстро:)
← →
OSokin (2008-01-15 20:04) [11]о_О а разве loop @a не равен dec cx / jnz @a ???
А xor вместо cmp дает что-нибудь?
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.006 c