• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

Animation loop Benchmark

Started by Patrice Terrier, September 06, 2009, 07:17:07 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

I have attached to this post a new Sprite demo showing the difference between a loop animation working in EXCLUSIVE mode, and one working in COOPERATIVE mode.

The graphic container uses a client size of 800 x 600 and it displays 24 sprites, using a pixel size of 140 x 140, the sprites are built from a BMP file using the magenta color to create the region on the fly.
The animation itself is running in 32-bit ARGB composited mode.

To see the difference between each of the loop animation mode, you will have to edit the code and rem /un-rem the appropriate section:


'         //////////////////////////////////////////////////
'         // EXCLUSIVE LOOP
         WHILE Done = %FALSE                              ' Loop That Runs While done = %FALSE
            IF PeekMessage(Msg, %NULL, 0, 0, %PM_REMOVE) THEN ' Is There A Message Waiting?
               IF msg.message = %WM_QUIT THEN             ' Have We Received A Quit Message?
                  Done = %TRUE                            ' If So done = %TRUE
               ELSE                                       ' If Not, Deal With Window Messages
                  CALL TranslateMessage(msg)              ' Translate The Message
                  CALL DispatchMessage(msg  )             ' Dispatch The Message
               END IF
            ELSE                                          ' If There Are No Messages
             ' Draw The Scene.
               IF gnAnimate THEN CALL DrawSprite            ' Render animation
            END IF
         WEND
'         //////////////////////////////////////////////////


'         //////////////////////////////////////////////////
'         // COOPERATIVE LOOP
'          FOR K = 1 TO 5 ' Use 5 timers to get the same FPS than in exclusive mode
'              CALL SetTimer(ghMain, K, K - 1, %NULL)
'          NEXT
'          WHILE GetMessage(Msg, %NULL, 0, 0)
'             CALL TranslateMessage(Msg)
'             CALL DispatchMessage(Msg)
'          WEND
'          FOR K = 1 TO 5
'              CALL KillTimer(ghMain, K)
'          NEXT
'         //////////////////////////////////////////////////


Actually each loop mode should display almost the same FPS.

On my computer with VISTA AERO 64-bit and a Dual Core 2 Duo T7200 running at 2Ghz, i got:
A FPS of 109-110 and a CPU charge of 49%.

To see the difference between the two modes, move the window around in exclusive mode the animation should stop, while in cooperative mode it is still running and responsive.

In real life application, it is very important to work in cooperative mode to let the other process work smoothly and simultaneously.

Usualy one single timer is enough, but then the maximum average you can get is 65 FPS. Most of the time i am limiting myself to 30 FPS, like with BassBox or MovieBox, because that is quite enough for the human eye and it keeps the other applications very responsive (The Windows task manager can still switch between all the other running process).

Another important thing when working in cooperative mode, never draw yourself directly, but instead invalidate the rectangle or the region and let Windows process the messages accordingly.

Note: I have no idea of the FPS this will produce on Emachine, thus if you have one, please let me know.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#1
Forget to say that this demo hogs the CPU by design, especialy on single core computer.
This is because i simulate a non-cooperative game loop (even in the cooperative mode) to get the higest FPS possible.

To reduce the CPU foot print, use the COOPERATIVE mode with only one TIMER instead of five, then on dual core you should get a 65 FPS, but on a single core it could be much smaller.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

From the private information that has been sent to me, it looks like the result on a single core processor is twice slower than on a  Dual Core, and use 99% CPU instead of 49%.

I wonder what would be the result running on a Quad Core, anyone having one?

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

Well the result on a Quad Core q6600 @ 2.4 GHz

123-126 fps
cpu ~ 34%


Well, these computers are realy playing in another category.

Thank you James!

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#4
I have added 3 new methods (radio buttons) to the zSprite demo to show you more about the FPS behavior.


  • GDImage TransBlt (ultimate speed)
  • GDImage Alphalend (high speed)
  • GDImage Composited (XP and VISTA AERO mode compatibility)
FPS values for Dual Core 2 T7200 running at 2Ghz on VISTA AERO 64-bit

EXCLUSIVE mode:
FPS 326 (GDImage TransBlt) Sprite.exe CPU 49%, DWM 9%
FPS 285 (GDImage AlphaBlend) Sprite.exe CPU 49%, DWM 9%
FPS 110 (GDImage Composited) Sprite.exe CPU 49%,  DWM 9%

COOPERATIVE mode (with one single TIMER):
FPS 65 (GDImage TransBlt) Sprite.exe CPU ~2%, DWM 7%
FPS 65 (GDImage AlphaBlend) Sprite.exe CPU ~4%, DWM 7%
FPS 65 (GDImage Composited) Sprite.exe CPU ~15%, DWM 5%

