考虑以下代码:
import java.util.ArrayDeque;
import javafx.animation.AnimationTimer;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FrameTest extends Application
{
private static final int SUBFRAMES = 1;
private static final int FRAME_SAMPLE = 10;
private long prevTime;
private long frame;
private ArrayDeque<Long> frameTimes = new ArrayDeque<>();
private double fps;
private int subframe;
public static void main(String[] args)
{
Application.launch(args);
}
public void frameTick()
{
long time = System.nanoTime();
if (prevTime != -1)
{
while (frameTimes.size() > FRAME_SAMPLE - 1)
frameTimes.remove();
frameTimes.add(time - prevTime);
double fps = 0;
for (long ftime : frameTimes)
fps += ftime * 1e-9;
fps = frameTimes.size() / fps;
this.fps = fps;
System.out.printf("%.9f\n", fps);
}
prevTime = time;
}
@Override
public void start(Stage primaryStage) throws Exception
{
Transition trans = new Transition()
{
{
setCycleCount(INDEFINITE);
setCycleDuration(Duration.ONE);
}
@Override
protected void interpolate(double frac)
{
frameTick();
}
};
AnimationTimer timer = new AnimationTimer()
{
@Override
public void handle(long now)
{
frameTick();
}
};
//Comment out either one
trans.play();
//timer.start();
}
}
它基本上计算动画计时器的帧速率与转换。
当我使用javafx.animation.Transition
运行此FPS计算器时,它会吐出大约600~100000 fps(大范围)。当我使用AnimationTimer进行测试时,它大约在60fps左右。
只是好奇,这两种方法之间的内部区别是什么造成了如此贬低的结果?
答案 0 :(得分:2)
通过转换,您不会测量实际帧速率;您只是测量interpolate
被调用的频率。场景仍将仅以Prism渲染机制限制的速率渲染(默认情况下,其上限为60fps)。
因此,如果您的interpolate
方法实际更改了场景图,则并非所有这些更改都会在场景中实现。
AnimationTimer
的{{1}}方法实际上是作为场景渲染的一部分调用的:所以保证每帧只执行一次。