libgdx-glClear需要太多时间

问题描述 投票:2回答:2

[方法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毫秒

android opengl-es libgdx
2个回答
8
投票

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

要了解此处发生的情况,您需要知道GPU与CPU代码异步运行。例如,当您调用glClear()时,您正在提交一条命令,告诉GPU清除帧缓冲区。描述此工作方式的最简单方法是将命令添加到队列中,稍后由GPU处理。

结果是,当glClear()调用返回时,通常不会清除帧缓冲区。因此,衡量调用所花费的时间与实际清除帧缓冲区所需的时间无关。

那么您要测量什么?基本上是帧速率。 Android不允许您以比屏幕刷新率(通常为60 Hz或更高)的速度更快地生成帧。在60 Hz时,显示屏每隔16.667 ms会显示一个新帧,这几乎恰好是您正在测量的时间。

您需要调整渲染速度以匹配显示刷新率,否则您将以更高的速度生成帧,并且会排队处理越来越多的工作。节流可能在任何地方发生,但是当已经有足够的工作排队时,在新帧开始时阻止应用程序是相当普遍的。

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

这实际上是非常可取的行为。根据系统和设置,某些PC类型的设备可使您渲染的速度快于屏幕刷新率。结果是您渲染的帧永远不会出现在显示器上,而只会被丢弃。如果您考虑一下,这完全是浪费。特别是在电池供电和/或受热量限制的设备上,您不想做任何不必要的工作。调整渲染以使其与屏幕刷新率相匹配是完全有意义的。


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 [[延迟了使用和返回为了避免无意义的GL调用。]如果您进行了以下类似的其他实验,则可能会发现记录的时间要短得多。

glClear()

© www.soinside.com 2019 - 2024. All rights reserved.