libgdx - glClear需要太多时间

时间:2015-09-12 12:30:04

标签: android opengl-es libgdx

方法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)上,在我的电脑上它的2-3毫秒

2 个答案:

答案 0 :(得分:6)

这是预期的。您正在测量帧速率,而不是glClear()的执行时间。

要了解这里发生的事情,您需要注意GPU与CPU代码异步操作。例如,当您调用glClear()时,您将提交一个命令,告诉GPU清除帧缓冲区。描述其工作原理的最简单方法是将命令添加到队列中,该队列稍后由GPU处理。

一个结果是,当glClear()调用返回时,帧缓冲区通常没有被清除。因此,测量在通话中花费的时间与实际清除帧缓冲所需的时间无关。

那你在测量什么?它基本上是帧速率。 Android不允许您生成比屏幕刷新率更快的帧,通常为60 Hz或稍高。在60 Hz时,显示屏每16.667 ms显示一个新帧,这几乎就是您测量的时间。

您的渲染需要受到限制以匹配显示刷新率,否则您将以更高的速率生成帧,并且会排队越来越多的工作。限制可能会发生在任何地方,但是当新的框架已经排队时,在新框架开始时阻止应用程序是相当常见的。

我相信大多数Android系统都使用三重缓冲。这意味着如果两个未显示的帧已经排队等待显示,并且您开始渲染另一个帧,则会阻止您的阻止,直到下一个屏幕刷新时显示两个待处理帧中的一个。

这实际上是非常理想的行为。根据系统和设置的不同,某些PC类型设备的渲染速度比屏幕刷新速度快。结果是您渲染的帧永远不会出现在显示器上,只是简单地删除。如果你考虑一下,这完全是浪费。特别是在电池供电和/或受热约束的设备上,您不希望做任何不必要的工作。限制渲染以匹配屏幕刷新率是完全合理的。

答案 1 :(得分:0)

接受的答案准确无误。我想使其更简单。

假设您的渲染功能如下:

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 延迟了glClear()调用的使用和返回,以避免无意义的GL调用。

如果您进行了以下类似的其他实验,则可能会发现记录的时间要短得多。

onDrawFrame() {
    time t1, t2;
    t1 = getTime();
    glClear();
    t2 = getTime();
    sleep(10);       // sleep 10 ms
    logOut(t2 - t1); // log time would be around 5 to 6 ms now
} 
相关问题