diff options
-rw-r--r-- | src/gui/kernel/qopenglcontext_platform.h | 2 | ||||
-rw-r--r-- | src/gui/opengl/platform/egl/qeglplatformcontext_p.h | 6 | ||||
-rw-r--r-- | src/gui/platform/unix/qunixnativeinterface.cpp | 16 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/api/qeglfscontext.cpp | 15 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/api/qeglfswindow.cpp | 25 |
5 files changed, 59 insertions, 5 deletions
diff --git a/src/gui/kernel/qopenglcontext_platform.h b/src/gui/kernel/qopenglcontext_platform.h index fe36478a65..1f84cf6ce3 100644 --- a/src/gui/kernel/qopenglcontext_platform.h +++ b/src/gui/kernel/qopenglcontext_platform.h @@ -79,6 +79,8 @@ struct Q_GUI_EXPORT QEGLContext virtual EGLContext nativeContext() const = 0; virtual EGLConfig config() const = 0; virtual EGLDisplay display() const = 0; + + virtual void invalidateContext() = 0; }; #endif diff --git a/src/gui/opengl/platform/egl/qeglplatformcontext_p.h b/src/gui/opengl/platform/egl/qeglplatformcontext_p.h index 556fbabee4..b1e9c4b4c2 100644 --- a/src/gui/opengl/platform/egl/qeglplatformcontext_p.h +++ b/src/gui/opengl/platform/egl/qeglplatformcontext_p.h @@ -69,12 +69,14 @@ public: QSurfaceFormat format() const override; bool isSharing() const override { return m_shareContext != EGL_NO_CONTEXT; } - bool isValid() const override { return m_eglContext != EGL_NO_CONTEXT; } + bool isValid() const override { return m_eglContext != EGL_NO_CONTEXT && !m_markedInvalid; } EGLContext nativeContext() const override { return eglContext(); } EGLConfig config() const override { return eglConfig(); } EGLDisplay display() const override { return eglDisplay(); } + virtual void invalidateContext() override { m_markedInvalid = true; } + EGLContext eglContext() const; EGLDisplay eglDisplay() const; EGLConfig eglConfig() const; @@ -102,6 +104,8 @@ private: Flags m_flags; bool m_ownsContext = false; QList<EGLint> m_contextAttrs; + + bool m_markedInvalid = false; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QEGLPlatformContext::Flags) diff --git a/src/gui/platform/unix/qunixnativeinterface.cpp b/src/gui/platform/unix/qunixnativeinterface.cpp index 1cca97b34c..1f891de0f5 100644 --- a/src/gui/platform/unix/qunixnativeinterface.cpp +++ b/src/gui/platform/unix/qunixnativeinterface.cpp @@ -123,6 +123,22 @@ QOpenGLContext *QNativeInterface::QGLXContext::fromNative(GLXContext visualBased \return the EGLDisplay associated with the underlying EGLContext. */ + +/*! + \fn void QNativeInterface::QEGLContext::invalidateContext() + \since 6.5 + \brief Marks the context as invalid + + If this context is used by the Qt Quick scenegraph, this will trigger the + SceneGraph to destroy this context and create a new one. + + Similarly to QPlatformWindow::invalidateSurface(), + this function can only be expected to have an effect on certain platforms, + such as eglfs. + + \sa QOpenGLContext::isValid(), QPlatformWindow::invalidateSurface() +*/ + QT_DEFINE_NATIVE_INTERFACE(QEGLContext); QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QEGLIntegration); diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp index a17b567b24..9c10c1a998 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp @@ -22,10 +22,19 @@ QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContex EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) { - if (surface->surface()->surfaceClass() == QSurface::Window) - return static_cast<QEglFSWindow *>(surface)->surface(); - else + if (surface->surface()->surfaceClass() == QSurface::Window) { + + QEglFSWindow *w = static_cast<QEglFSWindow *>(surface); + EGLSurface s = w->surface(); + if (s == EGL_NO_SURFACE) { + w->resetSurface(); + s = w->surface(); + } + return s; + + } else { return static_cast<QEGLPbuffer *>(surface)->pbuffer(); + } } EGLSurface QEglFSContext::createTemporaryOffscreenSurface() diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp index bbd0b8ed68..1a31f97d7b 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -22,6 +22,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug) + QEglFSWindow::QEglFSWindow(QWindow *w) : QPlatformWindow(w), #ifndef QT_NO_OPENGL @@ -162,8 +164,29 @@ void QEglFSWindow::destroy() void QEglFSWindow::invalidateSurface() { if (m_surface != EGL_NO_SURFACE) { - eglDestroySurface(screen()->display(), m_surface); + qCDebug(qLcEglDevDebug) << Q_FUNC_INFO << " about to destroy EGLSurface: " << m_surface; + + bool ok = eglDestroySurface(screen()->display(), m_surface); + + if (!ok) { + qCWarning(qLcEglDevDebug, "QEglFSWindow::invalidateSurface() eglDestroySurface failed!" + " Follow-up errors or memory leaks are possible." + " eglGetError(): %x", eglGetError()); + } + + if (eglGetCurrentSurface(EGL_READ) == m_surface || + eglGetCurrentSurface(EGL_DRAW) == m_surface) { + bool ok = eglMakeCurrent(eglGetCurrentDisplay(), EGL_NO_DISPLAY, EGL_NO_DISPLAY, EGL_NO_CONTEXT); + qCDebug(qLcEglDevDebug) << Q_FUNC_INFO << " due to eglDestroySurface on *currently* bound surface" + << "we just called eglMakeCurrent(..,0,0,0)! It returned: " << ok; + } + + if (screen()->primarySurface() == m_surface) + screen()->setPrimarySurface(EGL_NO_SURFACE); + + m_surface = EGL_NO_SURFACE; + m_flags = m_flags & ~Created; } qt_egl_device_integration()->destroyNativeWindow(m_window); m_window = 0; |