Merge pull request #5697 from JakubValtar/improve-frame-rate

Stop frame rate counter from exaggerating
This commit is contained in:
Ben Fry
2019-01-11 19:40:52 -05:00
committed by GitHub
+29 -4
View File
@@ -713,7 +713,7 @@ public class PApplet implements PConstants {
* @see PApplet#frameRate(float)
* @see PApplet#frameCount
*/
public float frameRate = 10;
public float frameRate = 60;
protected boolean looping = true;
@@ -2434,9 +2434,34 @@ public class PApplet implements PConstants {
} else { // frameCount > 0, meaning an actual draw()
// update the current frameRate
double rate = 1000000.0 / ((now - frameRateLastNanos) / 1000000.0);
float instantaneousRate = (float) (rate / 1000.0);
frameRate = (frameRate * 0.9f) + (instantaneousRate * 0.1f);
// Calculate frameRate through average frame times, not average fps, e.g.:
//
// Alternating 2 ms and 20 ms frames (JavaFX or JOGL sometimes does this)
// is around 90.91 fps (two frames in 22 ms, one frame 11 ms).
//
// However, averaging fps gives us: (500 fps + 50 fps) / 2 = 275 fps.
// This is because we had 500 fps for 2 ms and 50 fps for 20 ms, but we
// counted them with equal weight.
//
// If we average frame times instead, we get the right result:
// (2 ms + 20 ms) / 2 = 11 ms per frame, which is 1000/11 = 90.91 fps.
//
// The counter below uses exponential moving average. To do the
// calculation, we first convert the accumulated frame rate to average
// frame time, then calculate the exponential moving average, and then
// convert the average frame time back to frame rate.
{
// Get the frame time of the last frame
double frameTimeSecs = (now - frameRateLastNanos) / 1e9;
// Convert average frames per second to average frame time
double avgFrameTimeSecs = 1.0 / (double) frameRate;
// Calculate exponential moving average of frame time
final double alpha = 0.05;
avgFrameTimeSecs = (1.0 - alpha) * avgFrameTimeSecs + alpha * frameTimeSecs;
// Convert frame time back to frames per second
frameRate = (float) (1.0 / avgFrameTimeSecs);
}
if (frameCount != 0) {
handleMethods("pre");