OpenGL ES 在无头嵌入式 linux 平台中的使用

OpenGL ES use in a headless embedded linux platform

在我们的项目中,我们希望使用 Freescale iMX6Q ARM 处理器的 GPU 渲染图像,然后通过 gstreamer 管道写入 VNC 服务器。 顺序如下:

我们使用 Yocto 1.8 作为构建系统,初始化序列下方的源代码适用于我们的 nitrogen6X-lite 原型板(定义了 USE_PBUFFER),但不适用于我们的无头生产板。在生产板上我们无法初始化 "display":无论是否定义了 USE_PBUFFER,我们都会得到一个 0x3003 EGL_BAD_ALLOC 错误。我们有 vfb 内核模块加载了 vfb_enable=1video=vfb 内核选项。开发文件 /dev/fb0 创建成功。在 yocto 中,我们尝试了默认模式下的 fsl-image-multimedia-fullimage-coreimage-core-directfb 图像,以及

DISTRO_FEATURES_remove = " x11 wayland"
DISTRO_FEATURES_append = " directfb"

在我们的 conf/local.conf 文件中。

我们应该如何在嵌入式 Linux 设置中使用 iMX 处理器的 GPU 在没有显示器的情况下进行离屏渲染?什么是合适的内核设置?什么是合适的 user-space 使用的功能?

当前用户-space OpenGL 初始化序列的实现:

EGLDisplay display;
EGLSurface surface;
#ifdef  USE_PBUFFER
  display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
#else
 int fbnum = 0; // fbnum is an integer for /dev/fb0 fbnum = 0
 EGLNativeDisplayType native_display = fbGetDisplayByIndex(fbnum);
 EGLNativeWindowType native_window = fbCreateWindow(native_display, 0, 0, 0, 0);
 display = eglGetDisplay(native_display);
#endif  
if (display == EGL_NO_DISPLAY) {
 g_print("Unable to open connection to Window system: 0x%x\n",eglGetError());
 return 0; // <-- Point of failure, both with and without USE_PBUFFER set
}
// ...
if (!eglInitialize(display, &majorVersion, &minorVersion)) {
 g_print("Unable to initialize Display: 0x%x\n",eglGetError());
 return 0;
}
// ...
#ifdef USE_PBUFFER
  surface = eglCreatePbufferSurface(display, config, surfaceAttribList); 
#else
  surface = eglCreateWindowSurface(display, config, native_display, surfaceAttribList);
#endif

当前内核配置的提取,基于 3.14.28

# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_HDMI=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
CONFIG_FB_SYS_FILLRECT=m
CONFIG_FB_SYS_COPYAREA=m
CONFIG_FB_SYS_IMAGEBLIT=m
# CONFIG_FB_FOREIGN_ENDIAN is not set
CONFIG_FB_SYS_FOPS=m
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
#
# Frame buffer hardware drivers
#
# CONFIG_FB_IMX is not set
# CONFIG_FB_UVESA is not set
# CONFIG_FB_OPENCORES is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_TMIO is not set
# CONFIG_FB_SMSCUFX is not set
# CONFIG_FB_UDL is not set
# CONFIG_FB_GOLDFISH is not set
CONFIG_FB_VIRTUAL=m
# CONFIG_FB_METRONOME is not set
CONFIG_FB_MX3=y
# CONFIG_FB_BROADSHEET is not set
# CONFIG_FB_AUO_K190X is not set
# CONFIG_FB_MXS is not set
# CONFIG_FB_SIMPLE is not set
# CONFIG_EXYNOS_VIDEO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
CONFIG_FB_MXC=y
# CONFIG_FB_MXC_SYNC_PANEL is not set
CONFIG_FB_MXC_EDID=y
# CONFIG_FB_MXC_EINK_PANEL is not set

2015-09-24更新: 好吧,作为解决问题的第一步,我们将正确的 MXC 帧缓冲驱动程序添加到内核和设备树中,但我们仍然不断收到 EGL_BAD_ALLOC 错误(无论是否将 x11 和 wayland 添加到图像中).我们使用以下内核命令行:

[..] video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24 gpumem=64M fbmem=32M,32M [..]

此外,设备文件 /dev/fb0/dev/fb1 已正确创建并在 /sys/class/graphics/fb0 上输出。 fb1 看起来合理(即与我的台式电脑和氮气参考板相同)

好的,您 运行 遇到的问题是,您正试图打开一个 "native" 显示,它期望在某种显示设备上显示 运行 .显然,这不适用于无头系统。

由于您使用的是 EGL,因此您需要某种 "display" 特定版本的 EGL 知道如何与之交谈。但是,您删除了所有可以解决问题的内容 (DISTRO_FEATURES_remove = " x11 wayland")。事情是这样的:

你完全是 overthinking/overengineering 的全部;假设有适当的 Wayland 支持。

如果您可以使用 Wayland,而不是做 "render to FBO with texture/renderbuffer attached then glReadPixels" 舞蹈,您可以实现 VNC Wayland 系统合成器,即提供由 VNC(或您使用 RealVNC http://www.realvnc.com/products/vnc/wayland/ 的现有实现)。由于 Wayland 协议本身与 GPU 无关,这允许您的应用程序使用 GPU,而图形输出将通过作为合成器的 VNC 服务器重定向到 VNC 服务器。

根据 https://community.freescale.com/thread/375384,这是 3.14.28 内核和 imx6 处理器的 Vivante 库之间的兼容性问题。因此,解决方案是回到另一个内核版本。