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 EGLConfig config() const = 0;
|
||||
virtual EGLDisplay display() const = 0;
|
||||
|
||||
virtual void invalidateContext() = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user