diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index 015f7a4e..328127f8 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -22,9 +22,24 @@ #include #include #include +#if !defined(_WIN32) +#include +#endif namespace MobileGL::MG_Impl::GLImpl { namespace { + bool TryGetNativeContextFlags(GLint* flags) { +#if !defined(_WIN32) + using GLGetIntegervFn = void (*)(GLenum, GLint*); + static auto* nextGetIntegerv = reinterpret_cast(dlsym(RTLD_NEXT, "glGetIntegerv")); + if (nextGetIntegerv) { + nextGetIntegerv(GL_CONTEXT_FLAGS, flags); + return true; + } +#endif + return false; + } + enum class IndexedBufferQueryKind { Binding, Start, @@ -896,9 +911,13 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_DEBUG_GROUP_STACK_DEPTH: *params = 0; // debug-group entrypoints are stubbed return; - case GL_CONTEXT_FLAGS: - *params = 0; // contexts are created without debug/robust/forward-compatible flags + case GL_CONTEXT_FLAGS: { + *params = MG_State::pEGLContext ? MG_State::pEGLContext->GetCurrentContextFlags() : 0; + if (*params == 0) { + TryGetNativeContextFlags(params); + } return; + } case GL_CULL_FACE: *params = MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace) ? GL_TRUE : GL_FALSE; return; diff --git a/MobileGL/MG_State/EGLState/Core.cpp b/MobileGL/MG_State/EGLState/Core.cpp index 152cf537..e960c33a 100644 --- a/MobileGL/MG_State/EGLState/Core.cpp +++ b/MobileGL/MG_State/EGLState/Core.cpp @@ -7,6 +7,7 @@ // End of Source File Header #include "Core.h" +#include namespace MobileGL { namespace MG_State { @@ -611,6 +612,32 @@ namespace MobileGL { if (auto value = ParseAttribValue(attribList, EGL_CONTEXT_OPENGL_PROFILE_MASK); value) { contextObject.OpenGLProfileMask = *value; } + if (auto value = ParseAttribValue(attribList, EGL_CONTEXT_FLAGS_KHR); value) { + contextObject.EGLContextFlags = *value; + if (*value & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) { + contextObject.OpenGLContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; + } + if (*value & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) { + contextObject.OpenGLContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; + } + if (*value & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) { + contextObject.OpenGLContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT; + } + } + if (auto value = ParseAttribValue(attribList, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE); + value && *value == EGL_TRUE) { + contextObject.EGLContextFlags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; + contextObject.OpenGLContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; + } + if (auto value = ParseAttribValue(attribList, EGL_CONTEXT_OPENGL_DEBUG); value && *value == EGL_TRUE) { + contextObject.EGLContextFlags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; + contextObject.OpenGLContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; + } + if (auto value = ParseAttribValue(attribList, EGL_CONTEXT_OPENGL_ROBUST_ACCESS); + value && *value == EGL_TRUE) { + contextObject.EGLContextFlags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + contextObject.OpenGLContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT; + } const auto context = EncodeHandle(m_nextContextHandle++); m_contexts[context] = contextObject; @@ -668,6 +695,9 @@ namespace MobileGL { case EGL_CONTEXT_MINOR_VERSION: *value = contextObject->MinorVersion; return true; + case EGL_CONTEXT_FLAGS_KHR: + *value = contextObject->EGLContextFlags; + return true; case EGL_CONFIG_ID: { const auto* cfg = TryGetConfig(contextObject->Config); if (!cfg) { @@ -709,6 +739,16 @@ namespace MobileGL { ctx->MajorVersion > 3 || (ctx->MajorVersion == 3 && ctx->MinorVersion >= 1); } + EGLint EGLContext::GetCurrentContextFlags() const { + const std::lock_guard lock(m_mutex); + auto currentIt = m_threadCurrents.find(CurrentThreadKey()); + if (currentIt == m_threadCurrents.end()) { + return 0; + } + const auto* ctx = TryGetContext(currentIt->second.Context); + return ctx ? ctx->OpenGLContextFlags : 0; + } + EGLContext::EGLSurfaceHandle EGLContext::CreateWindowSurface(EGLDisplayHandle display, EGLConfigHandle config, NativeWindowType window, diff --git a/MobileGL/MG_State/EGLState/Core.h b/MobileGL/MG_State/EGLState/Core.h index dfe0a1ae..bcedafb7 100644 --- a/MobileGL/MG_State/EGLState/Core.h +++ b/MobileGL/MG_State/EGLState/Core.h @@ -59,6 +59,7 @@ namespace MobileGL { Bool ValidateContext(EGLContextHandle context) const; Bool ValidateContextOnDisplay(EGLDisplayHandle display, EGLContextHandle context) const; Bool IsCurrentContextOpenGLCoreProfile() const; + EGLint GetCurrentContextFlags() const; // Surface EGLSurfaceHandle CreateWindowSurface(EGLDisplayHandle display, EGLConfigHandle config, @@ -160,6 +161,8 @@ namespace MobileGL { EGLint MajorVersion = 1; EGLint MinorVersion = 0; EGLint OpenGLProfileMask = 0; + EGLint EGLContextFlags = 0; + EGLint OpenGLContextFlags = 0; }; struct SurfaceObject {