7#include <QOpenGLContext>
12#include <QtGui/private/qglxconvenience_p.h>
14#include <qpa/qplatformsurface.h>
19class QOffscreenX11Info
22 QOffscreenX11Info(QOffscreenX11Connection *connection)
23 : m_connection(connection)
27 Display *display()
const {
28 return (Display *)m_connection->display();
32 return DefaultRootWindow(display());
35 int screenNumber()
const {
36 return m_connection->screenNumber();
40 QOffscreenX11Connection *m_connection;
54 case OpenGL:
return true;
55 case ThreadedOpenGL:
return true;
56 default:
return QOffscreenIntegration::hasCapability(cap);
60#if !defined(QT_NO_OPENGL) && QT_CONFIG(xcb_glx_plugin)
61QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QOpenGLContext *context)
const
63 auto &connection = nativeInterface()->m_connection;
66 connection.reset(
new QOffscreenX11Connection);
68 if (!connection->display())
71 return new QOffscreenX11GLXContext(connection->x11Info(), context);
77 if (!m_nativeInterface)
78 m_nativeInterface.reset(
new QOffscreenX11PlatformNativeInterface(
const_cast<QOffscreenX11Integration *>(
this)));
79 return static_cast<QOffscreenX11PlatformNativeInterface *>(m_nativeInterface.data());
93 if (resource.toLower() == QByteArrayLiteral(
"display") ) {
95 m_connection.reset(
new QOffscreenX11Connection);
96 return m_connection->display();
101#if !defined(QT_NO_OPENGL) && QT_CONFIG(xcb_glx_plugin)
102void *QOffscreenX11PlatformNativeInterface::nativeResourceForContext(
const QByteArray &resource, QOpenGLContext *context) {
103 if (resource.toLower() == QByteArrayLiteral(
"glxconfig") ) {
105 QOffscreenX11GLXContext *glxPlatformContext =
static_cast<QOffscreenX11GLXContext *>(context->handle());
106 if (glxPlatformContext)
107 return glxPlatformContext->glxConfig();
110 if (resource.toLower() == QByteArrayLiteral(
"glxcontext") ) {
112 QOffscreenX11GLXContext *glxPlatformContext =
static_cast<QOffscreenX11GLXContext *>(context->handle());
113 if (glxPlatformContext)
114 return glxPlatformContext->glxContext();
122Display *QOffscreenX11PlatformNativeInterface::display()
const
124 return m_connection ?
reinterpret_cast<Display *>(m_connection->display()) :
nullptr;
132 QByteArray displayName = qgetenv(
"DISPLAY");
133 Display *display = XOpenDisplay(displayName.constData());
135 m_screenNumber = m_display ? DefaultScreen(m_display) : -1;
141 XCloseDisplay((Display *)m_display);
147 m_x11Info.reset(
new QOffscreenX11Info(
this));
148 return m_x11Info.data();
151#if QT_CONFIG(xcb_glx_plugin)
152class QOffscreenX11GLXContextData
155 QOffscreenX11Info *x11 =
nullptr;
156 QSurfaceFormat format;
157 GLXContext context =
nullptr;
158 GLXContext shareContext =
nullptr;
159 GLXFBConfig config =
nullptr;
163static Window createDummyWindow(QOffscreenX11Info *x11, XVisualInfo *visualInfo)
165 Colormap cmap = XCreateColormap(x11->display(), x11->root(), visualInfo->visual, AllocNone);
166 XSetWindowAttributes a;
167 a.background_pixel = WhitePixel(x11->display(), x11->screenNumber());
168 a.border_pixel = BlackPixel(x11->display(), x11->screenNumber());
172 Window window = XCreateWindow(x11->display(), x11->root(),
174 0, visualInfo->depth, InputOutput, visualInfo->visual,
175 CWBackPixel|CWBorderPixel|CWColormap, &a);
176 XFreeColormap(x11->display(), cmap);
180static Window createDummyWindow(QOffscreenX11Info *x11, GLXFBConfig config)
182 XVisualInfo *visualInfo = glXGetVisualFromFBConfig(x11->display(), config);
183 if (Q_UNLIKELY(!visualInfo))
184 qFatal(
"Could not initialize GLX");
185 Window window = createDummyWindow(x11, visualInfo);
190QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context)
191 : d(
new QOffscreenX11GLXContextData)
195 d->format = context->format();
197 if (d->format.renderableType() == QSurfaceFormat::DefaultRenderableType)
198 d->format.setRenderableType(QSurfaceFormat::OpenGL);
200 if (d->format.renderableType() != QSurfaceFormat::OpenGL)
203 d->shareContext =
nullptr;
204 if (context->shareHandle())
205 d->shareContext =
static_cast<QOffscreenX11GLXContext *>(context->shareHandle())->d->context;
207 GLXFBConfig config = qglx_findConfig(x11->display(), x11->screenNumber(), d->format);
211 d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, d->shareContext,
true);
212 if (!d->context && d->shareContext) {
213 d->shareContext =
nullptr;
215 d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE,
nullptr,
true);
220 qglx_surfaceFormatFromGLXFBConfig(&d->format, x11->display(), config);
223 d->window = createDummyWindow(x11, config);
225 XVisualInfo *visualInfo = qglx_findVisualInfo(x11->display(), 0, &d->format);
226 if (Q_UNLIKELY(!visualInfo))
227 qFatal(
"Could not initialize GLX");
228 d->context = glXCreateContext(x11->display(), visualInfo, d->shareContext,
true);
229 if (!d->context && d->shareContext) {
231 d->shareContext =
nullptr;
232 d->context = glXCreateContext(x11->display(), visualInfo,
nullptr,
true);
235 d->window = createDummyWindow(x11, visualInfo);
240QOffscreenX11GLXContext::~QOffscreenX11GLXContext()
242 glXDestroyContext(d->x11->display(), d->context);
243 XDestroyWindow(d->x11->display(), d->window);
246bool QOffscreenX11GLXContext::makeCurrent(QPlatformSurface *surface)
248 QSize size = surface->surface()->size();
250 XResizeWindow(d->x11->display(), d->window, size.width(), size.height());
251 XSync(d->x11->display(),
true);
253 if (glXMakeCurrent(d->x11->display(), d->window, d->context)) {
254 glViewport(0, 0, size.width(), size.height());
261void QOffscreenX11GLXContext::doneCurrent()
263 glXMakeCurrent(d->x11->display(), 0,
nullptr);
266void QOffscreenX11GLXContext::swapBuffers(QPlatformSurface *)
270QFunctionPointer QOffscreenX11GLXContext::getProcAddress(
const char *procName)
272 return (QFunctionPointer)glXGetProcAddressARB(
reinterpret_cast<
const GLubyte *>(procName));
275QSurfaceFormat QOffscreenX11GLXContext::format()
const
280bool QOffscreenX11GLXContext::isSharing()
const
282 return d->shareContext;
285bool QOffscreenX11GLXContext::isValid()
const
287 return d->context && d->window;
290GLXContext QOffscreenX11GLXContext::glxContext()
const
295void *QOffscreenX11GLXContext::glxConfig()
const
~QOffscreenX11Connection()
QOffscreenX11Connection()
QOffscreenX11Info * x11Info()
bool hasCapability(QPlatformIntegration::Capability cap) const override
QOffscreenX11PlatformNativeInterface * nativeInterface() const override
QOffscreenX11Integration(const QStringList ¶mList)
~QOffscreenX11Integration()