Skip to content

Commit

Permalink
Expose context loss
Browse files Browse the repository at this point in the history
On platforms like Windows (and presumably on mobile devices too)
the loss of the context (e.g. the underlying D3D device in case of
ANGLE) is an event that can happen randomly and needs sufficient
handling.

Enhance QOpenGLContext::isValid() with the purpose of indicating
context loss.

Currently only the Windows EGL backend (ANGLE) has support for it.
Other platforms may be added later.

Task-number: QTBUG-43263
Change-Id: I8177694c1ee7cebbd5d330e34757fd94c563e6d6
Reviewed-by: Friedemann Kleint <[email protected]>
  • Loading branch information
Laszlo Agocs authored and alpqr committed Jan 22, 2015
1 parent a2b358e commit 2bc038a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/gui/kernel/qopenglcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,10 @@ QVariant QOpenGLContext::nativeHandle() const
*/
bool QOpenGLContext::create()
{
if (isValid())
Q_D(QOpenGLContext);
if (d->platformGLContext)
destroy();

Q_D(QOpenGLContext);
d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this);
if (!d->platformGLContext)
return false;
Expand Down Expand Up @@ -676,6 +676,15 @@ QOpenGLContext::~QOpenGLContext()
/*!
Returns if this context is valid, i.e. has been successfully created.
On some platforms the return value of \c false for a context that was
successfully created previously indicates that the OpenGL context was lost.
The typical way to handle context loss scenarios in applications is to
check via this function whenever makeCurrent() fails and returns \c false.
If this function then returns \c false, recreate the underlying native
OpenGL context by calling create(), call makeCurrent() again and then
reinitialize all OpenGL resources.
\sa create()
*/
bool QOpenGLContext::isValid() const
Expand Down
12 changes: 11 additions & 1 deletion src/plugins/platforms/windows/qwindowseglcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,17 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
QWindowsEGLStaticContext::libEGL.eglSwapInterval(m_staticContext->display(), m_swapInterval);
}
} else {
qWarning("QWindowsEGLContext::makeCurrent: eglError: %x, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
int err = QWindowsEGLStaticContext::libEGL.eglGetError();
// EGL_CONTEXT_LOST (loss of the D3D device) is not necessarily fatal.
// Qt Quick is able to recover for example.
if (err == EGL_CONTEXT_LOST) {
m_eglContext = EGL_NO_CONTEXT;
qCDebug(lcQpaGl) << "Got EGL context lost in makeCurrent() for context" << this;
// Drop the surface. Will recreate on the next makeCurrent.
window->invalidateSurface();
} else {
qWarning("QWindowsEGLContext::makeCurrent: eglError: %x, this: %p \n", err, this);
}
}

return ok;
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/platforms/windows/qwindowswindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2294,6 +2294,14 @@ void *QWindowsWindow::surface(void *nativeConfig)
#endif
}

void QWindowsWindow::invalidateSurface()
{
if (m_surface) {
m_data.staticOpenGLContext->destroyWindowSurface(m_surface);
m_surface = 0;
}
}

void QWindowsWindow::setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes)
{
if (!window->handle())
Expand Down
1 change: 1 addition & 0 deletions src/plugins/platforms/windows/qwindowswindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class QWindowsWindow : public QPlatformWindow
void setWindowIcon(const QIcon &icon);

void *surface(void *nativeConfig);
void invalidateSurface() Q_DECL_OVERRIDE;

#ifndef Q_OS_WINCE
void setAlertState(bool enabled);
Expand Down

0 comments on commit 2bc038a

Please sign in to comment.