diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qoffscreensurface.cpp | 7 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglpbuffer.cpp | 6 | ||||
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformcontext.cpp | 24 |
3 files changed, 29 insertions, 8 deletions
diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp index fb1dfd8df5..ed1b8d944a 100644 --- a/src/gui/kernel/qoffscreensurface.cpp +++ b/src/gui/kernel/qoffscreensurface.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE QOffscreenSurface is intended to be used with QOpenGLContext to allow rendering with OpenGL in an arbitrary thread without the need to create a QWindow. - Even though the surface is renderable, the surface's pixels are not accessible. + Even though the surface is typically renderable, the surface's pixels are not accessible. QOffscreenSurface should only be used to create OpenGL resources such as textures or framebuffer objects. @@ -77,6 +77,11 @@ QT_BEGIN_NAMESPACE created}. Passing the format returned from QWindow::requestedFormat() to setFormat() may result in an incompatible offscreen surface since the underlying windowing system interface may offer a different set of configurations for window and pbuffer surfaces. + + \note Some platforms may utilize a surfaceless context extension (for example + EGL_KHR_surfaceless_context) when available. In this case there will be no underlying + native surface. For the use cases of QOffscreenSurface (rendering to FBOs, texture + upload) this is not a problem. */ class Q_GUI_EXPORT QOffscreenSurfacePrivate : public QObjectPrivate { diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp index 2c6c332ac9..89f06ee3a9 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp +++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp @@ -55,6 +55,9 @@ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffs , m_display(display) , m_pbuffer(EGL_NO_SURFACE) { + if (q_hasEglExtension(display, "EGL_KHR_surfaceless_context")) + return; + EGLConfig config = q_configFromGLFormat(m_display, m_format, false, EGL_PBUFFER_BIT); if (config) { @@ -74,7 +77,8 @@ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffs QEGLPbuffer::~QEGLPbuffer() { - eglDestroySurface(m_display, m_pbuffer); + if (m_pbuffer != EGL_NO_SURFACE) + eglDestroySurface(m_display, m_pbuffer); } QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index d7c4fd6764..984abe123f 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -278,7 +278,13 @@ void QEGLPlatformContext::updateFormatFromGL() EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW); EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ); - EGLSurface tempSurface = createTemporaryOffscreenSurface(); + // Rely on the surfaceless extension, if available. This is beneficial since we can + // avoid creating an extra pbuffer surface which is apparently troublesome with some + // drivers (Mesa) when certain attributes are present (multisampling). + EGLSurface tempSurface = EGL_NO_SURFACE; + if (!q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) + tempSurface = createTemporaryOffscreenSurface(); + if (eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext)) { if (m_format.renderableType() == QSurfaceFormat::OpenGL || m_format.renderableType() == QSurfaceFormat::OpenGLES) { @@ -316,8 +322,11 @@ void QEGLPlatformContext::updateFormatFromGL() } } eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); + } else { + qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated"); } - destroyTemporaryOffscreenSurface(tempSurface); + if (tempSurface != EGL_NO_SURFACE) + destroyTemporaryOffscreenSurface(tempSurface); #endif // QT_NO_OPENGL } @@ -354,7 +363,8 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface) : surface->format().swapInterval(); if (requestedSwapInterval >= 0 && m_swapInterval != requestedSwapInterval) { m_swapInterval = requestedSwapInterval; - eglSwapInterval(eglDisplay(), m_swapInterval); + if (eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context + eglSwapInterval(eglDisplay(), m_swapInterval); } } else { qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); @@ -383,9 +393,11 @@ void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface) { eglBindAPI(m_api); EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface); - bool ok = eglSwapBuffers(m_eglDisplay, eglSurface); - if (!ok) - qWarning("QEGLPlatformContext: eglSwapBuffers failed: %x", eglGetError()); + if (eglSurface != EGL_NO_SURFACE) { // skip if using surfaceless context + bool ok = eglSwapBuffers(m_eglDisplay, eglSurface); + if (!ok) + qWarning("QEGLPlatformContext: eglSwapBuffers failed: %x", eglGetError()); + } } void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) () |