The composited mode works the same on both XP and VISTA AERO, and it is the only one that allows full sprite customization (size, variable opacity, anti-alias, rotation, etc.)

The TransBlt method works only with bitmap files using magenta (as transparent) color.

The ZIP file is attached to the first post of this thread.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Chris Boss

Patrice,

Do the different drawing modes depend upon high end video cards to see a difference between them ?

On my Windows XP Home PC (2.5 ghz, 768 meg Ram, NVidia GeForce4 MX 4000 video card) I don't see any real difference in the different modes.

EXCLUSIVE mode:

(GDImage TransBlt)
(GDImage AlphaBlend)
(GDImage Composited)

all get 22 to 24 FPS.


On your PC the TransBlt mode is nearly 300% faster than Composited mode.


Chris Boss

Ok, this is an interesting lesson.

I have a feeling that both the transparent Blit and alpha blt functions (if that is what you use) may be optimized by the video card on newer systems.
My XP likely was using 100% software to handle these functions, while on my Vista Home Premium (64 bit) PC, I saw a big, big difference.

Vista Home Premium (64 bit)  (rated 4.0 WEI)

Composite - 58 FPS
AlphaBlend - 98 FPS
TransBlt - 161 FPS

Thats 300% improvement for TransBlt over Composite. That matchs your numbers for your PC.

The best my sprite engine can get for the same # and size sprites (24) (140 x 140 pixels) is:

75 FPS

Very good Patrice!


Now I'll test it with more sprites, since as the number of sprites increases the drawing engine really gets put to the test.



Chris Boss

I tested your sprites (140 x 140) using 192 sprites on Vista Home Premium (WEI of 4.0):

Composite - 12 FPS
AlphaBlend - 20 FPS
TransBlt - 42 FPS

My sprite engine with same size sprites got:

13.68 FPS

TransBlt really flies on Vista!

Now I am sure TransBlt must have limitations compared to Composite, but if your customers need speed then it will likely be welcome.

Now I did one more test, this time with the penguin sprites:

1000 penguin sprites (your read it right one thousand):

Again on Vista: (I modified one of your original Penguin demos)

Composite - 1.94 FPS
Alphablend - 2.57 FPS
TransBlt - 3.53 FPS

Now for some strange reason, my sprite engine did quite well in this instance:

7.42 FPS
5.97 FPS (anti-aliased)

I don't know if it is the shape of the image that makes a difference (lot more jagged edges on penguin than a round sphere). The penguin sprite has a lot less pixels to draw too.






Patrice Terrier

#8
Because most modern LCD display are using a refresh rate of 60 Hz, the ideal maximum frame rate should be the same, because everything above the refresh rate would produce flickering and a waste of CPU resources.

To ease the comparison between the previous sprite demo, this one uses exactly the same code, but with the COOPERATIVE mode enabled and a FPS adjustment that should match a 60 Hz LCD display.

I have added variable opacity and stretching, to show you the big quality difference, between the GDImage Composite mode and (TransBlt or AlphaBlend).

Note: Even OpenGL and DirectX are using horizontal retrace synchronization, to avoid flickering.

This version uses a PNG file with alpha channel, instead of a BMP file with the magenta transparent color.


Changes done to the source code:

SUB CreateSprite(BYVAL hWin AS LONG)
   LOCAL rc AS RECT
   DIM gnXY(1 TO %MAX_SPRITE, 1 TO 4)

   CALL GetClientRect(gnCtrl, rc)
   x& = (rc.nRight - bmW&) \ 2: y& = (rc.nBottom - bmH&) \ 2
   FOR K& = 1 TO %MAX_SPRITE
       IF K& = 1 THEN
          'CALL ZD_DrawBitmapToCtrl(gnCtrl, x&, y&, ZI_CreateBitmapFromFile("Hal_red.bmp", bmW&, bmH&), &HFFFFFFFF, %ID_OBJECT_SPRITE + K&, %FALSE): CALL ZI_TransparentColor(%ZD_TRANSCOLOR, 1)
          CALL ZD_DrawBitmapToCtrl(gnCtrl, x&, y&, ZI_CreateBitmapFromFile("Red.png", bmW&, bmH&), &HFFFFFFFF, %ID_OBJECT_SPRITE + K&, %FALSE)
       ELSE
          CALL ZD_CloneObject(%ID_OBJECT_SPRITE + 1, %ID_OBJECT_SPRITE + K&, x&, y&)

CALL ZD_SetObjectScale(%ID_OBJECT_SPRITE + 1, (10 * RND(5, 9)) / 100)
CALL ZD_SetObjectAlpha(%ID_OBJECT_SPRITE + 1, RND(64,200), %FALSE)

       END IF
   NEXT

END SUB



