Hi all, I know this subject has already been discussed often. However I didn’t find a clear argued answer. This post is specially oriented for performance guru like me and people who are looking for an FPSAnimator set in mode ‘schedule at fixed rate’ with a setable FPS value.
What I collected on other forum thread :
- FPSAnimator is good for almost everybody. I agree.
- It is not cross-platform and seems to be unstable.
- Active rendering technique may not be as secure as the listener one.
- Using nano time may waste CPU cycle and we don’t really need this kind of resolution.
- Using Thread.sleep() is wasting a lof of CPU cycles.
When looking into FPSAnimator code I’ve seen it is synchronized and based on a java.util.Timer. It actually doesn’t measure the time needed for executing the display and use the timer queue mechanism. I’ve though damn this is pretty complicated for what I want to achieve. Basically I need a timer which doesn’t mind if the task is taking longer than the period. I think we can do this with a simple wait(period).
What do you think about this draft class ?
public class SimpleFPSAnimator extends Thread {
private GraphDrawable drawable;
private long delay;
private AtomicBoolean animating;
private final Object lock = new Object();
public SimpleFPSAnimator(GraphDrawable drawble, int fps) {
super("SimpleFPSAnimator");
this.drawable = drawble;
this.animating = new AtomicBoolean();
setFps(fps);
}
@Override
public void run() {
animating.set(true);
try {
while (animating.get()) {
long startTime = System.currentTimeMillis();
drawable.display();
long timeout;
while ((timeout = delay - System.currentTimeMillis() + startTime) > 0) {
//Wait only if the time spent in display is inferior than delay
//Otherwise the render loop acts as a 'as fast as you can' loop
synchronized (this.lock) {
this.lock.wait(timeout);
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void shutdown() {
animating.set(false);
}
public boolean isAnimating() {
return animating.get();
}
private void setFps(int fps) {
delay = (long) (1000.0f / (float) fps);
}
}
I precise I don’t care about thread-safety, I only have one GLAutoDrawable to display and a unique controller manages the Animator. It is better to use this class with a GLCanvas because it doesn’t use special mechanism of Animator to paint GLJPanel (see Animator source).