Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: When Using SetFramerateLimit(60) it's actually 30-32?  (Read 8262 times)

0 Members and 1 Guest are viewing this topic.

efeX

  • Newbie
  • *
  • Posts: 13
    • View Profile
When Using SetFramerateLimit(60) it's actually 30-32?
« on: September 12, 2009, 11:18:26 pm »
I noticed when i use SetFramerateLimit(60) the FPS actually seems to be 30-32... When i use SetFramerateLimit(30) the FPS is 20-21. When I use SetFramerateLimit(90) the FPS is 60-62....

Am I using it wrong or is the parameter the FPS you want to limit it to?

Code...

Code: [Select]

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Test");
Window.SetFramerateLimit(60);

while (Window.IsOpened())
{
sf::Event Event;
while (Window.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
Window.Close();
}

Window.Clear();

std::cout << 1 / Window.GetFrameTime() << std::endl;

Window.Display();
}
}
[/code]

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #1 on: September 13, 2009, 01:19:14 am »
You're not printing the right thing :
Code: [Select]
std::cout << 1 / Window.GetFrameTime() << std::endl; doesn't print FPS because there are some Sleep call inside Display so you're not measuring the right among of time. ( Sorry if you don't understand what I'm saying. I don't find my words. )
SFML / OS X developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #2 on: September 13, 2009, 10:34:27 am »
Quote
doesn't print FPS because there are some Sleep call inside Display so you're not measuring the right among of time

GetFrameTime takes this in account. Otherwise it would be completely useless ;)

Quote
I noticed when i use SetFramerateLimit(60) the FPS actually seems to be 30-32...

Do you have vertical synchronization enabled (in your display driver settings)?
Laurent Gomila - SFML developer

K-Bal

  • Full Member
  • ***
  • Posts: 104
    • View Profile
    • pencilcase.bandcamp.com
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #3 on: September 13, 2009, 10:47:11 am »
I would also guess this has to do with VSync.

However, you should write 1.0 instead of 1 ;)
Listen to my band: pencilcase.bandcamp.com

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #4 on: September 13, 2009, 10:53:29 am »
Quote from: "K-Bal"
However, you should write 1.0 instead of 1 ;)
Here it doesn't change anything : Window.GetFrameTime()'s type is float.
But it's cleaner yeah.
you can also write 1.f .

Laurent, 8 hours later I agree.  :P
SFML / OS X developer

efeX

  • Newbie
  • *
  • Posts: 13
    • View Profile
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #5 on: September 13, 2009, 11:01:06 am »
Quote from: "Laurent"
Quote
doesn't print FPS because there are some Sleep call inside Display so you're not measuring the right among of time

GetFrameTime takes this in account. Otherwise it would be completely useless ;)

Quote
I noticed when i use SetFramerateLimit(60) the FPS actually seems to be 30-32...

Do you have vertical synchronization enabled (in your display driver settings)?


It's set to "Let the application decide"

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #6 on: September 13, 2009, 11:17:43 am »
Which version of SFML do you use?
Laurent Gomila - SFML developer

efeX

  • Newbie
  • *
  • Posts: 13
    • View Profile
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #7 on: September 13, 2009, 12:10:38 pm »
1.5... tempted to just get the svn and build

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #8 on: September 13, 2009, 06:59:55 pm »
I think that it wouldn't solve your problem :(
Laurent Gomila - SFML developer

ptrxyz

  • Newbie
  • *
  • Posts: 32
    • View Profile
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #9 on: September 18, 2009, 12:12:29 pm »
Yes, I got this problem too. I am using SFML 1.5 on WinXP SP3....some ATI GFX card, latest drivers.
I worked around this using my own timing functions but since other people have that problem too, maybe we can find out what the problem with it is?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #10 on: September 18, 2009, 12:20:33 pm »
Quote
I worked around this using my own timing functions

Does it work? Can you show it?
Laurent Gomila - SFML developer

ptrxyz

  • Newbie
  • *
  • Posts: 32
    • View Profile
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #11 on: September 18, 2009, 12:34:55 pm »
All I do is looping until a specific time has passed...
I dont use the SFML functions so I guess it wont help you in any way. It's just something like:

Code: [Select]

...
while (main_game_loop) {
framestart = getMilliSecSinceMidnight();

PrepareAllSprites();
DoDisplay();

while (getMilliSecSinceMidnight()-framestart < 25) { // use at least 25 msec per Frame since I want 40 Frames Per Sec.
LetWindowsHandleEvents(); // I am using windows....
}
}
...


So it's actually just a delay added to the loop. Well the original code is way better done but still nothing really super clever. Just a little work around...
If you still want to see the original code I can post it this evening. currently I am at work so I can access it =(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #12 on: September 18, 2009, 12:54:54 pm »
Ok I see, thanks.

But what's the point of this code? There's nothing to make the main thread sleep, so your CPU will just be busy looping instead of being busy rendering more frames.
Laurent Gomila - SFML developer

ptrxyz

  • Newbie
  • *
  • Posts: 32
    • View Profile
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #13 on: September 18, 2009, 12:54:54 pm »
Oh I just checked your sources and found out you are doing some timing with QPC.... I didnt check if you get the frame time with QPC too, but if so, this might be the problem.
QPC is known to be buggy in many ways:
- If you have more then one CPU core the frequency might change depending on the core your thread is running on.
- The frequency can be dynamic if you are running this on a CPU that changes it's speed (for energy saving purposes, e.g Laptops and some low energy using desktop CPUs)
- some CPUs have dynamic clock skip feature used for thermal throttling
- If you are using it in virutalized environment, e.g. VMWare, Xen, VirtualBox etc you will get most likely not get real values.
...

Well, therefore most programmes do this:

check if the frequency from QPC is "stable" over time and if it fits to the values returned from getTickCount. If not, consider it as bugged and use getTickCount or timeGetTime().

Another way would be a nice callback timer....this one calls a function to increase a counter....:
Code: [Select]


// Some variables to put somewhere:

MMRESULT timer_id = 0;
TIMECAPS timer_caps;
unsigned int volatile GlobalInternalTimerValue = 0;

// Timer init:

if( timeGetDevCaps(&timer_caps,sizeof(TIMECAPS)) != TIMERR_NOERROR)
  return Error("Unable to retrieve timing capabilities");
if( timeBeginPeriod(timer_caps.wPeriodMin) != TIMERR_NOERROR )
  return Error("Unable to set timer resolution" );

timer_id = timeSetEvent(1,timer_caps.wPeriodMin,timer_func,0,TIME_PERIODIC);
if( timer_id == 0 )
  return Error("Unable to create timer");

// Timer callback:

void CALLBACK timer_func(unsigned int,unsigned int,DWORD,DWORD,DWORD)
{
  GlobalInternalTimerValue++;
}

// Timer release:

unsigned int hr = timeEndPeriod( timer_caps.wPeriodMin );
// make sure hr == TIMERR_NOERROR
hr = timeKillEvent( timer_id );
// make sure hr == TIMERR_NOERROR


ptrxyz

  • Newbie
  • *
  • Posts: 32
    • View Profile
When Using SetFramerateLimit(60) it's actually 30-32?
« Reply #14 on: September 18, 2009, 12:57:53 pm »
Quote from: "Laurent"

But what's the point of this code? There's nothing to make the main thread sleep, so your CPU will just be busy looping instead of being busy rendering more frames.


Well, the problem was that Windows was using 100% CPU to just draw frames. So the LetWindowsHangleEvents() thing lets windows clear the message stack....as I said, just a quick work around. The main problem is the QPC I guess.... (see above ;))

 

anything