c - eglSwapBuffers 在 Raspberry Pi 上非常慢

标签 c opengl-es-2.0 raspberry-pi3

我目前将 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 - eglSwapBuffers 在 Raspberry Pi 上非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55863929/

相关文章:

c - 给定月份的最后一天

C fgets 与 fgetc 读取行

android - Android OpenGL ES 应用程序的屏幕截图

java - 为什么这不能形成一个好看的正方形?

python - Raspberry Pi 上的按钮交互

audio - 将多个蓝牙扬声器与 Raspberry Pi 连接

c - 如何将位图中的位映射到伙伴分配器中的物理页?

c - 未知全局数组索引的归约或原子运算符

objective-c - OpenGL ES 2.0 纹理变成黑色

linux - 在 csv 命令输出的列后选择值