Search code examples
androidopengl-esopengl-es-2.0frame-rate

Android OpenGL ES: limit frames per second


I have the problem that my frame limiter works very imprecise. I set the target frames per second to 30 but I get values between 10FPS and 500FPS. I think I did a big mistake but I cant find it. This is the class that is supposed to limit the FPS:

public class FrameLimiter {

private long interval;
private long startTime;
private long endTime;
private long timeForOneFrame;

/** Limits an unlimited loop.
 * You should select a value above 25FPS!
 * @param FPS the target value of frames per second
 */
public FrameLimiter(int FPS){
    interval = 1000/FPS;
    startTime = System.currentTimeMillis();
}

/** Calling this method stops the current thread until enough time elapsed to reach the target FPS.
 */
public void limit(){
    endTime = System.currentTimeMillis();
    timeForOneFrame = endTime - startTime;

    if (timeForOneFrame < interval)
        try {
            Thread.sleep(interval - timeForOneFrame);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    startTime = System.currentTimeMillis();
}

/** Returns the current FPS measured against the time between two calls of limit().
 * This method just works in combination with limit()!
 * @return the current FPS.
 */
public int getFPS(){
    if(timeForOneFrame <= 0){
        return 0;
    }else{
        return (int) (1000/timeForOneFrame);
      }
  }
}

I use my class this way:

@Override
public void onDrawFrame(GL10 gl) {            
    this.render();

    Log.d(toString(), String.valueOf(limiter.getFPS())+ "FPS");
    limiter.limit();    //has to be the last statment
}

I would appreciate every help.


Solution

  • System.currentTimeMillis();
    

    This function is very imprecise in Android (is discontinuos) use instead:

    SystemClock.elapsedRealtime();
    

    and

    SystemClock.sleep(millis); //not need try block, instead of 
    
    Thread.sleep(millis);//need try block