From bc75bc54aa3984666f6d78b57d0bd690bce087bd Mon Sep 17 00:00:00 2001 From: Gabriel Jacobo Date: Sat, 3 Aug 2013 12:54:39 -0300 Subject: [PATCH] Fixes bug #1889, allows for GL Context deletion/recreation on Android Thanks ny00! --- .../src/org/libsdl/app/SDLActivity.java | 41 +++++++++++++------ src/core/android/SDL_android.c | 10 +++++ src/video/android/SDL_androidgl.c | 4 +- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index 62a3be1ba..9d57ef30f 100644 --- a/android-project/src/org/libsdl/app/SDLActivity.java +++ b/android-project/src/org/libsdl/app/SDLActivity.java @@ -72,6 +72,7 @@ protected void onCreate(Bundle savedInstanceState) { // Set up the surface mEGLSurface = EGL10.EGL_NO_SURFACE; mSurface = new SDLSurface(getApplication()); + mEGLContext = EGL10.EGL_NO_CONTEXT; mLayout = new AbsoluteLayout(this); mLayout.addView(mSurface); @@ -249,6 +250,20 @@ public static native void onNativeTouch(int touchDevId, int pointerFingerId, public static boolean createGLContext(int majorVersion, int minorVersion, int[] attribs) { return initEGL(majorVersion, minorVersion, attribs); } + + public static void deleteGLContext() { + if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLContext != EGL10.EGL_NO_CONTEXT) { + EGL10 egl = (EGL10)EGLContext.getEGL(); + egl.eglMakeCurrent(SDLActivity.mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); + egl.eglDestroyContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLContext); + SDLActivity.mEGLContext = EGL10.EGL_NO_CONTEXT; + + if (SDLActivity.mEGLSurface != EGL10.EGL_NO_SURFACE) { + egl.eglDestroySurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface); + SDLActivity.mEGLSurface = EGL10.EGL_NO_SURFACE; + } + } + } public static void flipBuffers() { flipEGL(); @@ -314,19 +329,20 @@ public static boolean showTextInput(int x, int y, int w, int h) { // EGL functions public static boolean initEGL(int majorVersion, int minorVersion, int[] attribs) { try { + EGL10 egl = (EGL10)EGLContext.getEGL(); + if (SDLActivity.mEGLDisplay == null) { - Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); - - EGL10 egl = (EGL10)EGLContext.getEGL(); - - EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - + SDLActivity.mEGLDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] version = new int[2]; - egl.eglInitialize(dpy, version); - + egl.eglInitialize(SDLActivity.mEGLDisplay, version); + } + + if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) { + // No current GL context exists, we will create a new one. + Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); EGLConfig[] configs = new EGLConfig[128]; int[] num_config = new int[1]; - if (!egl.eglChooseConfig(dpy, attribs, configs, 1, num_config) || num_config[0] == 0) { + if (!egl.eglChooseConfig(SDLActivity.mEGLDisplay, attribs, configs, 1, num_config) || num_config[0] == 0) { Log.e("SDL", "No EGL config available"); return false; } @@ -350,7 +366,7 @@ public static boolean initEGL(int majorVersion, int minorVersion, int[] attribs) attribs[j] == EGL10.EGL_ALPHA_SIZE || attribs[j] == EGL10.EGL_DEPTH_SIZE || attribs[j] == EGL10.EGL_STENCIL_SIZE)) { - egl.eglGetConfigAttrib(dpy, configs[i], attribs[j], value); + egl.eglGetConfigAttrib(SDLActivity.mEGLDisplay, configs[i], attribs[j], value); bitdiff += value[0] - attribs[j + 1]; // value is always >= attrib } } @@ -364,13 +380,12 @@ public static boolean initEGL(int majorVersion, int minorVersion, int[] attribs) } Log.d("SDL", "Selected mode with a total bit difference of " + bestdiff); - - SDLActivity.mEGLDisplay = dpy; SDLActivity.mEGLConfig = config; SDLActivity.mGLMajor = majorVersion; SDLActivity.mGLMinor = minorVersion; } + return SDLActivity.createEGLSurface(); } catch(Exception e) { @@ -397,7 +412,7 @@ public static boolean createEGLContext() { public static boolean createEGLSurface() { if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) { EGL10 egl = (EGL10)EGLContext.getEGL(); - if (SDLActivity.mEGLContext == null) createEGLContext(); + if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) createEGLContext(); if (SDLActivity.mEGLSurface == EGL10.EGL_NO_SURFACE) { Log.v("SDL", "Creating new EGL Surface"); diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 0d47b4bae..598e4095b 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -71,6 +71,7 @@ static jclass mActivityClass; // method signatures static jmethodID midCreateGLContext; +static jmethodID midDeleteGLContext; static jmethodID midFlipBuffers; static jmethodID midAudioInit; static jmethodID midAudioWriteShortBuffer; @@ -120,6 +121,8 @@ void SDL_Android_Init(JNIEnv* mEnv, jclass cls) midCreateGLContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "createGLContext","(II[I)Z"); + midDeleteGLContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "deleteGLContext","()V"); midFlipBuffers = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "flipBuffers","()V"); midAudioInit = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, @@ -361,6 +364,13 @@ SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion, return success ? SDL_TRUE : SDL_FALSE; } +SDL_bool Android_JNI_DeleteContext(SDL_GLContext context) +{ + /* There's only one context, so the parameter is ignored for now */ + JNIEnv *env = Android_JNI_GetEnv(); + (*env)->CallStaticBooleanMethod(env, mActivityClass, midDeleteGLContext); +} + void Android_JNI_SwapWindow() { JNIEnv *mEnv = Android_JNI_GetEnv(); diff --git a/src/video/android/SDL_androidgl.c b/src/video/android/SDL_androidgl.c index 1382b8878..f4fe55233 100644 --- a/src/video/android/SDL_androidgl.c +++ b/src/video/android/SDL_androidgl.c @@ -119,7 +119,9 @@ Android_GL_SwapWindow(_THIS, SDL_Window * window) void Android_GL_DeleteContext(_THIS, SDL_GLContext context) { - __android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_DeleteContext\n"); + if (context) { + Android_JNI_DeleteContext(context); + } } #endif /* SDL_VIDEO_DRIVER_ANDROID */