mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-13 06:38:31 +09:00
[Refactor] (Lifecycle): own MobileGL's lifecycle from the EGL layer instead of ELF static ctor/dtor - the first EGL/WGL entry point lazily initializes via a thread-safe, re-init-capable EnsureInitialized (AutoInit is gone), the last eglTerminate with no initialized display and nothing current tears the whole library down deterministically inside the EGL lifecycle, and the global singletons move to leak-at-exit heap storage so process exit runs no backend destructors at all (AutoDestroy and the Windows DllMain abandon hook are gone); fixes the exit-time SIGABRT from undefined static-destruction order - the DirectGLES buffer-pool mutex abort on Android clean exits, and the pre-existing macOS QueryTest/ProgramTest 'Subprocess aborted' gtest failures now pass (ctest 411/411)
This commit is contained in:
@@ -368,6 +368,26 @@ namespace MobileGL {
|
||||
return true;
|
||||
}
|
||||
|
||||
Bool EGLContext::HasAnyInitializedDisplay() const {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
for (const auto& [handle, displayObject] : m_displays) {
|
||||
if (displayObject.Initialized) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Bool EGLContext::HasAnyCurrentContext() const {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
for (const auto& [threadId, current] : m_threadCurrents) {
|
||||
if (current.Context != nullptr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Bool EGLContext::ChooseConfig(EGLDisplayHandle display, const EGLint* attribList, EGLConfigHandle* configs,
|
||||
EGLint configSize, EGLint* numConfig) {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
@@ -1415,6 +1435,7 @@ namespace MobileGL {
|
||||
}
|
||||
} // namespace EGLState
|
||||
|
||||
UniquePtr<EGLState::EGLContext> pEGLContext;
|
||||
// Leak-at-exit storage; see GlobalObjects.cpp.
|
||||
UniquePtr<EGLState::EGLContext>& pEGLContext = *new UniquePtr<EGLState::EGLContext>();
|
||||
} // namespace MG_State
|
||||
} // namespace MobileGL
|
||||
|
||||
@@ -39,6 +39,10 @@ namespace MobileGL {
|
||||
Bool IsDisplayInitialized(EGLDisplayHandle display) const;
|
||||
Bool InitializeDisplay(EGLDisplayHandle display, EGLint* major, EGLint* minor);
|
||||
Bool TerminateDisplay(EGLDisplayHandle display);
|
||||
// Whole-library idle checks used by EGLImpl::Terminate to decide
|
||||
// when the last eglTerminate may tear MobileGL down entirely.
|
||||
Bool HasAnyInitializedDisplay() const;
|
||||
Bool HasAnyCurrentContext() const;
|
||||
|
||||
// Config
|
||||
Bool ChooseConfig(EGLDisplayHandle display, const EGLint* attribList, EGLConfigHandle* configs,
|
||||
@@ -262,6 +266,6 @@ namespace MobileGL {
|
||||
};
|
||||
} // namespace EGLState
|
||||
|
||||
extern UniquePtr<EGLState::EGLContext> pEGLContext;
|
||||
extern UniquePtr<EGLState::EGLContext>& pEGLContext;
|
||||
} // namespace MG_State
|
||||
} // namespace MobileGL
|
||||
|
||||
@@ -721,5 +721,6 @@ namespace MobileGL::MG_State {
|
||||
}
|
||||
} // namespace GLState
|
||||
|
||||
UniquePtr<GLState::GLContext> pGLContext;
|
||||
// Leak-at-exit storage; see GlobalObjects.cpp.
|
||||
UniquePtr<GLState::GLContext>& pGLContext = *new UniquePtr<GLState::GLContext>();
|
||||
} // namespace MobileGL::MG_State
|
||||
|
||||
@@ -252,7 +252,7 @@ namespace MobileGL {
|
||||
};
|
||||
} // namespace GLState
|
||||
|
||||
extern UniquePtr<GLState::GLContext> pGLContext;
|
||||
extern UniquePtr<GLState::GLContext>& pGLContext;
|
||||
|
||||
// True when relaxed GL semantics apply. Strict core rules are enforced only when the
|
||||
// current EGL context explicitly requested a core profile (core bit in
|
||||
|
||||
Reference in New Issue
Block a user