[方法Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
花费太多时间,大约15毫秒
这里是代码示例:
long now = System.currentTimeMillis();
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
long end = System.currentTimeMillis() - now;//this is almost always > 15 ms
System.out.println("render time total: " + end);
这是在我的android设备(nexus 5)上,在我的PC上是2-3毫秒
这是预期的。您正在测量帧速率,而不是glClear()
的执行时间。
要了解此处发生的情况,您需要知道GPU与CPU代码异步运行。例如,当您调用glClear()
时,您正在提交一条命令,告诉GPU清除帧缓冲区。描述此工作方式的最简单方法是将命令添加到队列中,稍后由GPU处理。
结果是,当glClear()
调用返回时,通常不会清除帧缓冲区。因此,衡量调用所花费的时间与实际清除帧缓冲区所需的时间无关。
那么您要测量什么?基本上是帧速率。 Android不允许您以比屏幕刷新率(通常为60 Hz或更高)的速度更快地生成帧。在60 Hz时,显示屏每隔16.667 ms会显示一个新帧,这几乎恰好是您正在测量的时间。
您需要调整渲染速度以匹配显示刷新率,否则您将以更高的速度生成帧,并且会排队处理越来越多的工作。节流可能在任何地方发生,但是当已经有足够的工作排队时,在新帧开始时阻止应用程序是相当普遍的。
我相信大多数Android系统都使用三重缓冲。这意味着,如果两个未显示的帧已经排队等待显示,并且开始渲染另一个帧,则会阻塞,直到在下一次屏幕刷新中显示两个挂起的帧之一。
这实际上是非常可取的行为。根据系统和设置,某些PC类型的设备可使您渲染的速度快于屏幕刷新率。结果是您渲染的帧永远不会出现在显示器上,而只会被丢弃。如果您考虑一下,这完全是浪费。特别是在电池供电和/或受热量限制的设备上,您不想做任何不必要的工作。调整渲染以使其与屏幕刷新率相匹配是完全有意义的。
接受的答案是准确准确的。我想使其更简单。
假设您的渲染功能如下:
onDrawFrame() {
time t1, t2;
t1 = getTime();
glClear();
t2 = getTime();
logOut(t2 - t1); // log time would be around 16 ms
}
如果刷新FPS为60Hz,则刷新裕度约为16.666毫秒。现在,如果您的渲染时间小于16毫秒,这将毫无意义,因为GPU无法处理更新的调用(很好的GPU拥有一个队列来缓冲这些调用,但是无论如何该队列都不是无限的)。
因此,GPU [[延迟了使用和返回为了避免无意义的GL调用。]如果您进行了以下类似的其他实验,则可能会发现记录的时间要短得多。
glClear()