diff options
11 files changed, 73 insertions, 34 deletions
diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h index 59441d8c9a..ec6f668cba 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h @@ -88,7 +88,6 @@ public: protected: virtual bool filterConfig(EGLConfig config) const; -private: QSurfaceFormat m_format; EGLDisplay m_display; EGLint m_surfaceType; diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp index 756609a641..d1a31642b2 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp +++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp @@ -49,13 +49,15 @@ QT_BEGIN_NAMESPACE and return a new instance of this class. */ -QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface) +QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface, + QEGLPlatformContext::Flags flags) : QPlatformOffscreenSurface(offscreenSurface) , m_format(format) , m_display(display) , m_pbuffer(EGL_NO_SURFACE) { - bool hasSurfaceless = q_hasEglExtension(display, "EGL_KHR_surfaceless_context"); + bool hasSurfaceless = !flags.testFlag(QEGLPlatformContext::NoSurfaceless) + && q_hasEglExtension(display, "EGL_KHR_surfaceless_context"); // Disable surfaceless contexts on Mesa for now. As of 10.6.0 and Intel at least, some // operations (glReadPixels) are unable to work without a surface since they at some diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h index 3372c0735d..81fdab8901 100644 --- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h +++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h @@ -47,13 +47,15 @@ #include <EGL/egl.h> #include <qpa/qplatformoffscreensurface.h> +#include <QtPlatformSupport/private/qeglplatformcontext_p.h> QT_BEGIN_NAMESPACE class QEGLPbuffer : public QPlatformOffscreenSurface { public: - QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface); + QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface, + QEGLPlatformContext::Flags flags = 0); ~QEGLPbuffer(); QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; } diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index 2de7fb3b40..acd6197ed5 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -106,11 +106,12 @@ QT_BEGIN_NAMESPACE #endif QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLConfig *config, const QVariant &nativeHandle) + EGLConfig *config, const QVariant &nativeHandle, Flags flags) : m_eglDisplay(display) , m_swapInterval(-1) , m_swapIntervalEnvChecked(false) , m_swapIntervalFromEnv(-1) + , m_flags(flags) { if (nativeHandle.isNull()) { m_eglConfig = config ? *config : q_configFromGLFormat(display, format); @@ -291,7 +292,7 @@ void QEGLPlatformContext::updateFormatFromGL() // drivers (Mesa) when certain attributes are present (multisampling). EGLSurface tempSurface = EGL_NO_SURFACE; EGLContext tempContext = EGL_NO_CONTEXT; - if (!q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) + if (m_flags.testFlag(NoSurfaceless) || !q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) tempSurface = createTemporaryOffscreenSurface(); EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext); diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index 2ab7ad28d0..2fa465556b 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -56,8 +56,14 @@ QT_BEGIN_NAMESPACE class QEGLPlatformContext : public QPlatformOpenGLContext { public: + enum Flag { + NoSurfaceless = 0x01 + }; + Q_DECLARE_FLAGS(Flags, Flag) + QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLConfig *config = 0, const QVariant &nativeHandle = QVariant()); + EGLConfig *config = 0, const QVariant &nativeHandle = QVariant(), + Flags flags = 0); ~QEGLPlatformContext(); void initialize() Q_DECL_OVERRIDE; @@ -93,10 +99,13 @@ private: int m_swapInterval; bool m_swapIntervalEnvChecked; int m_swapIntervalFromEnv; + Flags m_flags; bool m_ownsContext; QVector<EGLint> m_contextAttrs; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QEGLPlatformContext::Flags) + QT_END_NAMESPACE #endif //QEGLPLATFORMCONTEXT_H diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index e2223aba43..6fcdae7ad2 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -44,7 +44,8 @@ QT_BEGIN_NAMESPACE QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLConfig *config, const QVariant &nativeHandle) - : QEGLPlatformContext(format, share, display, config, nativeHandle), + : QEGLPlatformContext(format, share, display, config, nativeHandle, + qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags(0) : QEGLPlatformContext::NoSurfaceless), m_tempWindow(0) { } diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index d27c949c8d..0c2aa7ad61 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -34,6 +34,7 @@ #include "qeglfsdeviceintegration.h" #include "qeglfsintegration.h" #include "qeglfscursor.h" +#include "qeglfswindow.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QGuiApplication> #include <private/qguiapplication_p.h> @@ -175,6 +176,11 @@ EGLNativeDisplayType QEGLDeviceIntegration::platformDisplay() const return EGL_DEFAULT_DISPLAY; } +EGLDisplay QEGLDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) +{ + return eglGetDisplay(nativeDisplay); +} + bool QEGLDeviceIntegration::usesDefaultScreen() { return true; @@ -238,6 +244,11 @@ qreal QEGLDeviceIntegration::refreshRate() const return q_refreshRateFromFb(framebuffer); } +EGLint QEGLDeviceIntegration::surfaceType() const +{ + return EGL_WINDOW_BIT; +} + QSurfaceFormat QEGLDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const { QSurfaceFormat format = inputFormat; @@ -257,6 +268,11 @@ bool QEGLDeviceIntegration::filterConfig(EGLDisplay, EGLConfig) const return true; } +QEglFSWindow *QEGLDeviceIntegration::createWindow(QWindow *window) const +{ + return new QEglFSWindow(window); +} + EGLNativeWindowType QEGLDeviceIntegration::createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format) @@ -313,4 +329,9 @@ bool QEGLDeviceIntegration::supportsPBuffers() const return true; } +bool QEGLDeviceIntegration::supportsSurfacelessContexts() const +{ + return true; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index 260fc313f7..d91d67de16 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE class QPlatformSurface; +class QEglFSWindow; #define QEGLDeviceIntegrationFactoryInterface_iid "org.qt-project.qt.qpa.egl.QEGLDeviceIntegrationFactoryInterface.5.5" @@ -67,6 +68,7 @@ public: virtual void platformInit(); virtual void platformDestroy(); virtual EGLNativeDisplayType platformDisplay() const; + virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay); virtual bool usesDefaultScreen(); virtual void screenInit(); virtual void screenDestroy(); @@ -79,6 +81,8 @@ public: virtual QImage::Format screenFormat() const; virtual qreal refreshRate() const; virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; + virtual EGLint surfaceType() const; + virtual QEglFSWindow *createWindow(QWindow *window) const; virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format); @@ -92,6 +96,7 @@ public: virtual QByteArray fbDeviceName() const; virtual int framebufferIndex() const; virtual bool supportsPBuffers() const; + virtual bool supportsSurfacelessContexts() const; }; class Q_EGLFS_EXPORT QEGLDeviceIntegrationPlugin : public QObject diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index f0946b9b64..2df06caa6b 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -117,7 +117,7 @@ void QEglFSIntegration::initialize() { qt_egl_device_integration()->platformInit(); - m_display = eglGetDisplay(nativeDisplay()); + m_display = qt_egl_device_integration()->createDisplay(nativeDisplay()); if (m_display == EGL_NO_DISPLAY) qFatal("Could not open egl display"); @@ -179,7 +179,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const { QWindowSystemInterface::flushWindowSystemEvents(); - QEglFSWindow *w = new QEglFSWindow(window); + QEglFSWindow *w = qt_egl_device_integration()->createWindow(window); w->create(); if (window->type() != Qt::ToolTip) w->requestActivateWindow(); @@ -213,10 +213,14 @@ QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOf { EGLDisplay dpy = surface->screen() ? static_cast<QEglFSScreen *>(surface->screen()->handle())->display() : display(); QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(surface->requestedFormat()); - if (qt_egl_device_integration()->supportsPBuffers()) - return new QEGLPbuffer(dpy, fmt, surface); - else + if (qt_egl_device_integration()->supportsPBuffers()) { + QEGLPlatformContext::Flags flags = 0; + if (!qt_egl_device_integration()->supportsSurfacelessContexts()) + flags |= QEGLPlatformContext::NoSurfaceless; + return new QEGLPbuffer(dpy, fmt, surface, flags); + } else { return new QEglFSOffscreenWindow(dpy, fmt, surface); + } // Never return null. Multiple QWindows are not supported by this plugin. } @@ -433,6 +437,7 @@ EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceForm }; Chooser chooser(display); + chooser.setSurfaceType(qt_egl_device_integration()->surfaceType()); chooser.setSurfaceFormat(format); return chooser.chooseConfig(); } diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index c3b9dd6ef0..8301be8c17 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -51,7 +51,7 @@ QEglFSWindow::QEglFSWindow(QWindow *w) m_backingStore(0), m_raster(false), m_winId(0), - m_surface(0), + m_surface(EGL_NO_SURFACE), m_window(0), m_flags(0) { @@ -120,13 +120,14 @@ void QEglFSWindow::create() setGeometry(QRect()); // will become fullscreen QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); - EGLDisplay display = static_cast<QEglFSScreen *>(screen)->display(); - QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat()); - m_config = QEglFSIntegration::chooseConfig(display, platformFormat); - m_format = q_glFormatFromConfig(display, m_config, platformFormat); - resetSurface(); + if (m_surface == EGL_NO_SURFACE) { + EGLint error = eglGetError(); + eglTerminate(screen->display()); + qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); + } + screen->setPrimarySurface(m_surface); if (isRaster()) { @@ -158,15 +159,10 @@ void QEglFSWindow::destroy() QOpenGLCompositor::instance()->removeWindow(this); } -// The virtual functions resetSurface and invalidateSurface may get overridden -// in derived classes, for example in the Android port, to perform the native -// window and surface creation differently. - void QEglFSWindow::invalidateSurface() { if (m_surface != EGL_NO_SURFACE) { - EGLDisplay display = static_cast<QEglFSScreen *>(screen())->display(); - eglDestroySurface(display, m_surface); + eglDestroySurface(screen()->display(), m_surface); m_surface = EGL_NO_SURFACE; } qt_egl_device_integration()->destroyNativeWindow(m_window); @@ -175,15 +171,13 @@ void QEglFSWindow::invalidateSurface() void QEglFSWindow::resetSurface() { - QEglFSScreen *nativeScreen = static_cast<QEglFSScreen *>(screen()); - EGLDisplay display = nativeScreen->display(); - m_window = qt_egl_device_integration()->createNativeWindow(this, nativeScreen->geometry().size(), m_format); + EGLDisplay display = screen()->display(); + QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat()); + + m_config = QEglFSIntegration::chooseConfig(display, platformFormat); + m_format = q_glFormatFromConfig(display, m_config, platformFormat); + m_window = qt_egl_device_integration()->createNativeWindow(this, screen()->geometry().size(), m_format); m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL); - if (m_surface == EGL_NO_SURFACE) { - EGLint error = eglGetError(); - eglTerminate(display); - qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); - } } void QEglFSWindow::setVisible(bool visible) diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 53b9e18dc1..806b21de0a 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -89,7 +89,7 @@ public: const QPlatformTextureList *textures() const Q_DECL_OVERRIDE; void endCompositing() Q_DECL_OVERRIDE; -private: +protected: QOpenGLCompositorBackingStore *m_backingStore; bool m_raster; WId m_winId; |