2012-09-01 86 views
8

我正在试图描绘我的渲染器,而且我看到一些我无法解释的奇怪分析行为。为什么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措施需要运行我的所有绘制调用时的时间,swapTimer措施的时间从onDrawFrame何时退出以及何时返回(调用eglSwapBuffers所用的时间)。

当我跑了很轻负载的情景,我得到了一些非常奇怪的号码,我无法解释:

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

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

当我得出一个更加繁忙景象,数字改变了不少:

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

在这个场景我绘制调用正在采取这么多的时间,它看起来像它隐藏了许多的VSYNC周期的,并且清除通话中的区块完全消失。

有没有解释为什么glClear会在我轻微加载的场景中阻塞?

链接到我的“定时器”类源代码的情况下,有人怀疑我的测量技术:http://pastebin.com/bhXt368W

+0

您可以尝试在clearTimer.start()方法之前调用GLES20.glFinish(),然后查看时间如何变化? –

+0

我放了一个'glFinish'(和finishTimer.start()/ end()),它需要所有的时间远离glClear。相反,现在glFinish需要几毫秒,glClear变为即时。看起来这和所有的vsync都有关系,尽管我很惊讶地发现vsync时间出现在glClear中。 – Tim

回答

10

我把glfinish在(和finishTimer.start()/()结束周围),和它需要所有的时间远离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)=〜30 Hz

同步的延迟时间出现在您的分析器中。渲染器正在与屏幕同步。这意味着如果您删除glClear()glFinish()呼叫,延迟会出现在其他地方。

重型场景

F = 1/T = 1 /((2 + 0 + 44)×10^-3))=〜22赫兹

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

好像这是所有涉及到VSYNC

这似乎是正确的。

相关问题