summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qoffscreensurface.cpp7
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer.cpp6
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp24
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)) ()