Enhance EGL_CONTEXT_LOST checks
Apparently failures can occur not just when doing eglMakeCurrent() but also when creating window surfaces. Change-Id: Ife1210293d5120fd41352164d9c89e83fb5ce468 Reviewed-by: Michael Brüning <michael.bruning@theqtcompany.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
This commit is contained in:
parent
f29007b1d5
commit
367a91d278
@ -416,12 +416,15 @@ QWindowsOpenGLContext *QWindowsEGLStaticContext::createContext(QOpenGLContext *c
|
|||||||
return new QWindowsEGLContext(this, context->format(), context->shareHandle());
|
return new QWindowsEGLContext(this, context->format(), context->shareHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig)
|
void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig, int *err)
|
||||||
{
|
{
|
||||||
|
*err = 0;
|
||||||
EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, (EGLConfig) nativeConfig,
|
EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, (EGLConfig) nativeConfig,
|
||||||
(EGLNativeWindowType) nativeWindow, 0);
|
(EGLNativeWindowType) nativeWindow, 0);
|
||||||
if (surface == EGL_NO_SURFACE)
|
if (surface == EGL_NO_SURFACE) {
|
||||||
qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, libEGL.eglGetError());
|
*err = libEGL.eglGetError();
|
||||||
|
qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, *err);
|
||||||
|
}
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
@ -578,8 +581,15 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
|
|||||||
|
|
||||||
QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
|
QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
|
||||||
window->aboutToMakeCurrent();
|
window->aboutToMakeCurrent();
|
||||||
EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig));
|
int err = 0;
|
||||||
Q_ASSERT(eglSurface);
|
EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err));
|
||||||
|
if (eglSurface == EGL_NO_SURFACE) {
|
||||||
|
if (err == EGL_CONTEXT_LOST) {
|
||||||
|
m_eglContext = EGL_NO_CONTEXT;
|
||||||
|
qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// shortcut: on some GPUs, eglMakeCurrent is not a cheap operation
|
// shortcut: on some GPUs, eglMakeCurrent is not a cheap operation
|
||||||
if (QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() == m_eglContext &&
|
if (QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() == m_eglContext &&
|
||||||
@ -597,7 +607,7 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
|
|||||||
QWindowsEGLStaticContext::libEGL.eglSwapInterval(m_staticContext->display(), m_swapInterval);
|
QWindowsEGLStaticContext::libEGL.eglSwapInterval(m_staticContext->display(), m_swapInterval);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int err = QWindowsEGLStaticContext::libEGL.eglGetError();
|
err = QWindowsEGLStaticContext::libEGL.eglGetError();
|
||||||
// EGL_CONTEXT_LOST (loss of the D3D device) is not necessarily fatal.
|
// EGL_CONTEXT_LOST (loss of the D3D device) is not necessarily fatal.
|
||||||
// Qt Quick is able to recover for example.
|
// Qt Quick is able to recover for example.
|
||||||
if (err == EGL_CONTEXT_LOST) {
|
if (err == EGL_CONTEXT_LOST) {
|
||||||
@ -625,8 +635,15 @@ void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface)
|
|||||||
{
|
{
|
||||||
QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
|
QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
|
||||||
QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
|
QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
|
||||||
EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig));
|
int err = 0;
|
||||||
Q_ASSERT(eglSurface);
|
EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err));
|
||||||
|
if (eglSurface == EGL_NO_SURFACE) {
|
||||||
|
if (err == EGL_CONTEXT_LOST) {
|
||||||
|
m_eglContext = EGL_NO_CONTEXT;
|
||||||
|
qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface);
|
bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
|
@ -260,7 +260,7 @@ public:
|
|||||||
void *moduleHandle() const { return libGLESv2.moduleHandle(); }
|
void *moduleHandle() const { return libGLESv2.moduleHandle(); }
|
||||||
QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGLES; }
|
QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGLES; }
|
||||||
|
|
||||||
void *createWindowSurface(void *nativeWindow, void *nativeConfig) Q_DECL_OVERRIDE;
|
void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE;
|
||||||
void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE;
|
void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat);
|
QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat);
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
|
|
||||||
// If the windowing system interface needs explicitly created window surfaces (like EGL),
|
// If the windowing system interface needs explicitly created window surfaces (like EGL),
|
||||||
// reimplement these.
|
// reimplement these.
|
||||||
virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; }
|
virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, int * /*err*/) { return 0; }
|
||||||
virtual void destroyWindowSurface(void * /*nativeSurface*/) { }
|
virtual void destroyWindowSurface(void * /*nativeSurface*/) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -2259,14 +2259,14 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *QWindowsWindow::surface(void *nativeConfig)
|
void *QWindowsWindow::surface(void *nativeConfig, int *err)
|
||||||
{
|
{
|
||||||
#ifdef QT_NO_OPENGL
|
#ifdef QT_NO_OPENGL
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
if (!m_surface) {
|
if (!m_surface) {
|
||||||
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
|
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
|
||||||
m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig);
|
m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_surface;
|
return m_surface;
|
||||||
|
@ -248,7 +248,7 @@ public:
|
|||||||
bool isEnabled() const;
|
bool isEnabled() const;
|
||||||
void setWindowIcon(const QIcon &icon);
|
void setWindowIcon(const QIcon &icon);
|
||||||
|
|
||||||
void *surface(void *nativeConfig);
|
void *surface(void *nativeConfig, int *err);
|
||||||
void invalidateSurface() Q_DECL_OVERRIDE;
|
void invalidateSurface() Q_DECL_OVERRIDE;
|
||||||
void aboutToMakeCurrent();
|
void aboutToMakeCurrent();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user