Add QEGLContext::invalidateContext
QEGLContext::invalidateContext will mark that egl context is invalide and trigger SceneGraph to destroy it, create a new one and re-create and re-upload all resources (e.g. textures) associated with the current state of the SceneGraph In addition this change also improves QEglFSWindow::invalidateSurface() and QEglFSContext::eglSurfaceForPlatformSurface(..) Where QEglFSWindow::invalidateSurface() will now destroy the corresponding EGLSurface via eglDestroySurface, including "unbinding" it from the current thread via eglMakeCurrent and un-setting the screen's EGLSurface in case it's the same resource. QEglFSContext::eglSurfaceForPlatformSurface(..) will now call QEglFSWindow::resetSurface() in case of getting a EGL_NO_SURFACE from the QEglFSWindow (which happens if above invalidateSurface() was called before) - therefor re-creating the resource if it was destoyed via QEglFSWindow::invalidateSurface() Change-Id: I37badd1fc11e993c395fb1502e9bd27ebe18b821 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit 17a59f661398bf56aeaba4187f55d07eea09c578) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
013a05a937
commit
af85a5c965
@ -79,6 +79,8 @@ struct Q_GUI_EXPORT QEGLContext
|
|||||||
virtual EGLContext nativeContext() const = 0;
|
virtual EGLContext nativeContext() const = 0;
|
||||||
virtual EGLConfig config() const = 0;
|
virtual EGLConfig config() const = 0;
|
||||||
virtual EGLDisplay display() const = 0;
|
virtual EGLDisplay display() const = 0;
|
||||||
|
|
||||||
|
virtual void invalidateContext() = 0;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -69,12 +69,14 @@ public:
|
|||||||
|
|
||||||
QSurfaceFormat format() const override;
|
QSurfaceFormat format() const override;
|
||||||
bool isSharing() const override { return m_shareContext != EGL_NO_CONTEXT; }
|
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(); }
|
EGLContext nativeContext() const override { return eglContext(); }
|
||||||
EGLConfig config() const override { return eglConfig(); }
|
EGLConfig config() const override { return eglConfig(); }
|
||||||
EGLDisplay display() const override { return eglDisplay(); }
|
EGLDisplay display() const override { return eglDisplay(); }
|
||||||
|
|
||||||
|
virtual void invalidateContext() override { m_markedInvalid = true; }
|
||||||
|
|
||||||
EGLContext eglContext() const;
|
EGLContext eglContext() const;
|
||||||
EGLDisplay eglDisplay() const;
|
EGLDisplay eglDisplay() const;
|
||||||
EGLConfig eglConfig() const;
|
EGLConfig eglConfig() const;
|
||||||
@ -102,6 +104,8 @@ private:
|
|||||||
Flags m_flags;
|
Flags m_flags;
|
||||||
bool m_ownsContext = false;
|
bool m_ownsContext = false;
|
||||||
QList<EGLint> m_contextAttrs;
|
QList<EGLint> m_contextAttrs;
|
||||||
|
|
||||||
|
bool m_markedInvalid = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QEGLPlatformContext::Flags)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QEGLPlatformContext::Flags)
|
||||||
|
@ -123,6 +123,22 @@ QOpenGLContext *QNativeInterface::QGLXContext::fromNative(GLXContext visualBased
|
|||||||
\return the EGLDisplay associated with the underlying EGLContext.
|
\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_NATIVE_INTERFACE(QEGLContext);
|
||||||
QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QEGLIntegration);
|
QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QEGLIntegration);
|
||||||
|
|
||||||
|
@ -22,11 +22,20 @@ QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContex
|
|||||||
|
|
||||||
EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
||||||
{
|
{
|
||||||
if (surface->surface()->surfaceClass() == QSurface::Window)
|
if (surface->surface()->surfaceClass() == QSurface::Window) {
|
||||||
return static_cast<QEglFSWindow *>(surface)->surface();
|
|
||||||
else
|
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();
|
return static_cast<QEGLPbuffer *>(surface)->pbuffer();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EGLSurface QEglFSContext::createTemporaryOffscreenSurface()
|
EGLSurface QEglFSContext::createTemporaryOffscreenSurface()
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug)
|
||||||
|
|
||||||
QEglFSWindow::QEglFSWindow(QWindow *w)
|
QEglFSWindow::QEglFSWindow(QWindow *w)
|
||||||
: QPlatformWindow(w),
|
: QPlatformWindow(w),
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
@ -162,8 +164,29 @@ void QEglFSWindow::destroy()
|
|||||||
void QEglFSWindow::invalidateSurface()
|
void QEglFSWindow::invalidateSurface()
|
||||||
{
|
{
|
||||||
if (m_surface != EGL_NO_SURFACE) {
|
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_surface = EGL_NO_SURFACE;
|
||||||
|
m_flags = m_flags & ~Created;
|
||||||
}
|
}
|
||||||
qt_egl_device_integration()->destroyNativeWindow(m_window);
|
qt_egl_device_integration()->destroyNativeWindow(m_window);
|
||||||
m_window = 0;
|
m_window = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user