HTC Desire特定的OpenGL ES 1帧速率 - 无法做到正确

时间:2010-09-14 07:15:38

标签: opengl-es android

我试图让一个非常简单的openGL ES 1程序在那里的几个设备上运行平稳的60fps,并且我被困在HTC的愿望上。手机本身快速,活泼,功能强大,使用起来轻而易举;但是,我似乎无法使用OpenGL以60fps的速度显示任何全屏。在我的应用程序长时间卡住之后,我决定使用代码从文档中创建一个包含代码的测试应用程序。

这是我正在做的事情。使用GLSurfaceView的简单初始化代码。我有三个版本的onDrawFrame,都很简单。一个是空的。一个只包含glClear。一个包含足够的状态只能绘制全屏四边形。跟踪时间之前和之后。在我的程序中除了我的GLSurfaceView之外没有其他视图。我无法解释我得到的时间。

在所有情况下,onDrawFrame函数本身总是在2ms以下完成。但很多时候,onDrawFrame在30~40ms之前不再被调用,将帧速率一直降低到30fps或更低。 我使用空的onDrawFrame获得大约50fps,使用glClear获得45,使用四边形获得35。 相同的代码在夏普ISO1上的三星Galaxy S上的HTC Magic上以60 fps运行。索尼Experia X10由于其屏幕而以30fps稳固封顶。我在HTC Magic上以60fps的速度做了更复杂的场景,与Desire相比,非常动力不足。我没有用于测试的Nexus One。 当然,我除了缓冲区交换阻止了几毫秒。但它只是一直跳过帧。

试图找出手机在onDrawFrame处理程序外部做什么,我尝试使用Debug.startMethodTracing。我无法获得跟踪以反映手机离开循环的实际时间。 在onDrawFrame的末尾,我使用startMethodTracing,然后将当前时间(SystemClock.uptimeMillis)保存在变量中。在下一个开始时,我记录自上次退出函数以来的时差,以及stopMethodTracing。这将被一遍又一遍地调用,所以我安排停止一旦我得到一个40+毫秒暂停的迭代的跟踪。 生成的跟踪的时间刻度不到2毫秒,就好像系统在我的程序之外花了38毫秒。

我尝试了很多东西。枚举EGL配置并一个接一个地尝试它们。只是为了看它是否改变了什么,当脏方案请求在每帧重绘时,我切换到渲染。无济于事。无论我做什么,交换缓冲区的预期间隔为14~16ms,大约一半时间需要30 + ms,无论我做什么,似乎设备都在等待两次屏幕刷新。设备上的ps显示我的应用程序大约10%cPU,System_server大约35%。当然我也尝试了显而易见的,杀死其他进程,重新启动设备...我总是得到相同的结果。

我对画布绘图没有同样的问题。

有没有人知道为什么欲望(和唯一的欲望)表现得像这样?

供参考,以下是我的测试代码:

public class GLTest extends Activity {  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        mGLView = new GLSurfaceView(this);  
        mGLView.setRenderer(new ClearRenderer());  
        setContentView(mGLView);  
    }  

    @Override  
    protected void onPause() {  
        super.onPause();  
        mGLView.onPause();  
    }  

    @Override  
    protected void onResume() {  
        super.onResume();  
        mGLView.onResume();  
    }  

    private GLSurfaceView mGLView;  
}  

class ClearRenderer implements GLSurfaceView.Renderer {  
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {}  
    public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); }  

    long start;  
    long end;  
    public void onDrawFrame(GL10 gl)  
    {  
    start = System.currentTimeMillis();  
    if (start - end > 20)  
        Log.e("END TO START", Long.toString(start - end));  
    //        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
    end = System.currentTimeMillis();  
    if (end - start > 15)  
        Log.e("START TO END", Long.toString(end - start));  
    }  
}  

2 个答案:

答案 0 :(得分:1)

你应该看看这个http://www.google.com/events/io/2010/sessions/writing-real-time-games-android.html

他建议你保持帧速率为30fps而不是60fps。

答案 1 :(得分:0)

也许我已经得到了答案:opengl驱动程序可能决定在稍后的步骤中执行大部分实际渲染。默认情况下,此步骤在onDrawFrame之后立即完成,这似乎是设备在离开方法后空闲的原因。好消息是,您可以将此步骤直接包含在onDrawFrame方法中:只需调用gl.glFinish() - 这将执行最终渲染并在完成时返回。之后应该没有空闲时间。然而,坏消息是实际上没有空闲时间,所以你将无法得到这个时间(我对我的渲染速度有多么幻想......现在我必须面对我真正的缓慢实施;))。关于glFinish你应该知道的:似乎有一个os级错误会导致某些htc设备出现死锁(比如欲望),据我所知,这仍然存在于2.2中。如果动画运行几个小时似乎会发生。但是,在网上存在修补的opengl表面视图实现,您可以使用它来避免此问题。不幸的是我现在没有链接,但你应该能够通过谷歌找到它(对不起!)。可能有一些方法可以使用在glFinish()中花费的时间:对于某些(全部?)部分,它可能是gpu活动,因此cpu可以自由地进行其他处理。