使用 Docker 使用 QOffscreenSurface 进行屏幕外渲染

Posted

技术标签:

【中文标题】使用 Docker 使用 QOffscreenSurface 进行屏幕外渲染【英文标题】:Offscreen render with QOffscreenSurface using Docker 【发布时间】:2020-03-03 21:13:27 【问题描述】:

我使用 Qt5 进行离屏渲染,在 Docker 中运行时出现分段错误。

我在c++ 中有代码,并通过python 使用pybind11 调用函数

这是导致段错误的代码

QSurfaceFormat glFormat;
glFormat.setVersion(3, 3);
glFormat.setProfile(QSurfaceFormat::CoreProfile);
glFormat.setRenderableType(QSurfaceFormat::OpenGL);

surface = new QOffscreenSurface();
surface->setFormat(glFormat);
surface->create(); // <-- Here 

确切的错误是:

QObject::connect: Cannot connect (null)::destroyed(QObject*) to QOffscreenSurface::screenDestroyed(QObject*) 

我尝试通过xvfb-run -a python prg.py 运行它并得到同样的错误

任何调试这个的指针?

关于这个问题的更多上下文,如果我在包裹在QApplication 中的主线程中使用上面的代码,它可以正常工作。仅当我将其移动到函数中时才会出现此问题,以便我可以在 python 中调用它。

【问题讨论】:

提供minimal reproducible example 【参考方案1】:

关于在主线程之外运行的最后一条线索可能是您遇到的问题。

查看文档https://doc.qt.io/qt-5/qoffscreensurface.html#details:

注意:由于 QOffscreenSurface 由 QWindow 支持 某些平台,跨平台应用程序必须确保 create() 仅在主(GUI)线程上调用。 QOffscreenSurface 然后是 在其他线程上与 makeCurrent() 一起使用是安全的,但是 初始化和销毁​​必须始终在主(GUI)上进行 线程。

因此解决方案可能是在主线程中创建表面,然后通过 pybind11 像您需要的那样使用它。

【讨论】:

我没有 GUI 线程。关于如何使用 pybind11 调用创建它的任何指示? GUI 线程只是应用程序的主线程。你应该在那里创建你的表面,然后如果你想从另一个线程中使用它,调用bool QOpenGLContext::makeCurrent(QSurface *surface) 但是在使用 pybind 时,我只是链接到一个函数调用,例如在 python 中 import myPackage as p p.myFunction() 我在调用表面之前在我的 pybind 函数中调用了 QApplication 并使用 xvfb 运行它以使 ti 工作。

以上是关于使用 Docker 使用 QOffscreenSurface 进行屏幕外渲染的主要内容,如果未能解决你的问题,请参考以下文章

使用 docker 如何使用 docker run 将文件从 docker 复制到主机 [重复]

WSL上使用docker遇到问题解决

安装使用NVIDIA-Docker-- 可使用GPU的Docker容器

[Docker] docker-compose使用教程

docker运行Spring Cloud使用外部IP

Docker基本使用命令