'         //////////////////////////////////////////////////
'         // EXCLUSIVE LOOP
'          WHILE Done = %FALSE                              ' Loop That Runs While done = %FALSE
'             IF PeekMessage(Msg, %NULL, 0, 0, %PM_REMOVE) THEN ' Is There A Message Waiting?
'                IF msg.message = %WM_QUIT THEN             ' Have We Received A Quit Message?
'                   Done = %TRUE                            ' If So done = %TRUE
'                ELSE                                       ' If Not, Deal With Window Messages
'                   CALL TranslateMessage(msg)              ' Translate The Message
'                   CALL DispatchMessage(msg  )             ' Dispatch The Message
'                END IF
'             ELSE                                          ' If There Are No Messages
'              ' Draw The Scene.
'                IF gnAnimate THEN CALL DrawSprite          ' Render animation
'             END IF
'          WEND
'         //////////////////////////////////////////////////


'         //////////////////////////////////////////////////
'         // COOPERATIVE LOOP
         FOR K = 1 TO 1 ' Use 5 timers to get the same FPS than in exclusive mode
'              CALL SetTimer(ghMain, K, K - 1, %NULL)
             CALL SetTimer(ghMain, K, 5, %NULL) ' <-----<<  Delay = 5 ms
         NEXT
         WHILE GetMessage(Msg, %NULL, 0, 0)
            CALL TranslateMessage(Msg)
            CALL DispatchMessage(Msg)
         WEND
         FOR K = 1 TO 1 '5
             CALL KillTimer(ghMain, K)
         NEXT
'         //////////////////////////////////////////////////



To see the quality difference, press the stop button, while trying each mode, and look at the stretching of the sprites.

I hope that this gives you a better insight of what must be done to produce state of the art animation :)

...


Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Stefan Midegaal

All Zip Files are corrupted.

greets

Patrice Terrier

This thread is almost 9 years old, and the 32-bit examples are deprecated anyway.

My current animation loop is based on the use of a SyncTimer thread function, to replace the classic TIMER API (that has a limited resolution of 60 FPS).
Now i am using the same resfresh rate than the main display being used (most of the time 75 hz on modern display).

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Stefan Midegaal

#11
Is nothing special. :)

Is nothing else then a  "high-resolution multimedia timer " From MMSystem, which uses no limit and thread.

But that was not the question ;)
OK no problem.

greets

Patrice Terrier

#12
Quoteis nothing else then a "high resolution multimedia timer" from MMSystem
No it is not. It is based on the DWM_TIMING_INFO, and the use of PostMessage from a permanent thread loop.

DWORD WINAPI SyncTimer(IN DWORD delay) {
    long sm, dr;
    for (;;) {
        EnterCriticalSection(&gP.cs);
        gP.AniTick = GetTickCount();
        sm = gP.sync_mode; dr = gP.doneRender;
        LeaveCriticalSection(&gP.cs);
        if (sm == SYNC_ON) {
            if (!dr) {
                PostMessage(gP.hMain, WM_SYNC_NOTIFY, IDC_TIMER, 0);
            }
            // timeBeginPeriod() IS A MUST, ELSE Sleep()
            // WILL ALWAYS SLEEP NOT LESS THAN 16 msec (= 62.5 FPS ONLY) !!!
            timeBeginPeriod(1); // set wait resolution to 1 msec
            Sleep(delay); // let loop run at monitor refresh rate plus a few extra FPS for reliable VSYNC
            timeEndPeriod(1); // restore default resolution
        } else if (sm == SYNC_BREAK) {
            ExitThread(ERROR_SUCCESS);
        }
    }
    return 0;
}



This is how the ObjReader VBO version 2.52 renders millions polies with a refresh rate of 75 FPS, or even more if the main display vsync refresh rate is faster. The accuracie has been checked with FRAPS...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Stefan Midegaal

#13
QuoteWILL ALWAYS SLEEP NOT LESS THAN 16 msec
Timer set over SetTimer simple API has a limit of 16ms eg.. if your set your timer then to 0 .. if the same 16ms Limit.

this Trouble is gone do use timeSetEvent a Callback of MMSytem High Resolution Multimedia Timer.
your timer Event is not faster or more accurate :) That is a fallacy.

QuoteThe timeSetEvent function starts a specified timer event. The multimedia timer runs in its own thread. After the event is activated, it calls the specified callback function or sets or pulses the specified event object.

EDIT:
QuoteThis is how the ObjReader VBO version 2.52 renders millions polies with a refresh rate of 75 FPS, or even more if the main display vsync refresh rate is faster. The accuracie has been checked with FRAPS...
use mmsystem and check again ;)

greets

Patrice Terrier

#14
Wrong you are, check ObjReader with FRAPS and see the result.
Look also carefully at the source code posted in my previous post.

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com