c - Raspberry Pi 上的 eglSwapBuffers 非常慢
问题描述
我目前将一个 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 试过了。
解决方案
重要的是要记住 GPU 和 CPU 独立运行,因此对 OpenGL 驱动程序的调用通常是异步的。在某些时候,CPU 必须等待这些 OpenGL 调用完成。
正如 Andreas 在上面的评论中提到的,强制此 CPU/GPU 同步的调用是 glFinish(),而 eglSwapBuffers 在开始交换缓冲区之前实际上会调用 glFinish。
这意味着您的 eglSwapBuffers 时间很可能包括处理 updateTexture、drawGradientRect、drawTexturedRect 所花费的几乎所有时间,以及交换缓冲区的时间。
我也希望你的计时单位是错误的?半秒渲染一帧对我来说听起来不太好?你确定他们不是ns而不是ms?
另外,我希望你不是在编译一个新的着色器并在每一帧创建一个新的纹理?(并且只有在它们真正改变时才这样做?)。如果您需要每帧创建一个新纹理,请确保在渲染完成后删除 GL 纹理,否则内存泄漏可能是导致速度减慢的原因。
推荐阅读
- c# - 角色停止移动,我不知道为什么
- azure - Azure Kubernets 部署失败 ....错误:收到来自模型管理服务的错误响应:响应代码:400
- c++ - 当我给出一个以上的测试用例时,这显示错误的输出
- postgresql - Wiki.js 未运行。数据库连接错误
- python - 使用 ID 获取 TextCtrl 值
- javascript - 努力了解 React 如何确定 API 服务器的地址
- java - Firebase 数据库指向错误的数据库 URL
- c# - 将 4 个 0-16 数字存储在一个短字节中(或 2 个数字存储在一个字节中)
- powerbi - PowerBi/Dax 汇总表并获得平均评分
- octave - 尽管相同的代码在“Octave-online”中有效,但输出错误并带有特殊符号“[square]”