News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Timing Anti Aliasing in pure GDI versus GDI+

Started by LordAdef, April 15, 2025, 10:14:29 AM

Previous topic - Next topic

LordAdef

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

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...















source code and .exe in the zip

zedd151

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.

jj2007

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:

TimoVJL

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
May the source be with you

zedd151

#4
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: 

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.

TimoVJL

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
May the source be with you

adeyblue

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.

LordAdef

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




LordAdef

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'

LordAdef

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

LordAdef

Quote from: adeyblue on April 16, 2025, 02:35:27 AM
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.
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
  • , timer.routineTime[8]
    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

LordAdef

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

zedd151

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.

zedd151

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:

TimoVJL

It seems, that just in Windows 7 GDI is slower?
May the source be with you