我目前将OpenGL应用程序(仅绘制2D内容)移植到OpenGL ES,以便在Raspberry Pi上正常运行。
由于某些原因,eglSwapBuffers
需要花费大量时间。这是我做过的基准测试(您可以看到我使用的功能):
****** BEGIN BENCHMARK RESULTS
GLESSTATS swap_buffers: 519,180 ms
GLESSTATS createShader: 5,508 ms
GLESSTATS createProgram: 3,584 ms
GLESSTATS setViewport: 0,010 ms
GLESSTATS createTexture: 17,087 ms
GLESSTATS bindTexture: 0,008 ms
GLESSTATS updateTexture: 2,192 ms
GLESSTATS drawGradientRect: 0,288 ms
GLESSTATS drawTexturedRect: 0,206 ms
****** END BENCHMARK RESULTS
当前,我尝试创建RGBA表面。这些是我对EGL的属性:
EGLint ctx_attrs[] = {
EGL_RENDERABLE_TYPE, OPEN_GL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_NONE
};
EGLint surf_attrs[] = {
EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
EGL_NONE
};
我在这里做错什么了吗?我所发现的是,窗口和表面之间的像素格式不匹配可能会使swap_buffers花费很长时间。我已经在R5G6B5,R8G8B8和R8G8B8A8上进行过尝试。
答案 0 :(得分:1)
请记住,GPU和CPU独立运行,因此对OpenGL驱动程序的调用通常是异步的。在某个时候,CPU必须坐下来等待这些OpenGL调用完成。
正如Andreas在上面的评论中提到的,强制执行此CPU / GPU同步的调用是glFinish(),恰好碰巧eglSwapBuffers实际上会在开始交换缓冲区之前调用glFinish。
这意味着您为eglSwapBuffers安排的时间很可能包括处理updateTexture,drawGradientRect,drawTexturedRect的几乎所有时间,以及交换缓冲区的时间。
我也希望您的计时单位错误?半秒钟渲染帧对我来说听起来并不好吗?您确定它们不是ns而不是ms?
此外,我希望您不编译新的着色器,也不在每帧创建新的纹理? (并且仅在它们实际更改时才这样做吗?)。如果需要每帧创建一个新纹理,请确保渲染完成后删除GL纹理,否则内存泄漏可能是导致速度变慢的原因。