From fd30fe77df10d33ef86a56a54cc1516b192af9af Mon Sep 17 00:00:00 2001 From: offtkp Date: Wed, 31 Jul 2024 18:40:41 +0300 Subject: [PATCH] Context shenanigans --- src/core/renderer_gl/async_compiler.cpp | 14 ++++++----- src/jni_driver.cpp | 33 +++++++++++++++++++++++++ src/panda_sdl/frontend_sdl.cpp | 17 +++---------- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/core/renderer_gl/async_compiler.cpp b/src/core/renderer_gl/async_compiler.cpp index 800aec49..a6de1136 100644 --- a/src/core/renderer_gl/async_compiler.cpp +++ b/src/core/renderer_gl/async_compiler.cpp @@ -4,9 +4,8 @@ #include "glad/gl.h" #include "opengl.hpp" -namespace Frontend::AsyncCompiler { +namespace AsyncCompiler { void* createContext(void* userdata); - void makeCurrent(void* userdata, void* context); void destroyContext(void* userdata, void* context); } @@ -40,9 +39,12 @@ bool AsyncCompilerState::PopCompiledProgram(CompiledProgram*& program) } void AsyncCompilerState::Start() { - void* context = Frontend::AsyncCompiler::createContext(contextCreationUserdata); - shaderCompilationThread = std::thread([this, context]() { - Frontend::AsyncCompiler::makeCurrent(contextCreationUserdata, context); + shaderCompilationThread = std::thread([this]() { + void* context = AsyncCompiler::createContext(contextCreationUserdata); + if (!context) { + Helpers::panic("Failed to create async compiler context"); + } + printf("Async compiler started, version: %s\n", glGetString(GL_VERSION)); std::string defaultShadergenVSSource = fragShaderGen.getDefaultVertexShader(); defaultShadergenVs.create({defaultShadergenVSSource.c_str(), defaultShadergenVSSource.size()}, OpenGL::Vertex); @@ -85,7 +87,7 @@ void AsyncCompilerState::Start() { std::this_thread::yield(); } - Frontend::AsyncCompiler::destroyContext(contextCreationUserdata, context); + AsyncCompiler::destroyContext(contextCreationUserdata, context); }); } diff --git a/src/jni_driver.cpp b/src/jni_driver.cpp index e4ce2b39..355856a1 100644 --- a/src/jni_driver.cpp +++ b/src/jni_driver.cpp @@ -18,6 +18,10 @@ JavaVM* jvm = nullptr; jclass alberClass; jmethodID alberClassOpenDocument; +EGLSurface eglSurface = EGL_NO_SURFACE; +EGLDisplay eglDisplay = EGL_NO_DISPLAY; +int eglVersion = 0; + #define AlberFunction(type, name) JNIEXPORT type JNICALL Java_com_panda3ds_pandroid_AlberDriver_##name void throwException(JNIEnv* env, const char* message) { @@ -70,6 +74,10 @@ AlberFunction(void, Initialize)(JNIEnv* env, jobject obj) { return throwException(env, "Failed to load OpenGL ES 2.0"); } + eglDisplay = eglGetCurrentDisplay(); + eglSurface = eglGetCurrentSurface(EGL_DRAW); + eglQueryContext(eglDisplay, eglGetCurrentContext(), EGL_CONTEXT_CLIENT_VERSION, &eglVersion); + __android_log_print(ANDROID_LOG_INFO, "AlberDriver", "OpenGL ES %d.%d", GLVersion.major, GLVersion.minor); emulator->initGraphicsContext(nullptr); } @@ -139,4 +147,29 @@ int AndroidUtils::openDocument(const char* path, const char* perms) { env->DeleteLocalRef(jmode); return (int)result; +} + +namespace AsyncCompiler { + void createContext(void* userdata) { + EGLint attribList[] = { + EGL_CONTEXT_CLIENT_VERSION, eglVersion, + EGL_NONE + }; + + EGLContext threadContext = eglCreateContext(eglDisplay, eglSurface, EGL_NO_CONTEXT, attribList); + if (threadContext == EGL_NO_CONTEXT) { + throwException(jniEnv(), "Failed to create EGL context"); + } + + if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, threadContext)) { + throwException(jniEnv(), "Failed to make EGL context current"); + } + + __android_log_print(ANDROID_LOG_INFO, "AlberDriver", "Async compiler started, version: %s", glGetString(GL_VERSION)); + } + + void destroyContext(void* userdata, void* context) { + eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(eglDisplay, (EGLContext)context); + } } \ No newline at end of file diff --git a/src/panda_sdl/frontend_sdl.cpp b/src/panda_sdl/frontend_sdl.cpp index 4c1df3d8..68e32d94 100644 --- a/src/panda_sdl/frontend_sdl.cpp +++ b/src/panda_sdl/frontend_sdl.cpp @@ -344,12 +344,12 @@ void FrontendSDL::run() { } } -namespace Frontend::AsyncCompiler { +namespace AsyncCompiler { void* createContext(void* userdata) { SDL_Window* window = static_cast(userdata); - SDL_GLContext previousContext = SDL_GL_GetCurrentContext(); - SDL_GLContext context = SDL_GL_CreateContext(window); // this sets it as current :( - SDL_GL_MakeCurrent(window, previousContext); + + // SDL_GL_CreateContext also makes it the current context + SDL_GLContext context = SDL_GL_CreateContext(window); if (context == nullptr) { Helpers::panic("OpenGL context creation failed: %s", SDL_GetError()); @@ -358,15 +358,6 @@ namespace Frontend::AsyncCompiler { return context; } - void makeCurrent(void* userdata, void* context) { - SDL_Window* window = static_cast(userdata); - int result = SDL_GL_MakeCurrent(window, context); - - if (result < 0) { - Helpers::panic("OpenGL context make current failed: %s", SDL_GetError()); - } - } - void destroyContext(void* userdata, void* context) { SDL_GL_DeleteContext(static_cast(context)); }