Create robust egl context if possible

This commit is contained in:
Martin Gräßlin 2015-11-13 09:45:11 +01:00
parent 6d96b8c4af
commit b383db2e2e
2 changed files with 114 additions and 46 deletions

View file

@ -184,34 +184,69 @@ bool AbstractEglBackend::isOpenGLES() const
bool AbstractEglBackend::createContext() bool AbstractEglBackend::createContext()
{ {
const QByteArray eglExtensions = eglQueryString(m_display, EGL_EXTENSIONS);
const QList<QByteArray> extensions = eglExtensions.split(' ');
const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness"));
const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context"));
EGLContext ctx = EGL_NO_CONTEXT; EGLContext ctx = EGL_NO_CONTEXT;
if (isOpenGLES()) { if (isOpenGLES()) {
const EGLint context_attribs[] = { if (haveCreateContext && haveRobustness) {
EGL_CONTEXT_CLIENT_VERSION, 2, const EGLint context_attribs[] = {
EGL_NONE EGL_CONTEXT_CLIENT_VERSION, 2,
}; EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT,
EGL_NONE
};
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs);
}
if (ctx == EGL_NO_CONTEXT) {
const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs); ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs);
}
} else { } else {
const EGLint context_attribs_31_core[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
EGL_CONTEXT_MINOR_VERSION_KHR, 1,
EGL_NONE
};
const EGLint context_attribs_legacy[] = {
EGL_NONE
};
const QByteArray eglExtensions = eglQueryString(m_display, EGL_EXTENSIONS);
const QList<QByteArray> extensions = eglExtensions.split(' ');
// Try to create a 3.1 core context // Try to create a 3.1 core context
if (options->glCoreProfile() && extensions.contains("EGL_KHR_create_context")) if (options->glCoreProfile() && haveCreateContext) {
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs_31_core); if (haveRobustness) {
const int attribs[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
EGL_CONTEXT_MINOR_VERSION_KHR, 1,
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR,
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR,
EGL_NONE
};
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs);
}
if (ctx == EGL_NO_CONTEXT) {
// try without robustness
const EGLint attribs[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
EGL_CONTEXT_MINOR_VERSION_KHR, 1,
EGL_NONE
};
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs);
}
}
if (ctx == EGL_NO_CONTEXT) if (ctx == EGL_NO_CONTEXT && haveRobustness && haveCreateContext) {
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, context_attribs_legacy); const int attribs[] = {
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR,
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR,
EGL_NONE
};
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs);
}
if (ctx == EGL_NO_CONTEXT) {
// and last but not least: try without robustness
const EGLint attribs[] = {
EGL_NONE
};
ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs);
}
} }
if (ctx == EGL_NO_CONTEXT) { if (ctx == EGL_NO_CONTEXT) {

View file

@ -135,38 +135,71 @@ bool AbstractPlatformContext::bindApi()
void AbstractPlatformContext::createContext(EGLContext shareContext) void AbstractPlatformContext::createContext(EGLContext shareContext)
{ {
const QByteArray eglExtensions = eglQueryString(eglDisplay(), EGL_EXTENSIONS);
const QList<QByteArray> extensions = eglExtensions.split(' ');
const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness"));
const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context"));
EGLContext context = EGL_NO_CONTEXT; EGLContext context = EGL_NO_CONTEXT;
if (isOpenGLES()) { if (isOpenGLES()) {
const EGLint context_attribs[] = { if (haveCreateContext && haveRobustness) {
EGL_CONTEXT_CLIENT_VERSION, 2, const EGLint context_attribs[] = {
EGL_NONE EGL_CONTEXT_CLIENT_VERSION, 2,
}; EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT,
EGL_NONE
};
context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs);
}
if (context == EGL_NO_CONTEXT) {
const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs); context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs);
}
} else { } else {
const EGLint context_attribs_31_core[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(),
EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(),
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
EGL_NONE
};
const EGLint context_attribs_legacy[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
const char* eglExtensionsCString = eglQueryString(eglDisplay(), EGL_EXTENSIONS);
const QList<QByteArray> extensions = QByteArray::fromRawData(eglExtensionsCString, qstrlen(eglExtensionsCString)).split(' ');
// Try to create a 3.1 core context // Try to create a 3.1 core context
if (m_format.majorVersion() >= 3 && extensions.contains(QByteArrayLiteral("EGL_KHR_create_context"))) { if (m_format.majorVersion() >= 3 && haveCreateContext) {
context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs_31_core); if (haveRobustness) {
const int attribs[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(),
EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(),
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR,
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
EGL_NONE
};
context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
}
if (context == EGL_NO_CONTEXT) {
// try without robustness
const EGLint attribs[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(),
EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(),
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
EGL_NONE
};
context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
}
} }
if (context == EGL_NO_CONTEXT && haveRobustness && haveCreateContext) {
const int attribs[] = {
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR,
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR,
EGL_NONE
};
context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
}
if (context == EGL_NO_CONTEXT) { if (context == EGL_NO_CONTEXT) {
context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs_legacy); // and last but not least: try without robustness
const EGLint attribs[] = {
EGL_NONE
};
context = eglCreateContext(eglDisplay(), config(), shareContext, attribs);
} }
} }