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:
Laszlo Agocs 2015-03-10 12:14:03 +01:00
parent f29007b1d5
commit 367a91d278
5 changed files with 30 additions and 13 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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:

View File

@ -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;

View File

@ -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();