void QEGLPlatformContext::updateFormatFromGL() { #ifndef QT_NO_OPENGL // Have to save & restore to prevent QOpenGLContext::currentContext() from becoming // inconsistent after QOpenGLContext::create(). EGLDisplay prevDisplay = eglGetCurrentDisplay(); if (prevDisplay == EGL_NO_DISPLAY) // when no context is current prevDisplay = m_eglDisplay; EGLContext prevContext = eglGetCurrentContext(); EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW); EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ); // Rely on the surfaceless extension, if available. This is beneficial since we can // avoid creating an extra pbuffer surface which is apparently troublesome with some // drivers (Mesa) when certain attributes are present (multisampling). EGLSurface tempSurface = EGL_NO_SURFACE; if (!q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) tempSurface = createTemporaryOffscreenSurface(); if (eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext)) { if (m_format.renderableType() == QSurfaceFormat::OpenGL || m_format.renderableType() == QSurfaceFormat::OpenGLES) { const GLubyte *s = glGetString(GL_VERSION); if (s) { QByteArray version = QByteArray(reinterpret_cast<const char *>(s)); int major, minor; if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) { m_format.setMajorVersion(major); m_format.setMinorVersion(minor); } } m_format.setProfile(QSurfaceFormat::NoProfile); m_format.setOptions(QSurfaceFormat::FormatOptions()); if (m_format.renderableType() == QSurfaceFormat::OpenGL) { // Check profile and options. if (m_format.majorVersion() < 3) { m_format.setOption(QSurfaceFormat::DeprecatedFunctions); } else { GLint value = 0; glGetIntegerv(GL_CONTEXT_FLAGS, &value); if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)) m_format.setOption(QSurfaceFormat::DeprecatedFunctions); if (value & GL_CONTEXT_FLAG_DEBUG_BIT) m_format.setOption(QSurfaceFormat::DebugContext); if (m_format.version() >= qMakePair(3, 2)) { value = 0; glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); if (value & GL_CONTEXT_CORE_PROFILE_BIT) m_format.setProfile(QSurfaceFormat::CoreProfile); else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) m_format.setProfile(QSurfaceFormat::CompatibilityProfile); } } } } eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); } else { qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated"); } if (tempSurface != EGL_NO_SURFACE) destroyTemporaryOffscreenSurface(tempSurface); #endif // QT_NO_OPENGL }
void EGLPlatformContext::updateFormatFromGL() { #ifndef QT_NO_OPENGL // Have to save & restore to prevent QOpenGLContext::currentContext() from becoming // inconsistent after QOpenGLContext::create(). EGLDisplay prevDisplay = eglGetCurrentDisplay(); if (prevDisplay == EGL_NO_DISPLAY) // when no context is current prevDisplay = m_eglDisplay; EGLContext prevContext = eglGetCurrentContext(); EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW); EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ); // Rely on the surfaceless extension, if available. This is beneficial since we can // avoid creating an extra pbuffer surface which is apparently troublesome with some // drivers (Mesa) when certain attributes are present (multisampling). EGLSurface tempSurface = EGL_NO_SURFACE; EGLContext tempContext = EGL_NO_CONTEXT; if (m_flags.testFlag(NoSurfaceless) || !EglUtils::hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) tempSurface = createTemporaryOffscreenSurface(); EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext); if (!ok) { EGLConfig config = EglUtils::configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT); tempContext = eglCreateContext(m_eglDisplay, config, 0, m_contextAttrs.constData()); if (tempContext != EGL_NO_CONTEXT) ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, tempContext); } if (ok) { if (m_format.renderableType() == QSurfaceFormat::OpenGL || m_format.renderableType() == QSurfaceFormat::OpenGLES) { const GLubyte *s = glGetString(GL_VERSION); if (s) { QByteArray version = QByteArray(reinterpret_cast<const char *>(s)); int major, minor; if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) { #ifdef Q_OS_ANDROID // Some Android 4.2.2 devices report OpenGL ES 3.0 without the functions being available. static int apiLevel = QtAndroidPrivate::androidSdkVersion(); if (apiLevel <= 17 && major >= 3) { major = 2; minor = 0; } #endif m_format.setMajorVersion(major); m_format.setMinorVersion(minor); } } m_format.setProfile(QSurfaceFormat::NoProfile); m_format.setOptions(QSurfaceFormat::FormatOptions()); if (m_format.renderableType() == QSurfaceFormat::OpenGL) { // Check profile and options. if (m_format.majorVersion() < 3) { m_format.setOption(QSurfaceFormat::DeprecatedFunctions); } else { GLint value = 0; glGetIntegerv(GL_CONTEXT_FLAGS, &value); if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)) m_format.setOption(QSurfaceFormat::DeprecatedFunctions); if (value & GL_CONTEXT_FLAG_DEBUG_BIT) m_format.setOption(QSurfaceFormat::DebugContext); if (m_format.version() >= qMakePair(3, 2)) { value = 0; glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); if (value & GL_CONTEXT_CORE_PROFILE_BIT) m_format.setProfile(QSurfaceFormat::CoreProfile); else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) m_format.setProfile(QSurfaceFormat::CompatibilityProfile); } } } } runGLchecks(); eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); } else { qCWarning(lcEglConvenience, "Failed to make temporary surface current, format not updated (%x)", eglGetError()); } if (tempSurface != EGL_NO_SURFACE) destroyTemporaryOffscreenSurface(tempSurface); if (tempContext != EGL_NO_CONTEXT) eglDestroyContext(m_eglDisplay, tempContext); #endif // QT_NO_OPENGL }