Too many FPS in android device

Hello, everybody.

I’ve been testing a simple runner game both in Win32 and in a Galaxy S3, as well as other similar phones. The FPS always remains around 60 fps, which is very good. The game has 3 sets of assets: 2048x1536, 1024x768 and 512x384.
Now, I’m testing on a Samsung Galaxy Ace Plus S7500 running Android 2.3.6, which has a 480x320 resolution, so the 512x384 resolution is picked and scaled down. The problem I have is that in this device the game runs at 86 fps, so it’s unbearably fast.

Could this be a problem of the assets being scaled down instead of up? (should I make them 480x320 instead of 512x384? It’s a drag to do it, that’s why I ask here first in case anyone knows)
The Animation Interval is set in AppDelegate.cpp like this:

pDirector->setAnimationInterval(1.0 / 60);

Please note this doesn’t happen in Win32 when I set the window to 480x320 (the right assets of 512x384 are picked and scaled down, but the FPS remains at 60).

Any help is greatly appreciated! :slight_smile:

Cheers!

Cocos2dx relies on vsync (vertical synchronization) to provide the same FPS that other system uses. It’s vendor choice if vsync enabled and how many FPS it expects. IPad simulator have vsync with FPS limit=20, some android devices have FPS limit=60 or 30, and seems that vsync disabled on Samsung Galaxy Ace Plus.

Maybe it can be enabled in android settings app.

Hi, Sergey.

Thank you very much for your answer. :slight_smile:
I looked around the phone’s configuration options, but didn’t come across anything like that. I searched in Google too, but found nothing. :confused:
Does that mean that any game I do in cocos2dx, in this phone (and possibly others) the framerate will be all wrong?
Do you know of any other way to control the framerate?

Thanks!

You can try to make tweak in CCDirector.cpp: I think code should be inserted right after _openGLView->swapBuffers() call. You should ensure that every frame renders in animation interval time, and sleeps rest of time.

After each swapBuffers calls, director should

  1. Get time saved on step 3, add animation interval time and compare with current time
  2. If current time is bigger, do nothing; otherwise sleep for delta time
  3. Save current time (prefer nanoseconds resolution)

Note that sleep can return control after desired date, so app will sleep longer than asked. It usually workarounded with “multimedia timers”, but I don’t know what exactly you should do.

I don’t understand the problem here. I would be very happy if my app runs at 60+ fps. It only means I won’t have any lag on the graphics. This is only a problem if your game update is based on frames not delta time. If your game update is based on frames (FPS) then I guess the solution that you should work on is how to make your game update base on delta time because that is how it should be. Does this make sense? XD

Sergey Shambir wrote:

You can try to make tweak in CCDirector.cpp: I think code should be inserted right after _openGLView->swapBuffers() call. You should ensure that every frame renders in animation interval time, and sleeps rest of time.
>
After each swapBuffers calls, director should
>
# Get time saved on step 3, add animation interval time and compare with current time
# If current time is bigger, do nothing; otherwise sleep for delta time
# Save current time (prefer nanoseconds resolution)
>
Note that sleep can return control after desired date, so app will sleep longer than asked. It usually workarounded with “multimedia timers”, but I don’t know what exactly you should do.

Thanks! I’ll check it out and see if I can make it work. :slight_smile:

Jan Michael Chuaquico wrote:

I don’t understand the problem here. I would be very happy if my app runs at 60+ fps. It only means I won’t have any lag on the graphics. This is only a problem if your game update is based on frames not delta time. If your game update is based on frames (FPS) then I guess the solution that you should work on is how to make your game update base on delta time because that is how it should be. Does this make sense? XD

mmm… maybe I’m not explaining myself good enough. :stuck_out_tongue:
Let’s see. For example the game character has a certain speed, which is used to move the scenario to the left in each update. The speed is a fraction of the screen (so in any resolution the amount is the “same”). The problem I have is that in the device I mentioned the speed is too much, everything flies to the left.
In the same manner, the “physics” are based on the same principle. If the player presses the screen to jump, I apply a certain amount to his Y vector, updating its up speed. When it reaches a maximum, gravity is applied down. This is also applied each update. What happens is that in any other device I’ve tested, the speed, up movement and down movement are just like in Win32, but in this device all of them are WAY TOO FAST. :stuck_out_tongue:

So, now that I checked that the FPS are around 85, I guess that in a second more updates are called, so each of those numbers are applied more times than in other devices (and that is why it looks faster).

I did it this way because I assumed cocos controlled more or less the amount of updates called each second, but if that’s not always the case, how would you change what I just described so it’s independent of that? Any help would be great! :slight_smile:

Cheers!

Pablo Mera wrote:
>

So, now that I checked that the FPS are around 85, I guess that in a second more updates are called, so each of those numbers are applied more times than in other devices (and that is why it looks faster).
>

This is exactly why you shouldn’t base your game logic updates ob FPS - this approach bases on assumption that you will always have the fixed amount of FPS. In my experience FPS always vary a little during play, so you get values like 58 ~ 62.
A better approach is to base your game logic updates on the amount of time that passed between frames. So for example you want your character to move 100px/second so when a device gives you 60FPS the time between frames is 1/60 of a second so you move your character 1/60 * 100px each frame. If you get 85FPS you move your character 1/85 * 100px each frame.

1 Like

Pawel Lopusinski wrote:

This is exactly why you shouldn’t base your game logic updates ob FPS - this approach bases on assumption that you will always have the fixed amount of FPS. In my experience FPS always vary a little during play, so you get values like 58 ~ 62.
A better approach is to base your game logic updates on the amount of time that passed between frames. So for example you want your character to move 100px/second so when a device gives you 60FPS the time between frames is 1/60 of a second so you move your character 1/60 * 100px each frame. If you get 85FPS you move your character 1/85 * 100px each frame.

Now I get it. Thank you so much for your help. :slight_smile:
It was much faster and easier to solve than I thought; changing everything to depend on dt only took 10 minutes. :smiley:

Great! :slight_smile:

Cocos2dx relies on vsync

OMG, this explains the most unclear thing: why my game runs at 54fps on my device, and at 85fps on my colleague’s device, while they both have the same processor and Android version.
But, don’t you think that relying on vsync is not cool? I mean theoretically we could have 100+fps which results in wasting processor time == wasting battery power. I believe that Cocos2dx should limit its framerate and sleep when it runs faster than it should. And this functionality should be out of the box.

Artists animate something based on what looks good for the FPS they expect the animation to run at. If it runs too fast or too slow, it simply doesn’t look right. I’m rather surprised that FPS is based on vertical sync since that can vary from device to device, instead of being based on time, which is more exacting. Perhaps a suggestion that can be made to the developers of Cocos2d-x ?

Yep, i created this issue to trace it.

Hello everyone I found this article which states that this issue was fixed with android 4.1 “Project Butter” so the fps wont go more than 60. I think its safe to drop support for android 2.3 now since android stopped supporting it.

take a look at this article also it talks about it