Hi guys,
This is a follow up from a thread at Campus where I've exchange with Zedd my anti aliasing with pure GDI, and he shared the same stuff, but in GDI+. Started here since I am timing things, it's more suitable for the laboratory.
original thread: https://masm32.com/board/index.php?topic=12693.0 (https://masm32.com/board/index.php?topic=12693.0)
I mainly wanted to check for 2 main things:
1. How both anti aliasing perform against each other
2. How FAST they both behave.
Without making any enhancements on my technique, my current conclusion is: pure GDI is faster for small shapes, GDI+ is faster for bigger shapes
So, I've run many tests. GDI+ is more consistent, pure GDI needs tweeking the "upscale" value to equals anti anliasing, and speed
Here is some of my results, with timings and image comparison (GDI+ os on the left, pure GDI on the right)
ps.: I deeply miss the time when we kept running speed tests...
(https://i.postimg.cc/PNYrXdy0/01.png) (https://postimg.cc/PNYrXdy0)
(https://i.postimg.cc/mhshFcPT/02.png) (https://postimg.cc/mhshFcPT)
(https://i.postimg.cc/4nQyvJcV/03.png) (https://postimg.cc/4nQyvJcV)
(https://i.postimg.cc/fJWLB67F/04.png) (https://postimg.cc/fJWLB67F)
(https://i.postimg.cc/fJHbFBBb/05.png) (https://postimg.cc/fJHbFBBb)
(https://i.postimg.cc/xXcdSM43/06.png) (https://postimg.cc/xXcdSM43)
(https://i.postimg.cc/Sn3xQj0F/07.png) (https://postimg.cc/Sn3xQj0F)
source code and .exe in the zip
I'm away from my computer at the moment. When I get back inside, I'll take a look.
Why are the results floating point values? What testing method are you using? I cannot view the source from my iPad. :tongue:
Some of those images (maybe all?) don't look identical in size... could skew the results.
Settings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 63.448700 GDI+: 153.076100
PURE GDI: 61.176500 GDI+: 73.054100
PURE GDI: 60.954300 GDI+: 74.998700
PURE GDI: 57.746300 GDI+: 75.268600
PURE GDI: 57.781100 GDI+: 75.136300
PURE GDI: 51.821600 GDI+: 74.247000
PURE GDI: 53.311100 GDI+: 76.663700
PURE GDI: 51.469200 GDI+: 71.506500
PURE GDI: 62.596000 GDI+: 71.281200
PURE GDI: 54.992700 GDI+: 77.235500
Loop count 100. I wonder why only the left circle flickers :cool:
An old AMD with AMD Radeon R5
Settings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 13.226360 GDI+: 5.684640
PURE GDI: 12.345840 GDI+: 7.344000
PURE GDI: 12.235960 GDI+: 5.652360
PURE GDI: 11.747280 GDI+: 6.490320
PURE GDI: 11.722800 GDI+: 6.553960
PURE GDI: 12.052520 GDI+: 5.652440
PURE GDI: 12.413360 GDI+: 5.631120
PURE GDI: 12.008080 GDI+: 5.545680
PURE GDI: 12.212120 GDI+: 5.727480
PURE GDI: 12.107880 GDI+: 5.591760
Sorry for the delay, Alex...
Settings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 4.015800 GDI+: 9.362000
PURE GDI: 3.822700 GDI+: 9.115100
PURE GDI: 3.491800 GDI+: 10.884700
PURE GDI: 3.527500 GDI+: 11.522300
PURE GDI: 3.627100 GDI+: 10.698900
PURE GDI: 3.514400 GDI+: 12.074400
PURE GDI: 3.671700 GDI+: 10.864500
PURE GDI: 3.479700 GDI+: 8.342200
PURE GDI: 3.848300 GDI+: 8.511500
PURE GDI: 3.347400 GDI+: 10.287700
Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz 3.60 GHz
Seems to be CPU specific which is faster, as is often the case. Maybe print the CPU stats in the results?
Are you running on AMD or Intel?
Quote from: jj2007 on April 15, 2025, 10:11:48 PMI wonder why only the left circle flickers :cool:
Although I do not see the flickering that jj does...
When resizing the window using the window borders, both circles and the white background color disappear - as does minimizing and restoring the window. Seems to be a rather high gdi object count, btw - 221
as seen in Task Manager. :wink2: (https://i.postimg.cc/CLXLrcby/untitled.png)
I wanted to try a few things in the source but...
While trying to rebuild with ml&link...
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: Aliasing_in_GDI.asm
***********
ASCII build
***********
extra_files\AF.inc(80) : error A2163: non-benign structure redefinition: incorrect initializers : POINT
extra_files\AF.inc(81) : error A2163: non-benign structure redefinition: incorrect initializers : POINT
extra_files\multiTimers.asm(83) : error A2070: invalid instruction operands
extra_files\multiTimers.asm(95) : error A2070: invalid instruction operands
Aliasing_in_GDI.asm(95) : error A2006: undefined symbol : upscale
fn(5): Macro Called From
printf(3): Macro Called From
con(3): Macro Called From
Aliasing_in_GDI.asm(95): Main Line Code
Aliasing_in_GDI.asm(95) : error A2114: INVOKE argument type mismatch : argument : 0
fn(5): Macro Called From
printf(3): Macro Called From
con(3): Macro Called From
Aliasing_in_GDI.asm(95): Main Line Code
Aliasing_in_GDI.asm(240) : error A2050: real or BCD number not allowed
Aliasing_in_GDI.asm(240) : error A2114: INVOKE argument type mismatch : argument : 4
Aliasing_in_GDI.asm(240) : error A2114: INVOKE argument type mismatch : argument : 3
Press any key to continue . .
Using uasm (or any other alternatives) is a nonstarter for me, I could live with polink though. Nothing against you or anyone else that uses uasm (or other *asm) just my personal preference not to use it, as it appears that it is not fully compatible with Microsofts Ml.exe.
AMD Ryzen 5 3400G with Radeon Vega Graphics
Settings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 4.930400 GDI+: 7.660700
PURE GDI: 4.295400 GDI+: 10.208600
PURE GDI: 4.119000 GDI+: 7.906300
PURE GDI: 4.521900 GDI+: 14.461100
PURE GDI: 4.770100 GDI+: 14.656700
PURE GDI: 4.113300 GDI+: 13.279400
PURE GDI: 4.352600 GDI+: 12.960300
PURE GDI: 4.358000 GDI+: 12.773100
PURE GDI: 4.889600 GDI+: 10.075000
PURE GDI: 4.309300 GDI+: 12.900800
Intel I7 4810 - Win7
This laptop has two graphics cards but it doesn't seem to make a difference if I force it to use the crappy Intel graphics or the NVidia one.
Settings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 18.162445 GDI+: 8.001578
PURE GDI: 16.100655 GDI+: 8.365186
PURE GDI: 16.356134 GDI+: 6.778799
PURE GDI: 15.276672 GDI+: 7.265198
PURE GDI: 16.488088 GDI+: 6.805190
PURE GDI: 16.465363 GDI+: 7.241373
PURE GDI: 15.735214 GDI+: 7.441504
PURE GDI: 16.431641 GDI+: 6.393198
PURE GDI: 16.451801 GDI+: 5.938322
PURE GDI: 15.387367 GDI+: 6.749842
GDI+ occasionally blips up to 13.xxx but the timings are generally like the ones above
QuoteSeems to be a rather high gdi object count, btw - 221 as seen in Task Manager
I'm sure it doesn't matter any more since everybody's been forgetting to do it for 35 years, but it's probably because all the created pens and things in the code are deleted while still selected into the DC, that's technically not allowed and won't work.
Quote from: jj2007 on April 15, 2025, 10:11:48 PMSettings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 63.448700 GDI+: 153.076100
PURE GDI: 61.176500 GDI+: 73.054100
PURE GDI: 60.954300 GDI+: 74.998700
PURE GDI: 57.746300 GDI+: 75.268600
PURE GDI: 57.781100 GDI+: 75.136300
PURE GDI: 51.821600 GDI+: 74.247000
PURE GDI: 53.311100 GDI+: 76.663700
PURE GDI: 51.469200 GDI+: 71.506500
PURE GDI: 62.596000 GDI+: 71.281200
PURE GDI: 54.992700 GDI+: 77.235500
Loop count 100. I wonder why only the left circle flickers :cool:
Hi Johen,
I am sure you know the answer!
Anyway, Zedd's gdi+ draws to the device, and I had to draw a background to it otherwise the gdi+ circle gets all jagged with repeating the loop.
try commenting line 119:
inv ui_draw_single, dc, 0, BACKGROUND_CLR, BACKGROUND_CLR, 0, 0, 300, 300
Quote from: TimoVJL on April 15, 2025, 10:57:24 PMAn old AMD with AMD Radeon R5
Settings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 13.226360 GDI+: 5.684640
PURE GDI: 12.345840 GDI+: 7.344000
PURE GDI: 12.235960 GDI+: 5.652360
PURE GDI: 11.747280 GDI+: 6.490320
PURE GDI: 11.722800 GDI+: 6.553960
PURE GDI: 12.052520 GDI+: 5.652440
PURE GDI: 12.413360 GDI+: 5.631120
PURE GDI: 12.008080 GDI+: 5.545680
PURE GDI: 12.212120 GDI+: 5.727480
PURE GDI: 12.107880 GDI+: 5.591760
Interesting how bad AMD pure gdi is performing, interesting.
It shows gdi+ in the end is more 'predictable'
Hi Zedd,
QuoteWhen resizing the window using the window borders, both circles and the white background color disappear - as does minimizing and restoring the window. Seems to be a rather high gdi object count, btw - 221
I was soly interested in the timing, didn't bother to refresh the device in these cases.
I left the delete stuff things out of the loop, adeyblue is right in his comment below.
This may add some extra time to gdi+.
I just ran it with no repetition and there are still 20 gdis there
Quote from: adeyblue on April 16, 2025, 02:35:27 AMQuoteSeems to be a rather high gdi object count, btw - 221 as seen in Task Manager
I'm sure it doesn't matter any more since everybody's been forgetting to do it for 35 years, but it's probably because all the created pens and things in the code are deleted while still selected into the DC, that's technically not allowed and won't work.
Yes, you are right. Deletes are out of the loop
Quote ;---------------------- GDI+ LOOP ----------------------------
mov tcount, loop_count
startTimer 1
@@:
inv ui_draw_single, dc, 0, BACKGROUND_CLR, BACKGROUND_CLR, 0, 0, 300, 300
call gdi_plus_circle
sub tcount, 1
cmp tcount, 0
jnz @B
stopTimer 1
con "PURE GDI: %f \tGDI+: %f", timer.routineTime sub results_count, 1
jnz next_run
;*************************************************************************************
invoke GdipDeletePen, hPen
invoke GdipDeleteGraphics, hGraphics
invoke GdiplusShutdown, gdiplusToken
;*************************************************************************************[/font][/color]
I ran the example, with the creation and deletion inside the loop, but it didn't change the number of dgis...still 219 in the task manager
Quote from: zedd151 on April 15, 2025, 11:27:12 PMI wanted to try a few things in the source but...
While trying to rebuild with ml&link...
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: Aliasing_in_GDI.asm
***********
ASCII build
***********
extra_files\AF.inc(80) : error A2163: non-benign structure redefinition: incorrect initializers : POINT
extra_files\AF.inc(81) : error A2163: non-benign structure redefinition: incorrect initializers : POINT
extra_files\multiTimers.asm(83) : error A2070: invalid instruction operands
extra_files\multiTimers.asm(95) : error A2070: invalid instruction operands
Aliasing_in_GDI.asm(95) : error A2006: undefined symbol : upscale
fn(5): Macro Called From
printf(3): Macro Called From
con(3): Macro Called From
Aliasing_in_GDI.asm(95): Main Line Code
Aliasing_in_GDI.asm(95) : error A2114: INVOKE argument type mismatch : argument : 0
fn(5): Macro Called From
printf(3): Macro Called From
con(3): Macro Called From
Aliasing_in_GDI.asm(95): Main Line Code
Aliasing_in_GDI.asm(240) : error A2050: real or BCD number not allowed
Aliasing_in_GDI.asm(240) : error A2114: INVOKE argument type mismatch : argument : 4
Aliasing_in_GDI.asm(240) : error A2114: INVOKE argument type mismatch : argument : 3
Press any key to continue . .
Using uasm (or any other alternatives) is a nonstarter for me, I could live with polink though. Nothing against you or anyone else that uses uasm (or other *asm) just my personal preference not to use it, as it appears that it is not fully compatible with Microsofts Ml.exe.
I'm sure the gurus on the topic will chime in, I am not...being on UASM for a long time, most of what I see looks easy to fix.
In UASM, I never had any issue building the other way around
Quote from: LordAdef on April 16, 2025, 03:16:51 AMHi Zedd,
QuoteWhen resizing the window using the window borders, both circles and the white background color disappear - as does minimizing and restoring the window. Seems to be a rather high gdi object count, btw - 221
I was soly interested in the timing, didn't bother to refresh the device in these cases.
I left the delete stuff things out of the loop, adeyblue is right in his comment below.
This may add some extra time to gdi+.
I just ran it with no repetition and there are still 20 gdis there
Oh okay, it was more or less intentional. (Not worrying about object cleanup for the testing)
20 gdi object seems about right, and nothing to worry about imo for a non looping/repeating run of the code.
Quote from: LordAdef on April 16, 2025, 03:43:42 AMI'm sure the gurus on the topic will chime in, I am not...being on UASM for a long time, most of what I see looks easy to fix.
In UASM, I never had any issue building the other way around
I would have to take a good look at the code and the disassembly of your executable to see what will be an easy fix... commenting out the redefined POINT structure is an easy fix I can see. I had done that while rebuilding the original example of your antialias source... the others will take a bit of time (for me) to make compatible for ml. :smiley:
As long as it works for you (uasm), I am happy. :smiley:
It seems, that just in Windows 7 GDI is slower?
Windows 11, i7-10700, GeForce RTX 3070 Ti
Settings: circle_size:50 thickness:4 pure_gdi upscale factor:5
-----------------------------------------------------------------------
PURE GDI: 3.836800 GDI+: 3.213700
PURE GDI: 2.955800 GDI+: 2.561800
PURE GDI: 2.920600 GDI+: 2.707800
PURE GDI: 2.928900 GDI+: 2.763000
PURE GDI: 3.181700 GDI+: 2.913500
PURE GDI: 2.959300 GDI+: 2.677500
PURE GDI: 2.885200 GDI+: 2.865500
PURE GDI: 2.904300 GDI+: 3.438000
PURE GDI: 2.923400 GDI+: 2.490500
PURE GDI: 2.907100 GDI+: 2.513700
Attached slightly modified files that make it work for both UAsm and ml.exe
Move the af.inc to the extra_files folder.
It is generally a good idea to test include files for both assemblers. UAsm is very compatible, but also a bit more powerful than MASM. Example:
works for both: invoke GdipDrawEllipse, hGraphics, hPen, FP4(50.0), FP4(50.0), PLUS_SIZE, PLUS_SIZE
UAsm only: invoke GdipDrawEllipse, hGraphics, hPen, 50.0, 50.0, PLUS_SIZE, PLUS_SIZE
Quote from: jj2007 on April 16, 2025, 07:42:18 AMAttached slightly modified files that make it work for both UAsm and ml.exe
Move the af.inc to the extra_files folder.
It is generally a good idea to test include files for both assemblers. UAsm is very compatible, but also a bit more powerful than MASM. Example:
works for both: invoke GdipDrawEllipse, hGraphics, hPen, FP4(50.0), FP4(50.0), PLUS_SIZE, PLUS_SIZE
UAsm only: invoke GdipDrawEllipse, hGraphics, hPen, 50.0, 50.0, PLUS_SIZE, PLUS_SIZE
Quote from: jj2007 on April 16, 2025, 07:42:18 AMAttached slightly modified files that make it work for both UAsm and ml.exe
Move the af.inc to the extra_files folder.
It is generally a good idea to test include files for both assemblers. UAsm is very compatible, but also a bit more powerful than MASM. Example:
works for both: invoke GdipDrawEllipse, hGraphics, hPen, FP4(50.0), FP4(50.0), PLUS_SIZE, PLUS_SIZE
UAsm only: invoke GdipDrawEllipse, hGraphics, hPen, 50.0, 50.0, PLUS_SIZE, PLUS_SIZE
Thanks JJ!!
I only ran the .exe. Apparently ml doesn't like my UASM printf routine too. It must be very simple to fix though, just saying :skrewy:
I love UASM !