为什么glClear在OpenGLES中被阻塞?

我正在试图描绘我的渲染器,并且我看到了一些我无法解释的奇怪分析行为。

我正在使用glSurfaceView,我已经设置了不断渲染。

这就是我的onDrawFrame()的结构

public void onDrawFrame(GL10 unused) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    executeAllDrawCommands();
}

这在轻负载下表现得很慢,所以我创建了一个计时器类,并开始分析这一些。 我对我所看到的很惊讶。

我在我的onDrawFrame方法上放置了一些探测器,如下所示:

public void onDrawFrame(GL10 unused) {
   swapTimer.end();

   clearTimer.start();
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
   clearTimer.end();

   drawTimer.start();
     executeAllDrawCommands();
   drawTimer.end();

   swapTimer.start();
}

clearTimer测量调用glClear所drawTimer的时间, drawTimer测量运行所有绘制调用所swapTimer的时间, swapTimer测量onDrawFrame退出时间和返回时间(调用eglSwapBuffers所用的时间)之间的时间。

当我跑了一个很轻的场景时,我得到了一些我无法解释的奇怪数字:

swapTimer  : 20ms (average)
clearTimer : 11ms (average)
drawTimer  :  2ms (average)

我预计交换时间会稍微大一点,因为我相信该设备在〜30fps时强制启用vsync,但我不知道为什么实际的“清除”呼叫会阻塞11毫秒? 我以为它只是应该发出一个异步命令并返回?

当我画出更繁忙的场景时,数字会发生很大变化:

swapTimer  :  2ms (average)
clearTimer :  0ms (average)
drawTimer  : 44ms (average)

在这个场景中,我的平局电话花费了很多时间,看起来像隐藏了很多的vsync时间段,并且清除电话中的块完全消失。

有什么解释为什么glClear阻止我轻轻加载的场景?

链接到我的'计时器'类源代码,以防有人怀疑我的测量技术:http://pastebin.com/bhXt368W


我把glFinish(和finishTimer.start()/ end()放在它的周围),并且它需要所有的时间远离glClear。 相反,现在glFinish需要几毫秒,glClear变为即时。

这解释了它。

当你的场景非常轻时,图形渲染速度非常快,用新颜色清理和填充像素的时间将需要一些时间(它总是需要时间,否则渲染器在后面,并且是当前绘制新的东西)。 较新的Android设备具有填充限制。 例如,Nexus One具有30 Hz的填充率锁定 - 无论您的实际图纸进行得多快,屏幕都将以该频率进行同步。 如果图形在30 Hz以下完成,则渲染器将与屏幕同步。 这就是为什么你注意到这个延迟,即使你删除了glClear()调用,你应该注意到这个延迟。 渲染器在屏幕更新之前并快于屏幕更新。

当渲染器有许多要绘制的对象时,由于渲染器现在位于屏幕更新之后,所以同步将暂停(给定繁忙场景的配置文件数据)。

当你使用glFinish() ,它会消除glClear()函数会导致的时间,通过遵循填充率逻辑,这意味着glFinish()现在是确保与屏幕同步的函数。

计算

F = 1 / T

简单的场景

F = 1 / T = 1 /((20 + 11 + 2)* 10 ^ -3)=〜30Hz

同步的延迟时间将显示在您的分析器中。 渲染器正在与屏幕同步。 这意味着如果你删除了glClear()或者glFinish()调用,延迟就会出现在别的地方。

重场景

F = 1 / T = 1 /((2 + 0 + 44)* 10 ^ -3))=〜22Hz

同步的延迟时间不会出现在您的分析器中。 渲染器在屏幕更新频率之后。

这似乎与所有与vsync有关

这似乎是正确的。

链接地址: http://www.djcxy.com/p/64639.html

上一篇: Why is glClear blocking in OpenGLES?

下一篇: Is there any alternative for GLES20.glClear(GLES20.GL