Внеэкранный рендеринг с QOffscreenSurface с использованием Docker

Я использую Qt5 для рендеринга за пределами экрана и имею ошибку сегментации при работе внутри Docker.

У меня есть код внутри c++ и вызов функции через python с использованием pybind11

Это код, вызывающий segfault

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.


person Pavan K    schedule 03.03.2020    source источник
comment
предоставьте минимальный воспроизводимый пример   -  person eyllanesc    schedule 04.03.2020


Ответы (1)


Ваша последняя подсказка о работе вне основного потока, вероятно, является проблемой, с которой вы столкнулись.

Глядя на документы https://doc.qt.io/qt-5/qoffscreensurface.html#details:

Примечание. Из-за того, что QOffscreenSurface поддерживается QWindow на некоторых платформах, кросс-платформенные приложения должны гарантировать, что create() вызывается только в основном (GUI) потоке. После этого QOffscreenSurface можно безопасно использовать с makeCurrent() в других потоках, но инициализация и уничтожение всегда должны происходить в основном (GUI) потоке.

Таким образом, решение, вероятно, будет состоять в том, чтобы создать поверхность в основном потоке, а затем просто использовать ее, как вам нужно, через pybind11.

person SigSegOwl    schedule 04.03.2020
comment
У меня нет потока графического интерфейса. Любые указатели на то, как создать это с помощью вызовов pybind11? - person Pavan K; 05.03.2020
comment
Поток GUI — это просто основной поток вашего приложения. Вы должны создать свою поверхность там, а затем, если вы хотите использовать ее из другого потока, вызовите bool QOpenGLContext::makeCurrent(QSurface *surface). - person SigSegOwl; 06.03.2020
comment
Но при использовании pybind я просто связываюсь с вызовом функции, например, в python import myPackage as p p.myFunction() - person Pavan K; 06.03.2020
comment
Я вызвал QApplication внутри моей функции pybind, прежде чем вызывать поверхность, и запустил ее с помощью xvfb, чтобы заставить ее работать. - person Pavan K; 18.03.2020