flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
revolution 22 Aug 2008, 18:05
LocoDelAssembly wrote: Anyone has a serious speed comparison about this? (On platforms not older than WinXP). LocoDelAssembly wrote: And yes revolution, I already checked your website but lots of .Net pages with not very well made benchmarks and lots of Command&Conquer links in some searches ![]() LocoDelAssembly wrote: I was using IDApro a little but it is somewhat hard to follow and seems that any call using integers parameters is forwarded to the float parameters version (in the case of DrawLineI it does DrawLineI>DrawLine(floats)>DrawLines>DrawPath>RenderPath). |
|||
![]() |
|
LocoDelAssembly 22 Aug 2008, 19:48
Quote:
Using DIBSection over a CompatibleDC? I had a bad experience with that approach, if the bit depth of the DIBSection didn't match that of the current display mode the CPU usage was a constant 100 % without being able to BitBlt one frame per Hz, setting the display bit depth to the one used in the DIBSection throttled down the CPU usage by about 50 % and one frame per Hz was possible, but the minimum CPU usage was using a CompatibleBitmap, having a hard to measure CPU usage. All this on an AMD Athlon 750 MHz with a GeForce FX 5200 and Windows Server 2003. What I've forgot to try was blitting the DIBSection to a DC with a CompatibleBitmap selected first and then from the latter DC to the window DC. I believe that using CompatibleBitmap MUST BE faster in average since the operations should be easy to perform by the driver (and hardware) than a DIB. BTW, I was tracing GdiplusDrawLineI on Olly and I don't know how many times I pressed F7 but after 15 minutes of doing that EIP still don't get back to my executable!! I'm starting to think that GDI+ has from few to none chances at all to be faster than plain GDI (apart of the fact that many functions seems to be built on top of plain GDI). I think I better abandon GDI+ and try to find how to do anti-aliasing on GDI instead... Thanks for answering revolution ![]() [edit]Setting a breakpoint to the list of functions below the debugger never stops. I wonder if this call is REALLY built on top of GDI ![]() CreateDIBitmap, PlgBlt, StretchDIBits, StrokePath, PolyDraw, GetPixel, SetPixelV, SetPixel, GetDIBits, SetDIBits, SelectObject, CreateDIBSection, PatBlt, LineTo, BitBlt. Code: ; Template for program using standard Win32 headers format PE GUI 4.0 entry start include 'win32ax.inc' struct GdiplusStartupInput GdiplusVersion dd ? DebugEventCallback dd ? SuppressBackgroundThread dd ? SuppressExternalCodecs dd ? ends section '.data' data readable writeable _class TCHAR 'FASMWIN32',0 _title TCHAR 'Win32 program template',0 _error TCHAR 'Startup failed.',0 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class msg MSG input GdiplusStartupInput 1 ; GdiplusVersion = 1 token dd ? section '.code' code readable executable start: invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc test eax,eax jz error invoke GdiplusStartup, token, input, NULL test eax, eax jnz error invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,256*3,192*3,NULL,NULL,[wc.hInstance],NULL test eax,eax jz error msg_loop: invoke GetMessage,msg,NULL,0,0 cmp eax,1 jb end_loop jne msg_loop invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop error: invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK end_loop: invoke GdiplusShutdown, [token] invoke ExitProcess,[msg.wParam] proc WindowProc hwnd,wmsg,wparam,lparam local ps:PAINTSTRUCT push ebx esi edi cmp [wmsg],WM_DESTROY je .wmdestroy cmp [wmsg], WM_PAINT je .wmpaint .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmpaint: invoke BeginPaint, [hwnd], addr ps stdcall draw, eax invoke EndPaint, [hwnd], addr ps jmp .finish_ret_0 .wmdestroy: invoke PostQuitMessage,0 .finish_ret_0: xor eax,eax .finish: pop edi esi ebx ret endp proc drawNode x, y, node ret endp proc draw hdc local pGraphics:DWORD, pPen:DWORD invoke GdipCreateFromHDC, [hdc], addr pGraphics invoke GdipCreatePen1, $FF000000, 3.0, 0, addr pPen push ebx mov ebx, 10 invoke GdipSetSmoothingMode, [pGraphics], 2 .loop: invoke GdipDrawLineI, [pGraphics], [pPen], addr 0+ebx*8, addr 100+ebx*8, addr 500+ebx*8, addr 200+ebx*8 dec ebx jns .loop pop ebx invoke GdipDeleteGraphics, [pGraphics] invoke GdipDeletePen, [pPen] ret endp section '.idata' import data readable writeable library gdi, 'GDI.DLL',\ gdiplus, 'GDIPLUS.DLL',\ kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api\gdi32.inc' import gdiplus,\ GdiplusShutdown, 'GdiplusShutdown',\ GdipCreateFromHDC, 'GdipCreateFromHDC',\ GdipCreatePen1, 'GdipCreatePen1',\ GdipDeleteGraphics, 'GdipDeleteGraphics',\ GdipDeletePen, 'GdipDeletePen',\ GdipDrawLineI, 'GdipDrawLineI',\ GdipSetSmoothingMode, 'GdipSetSmoothingMode',\ GdiplusStartup, 'GdiplusStartup' include 'api\kernel32.inc' include 'api\user32.inc' |
|||
![]() |
|
revolution 22 Aug 2008, 20:19
Oh, you absolutely need to match your BMP to the display capabilities. I only made two versions of my code, 16BPP and 24BPP(32BPP). I had no need to support 8BPP so I never implemented it, but such ancient systems would probably not have been usable anyhow so it didn't matter.
|
|||
![]() |
|
LocoDelAssembly 22 Aug 2008, 21:08
Something I forgot to mention, the CPU usage was also much higher when a window was on top of some portion of the window I was painting, however this performance hit was not perceived when using a CompatibleBitmap. In my box, blitting performance was seriously limited compared to compatible bitmaps BUT, I was doing very little work (very few pixels changed between blittings and there was no operation that needed GetPixel/SetPixel), so maybe in a more intensive graphics processing bitmaps compensate the lower blitting performance (not considering the obvious case of low-level operations where GetPixel/SetPixel would be the only high-level operations usable and for sure much more expensive than DIBSections).
|
|||
![]() |
|
bitRAKE 23 Aug 2008, 03:28
AntiGrain (C++) has really high-quality output. (Haven't used the newer Pascal version (AggPas).)
_________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
![]() |
|
LocoDelAssembly 23 Aug 2008, 04:37
Awesome bitRAKE!!! And it works flicker free also even though it uses SetDIBitsToDevice instead of BitBlt of a CompatibleDC with a CompatibleBitmap. Additionally it also has a test that proofs that GDI+ is slower than AntiGrain and it is even bugged.
Thank you very much!! |
|||
![]() |
|
slovach 24 Aug 2008, 08:36
Hi, you will surely find Get/SetPixel to be horrendously slow, I'm also sure that you will find GDI+ to infact be slower than GDI in most cases as well.
![]() As far as I know, the fastest way to draw in GDI is to create a DIB and draw on it by setting the bits. This probably gets the benefit of being accelerated by your graphics hardware on more modern hardware / drivers. Anyway, it's very simple to do actually, but information on it is definitely scarce. (sorry, it's going to be in C, I'm not experienced enough in ASM to convert it myself yet) The first issue for drawing is the bitmap padding. This can be simply worked around by doing something like: Code: (y * SCREEN_WIDTH + x) << 2) From then on, you basically set your pixels by doing this, then blitting it. Code: bits[padding + 2] = red; bits[padding + 1] = green; bits[padding ] = blue; If you need to load pictures, you can also convert your images to byte arrays and go from there, pixel by pixel straight to your DIB. It should be pretty simple to keep the number of BitBlit calls extremely minimal. BitBlt may also be faster than SetDIBitsToDevice. I wrote a simple retro 2d starfield a while back. While it's in C, and might have some possible speed ups from ASM, it's still pretty fast. The drawing is very cheap compared to the actual calculations for the starfield. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.