From 401f4a8ad585c0a5f4360084755e05d9b2bfb288 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 7 Feb 2011 17:44:07 -0800 Subject: [PATCH] Try to create an OpenGL ES 2.0 context on Android and successfully fall back to OpenGL ES 1.1 if that fails. --- .../src/org/libsdl/app/SDLActivity.java | 40 ++++++++++++++----- src/core/android/SDL_android.cpp | 11 +++-- src/core/android/SDL_android.h | 2 +- src/render/opengles2/SDL_render_gles2.c | 8 ++++ src/video/android/SDL_androidgl.c | 8 +++- src/video/android/SDL_androidwindow.c | 6 +++ 6 files changed, 61 insertions(+), 14 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index bb9cb22d6..ca82870ff 100644 --- a/android-project/src/org/libsdl/app/SDLActivity.java +++ b/android-project/src/org/libsdl/app/SDLActivity.java @@ -101,8 +101,8 @@ public static native void onNativeTouch(int action, float x, // Java functions called from C - public static void createGLContext() { - mSurface.initEGL(); + public static boolean createGLContext(int majorVersion, int minorVersion) { + return mSurface.initEGL(majorVersion, minorVersion); } public static void flipBuffers() { @@ -351,11 +351,10 @@ public void onDraw(Canvas canvas) {} // EGL functions - public boolean initEGL() { - Log.v("SDL", "Starting up"); + public boolean initEGL(int majorVersion, int minorVersion) { + Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion); try { - EGL10 egl = (EGL10)EGLContext.getEGL(); EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); @@ -363,20 +362,43 @@ public boolean initEGL() { int[] version = new int[2]; egl.eglInitialize(dpy, version); + int EGL_OPENGL_ES_BIT = 1; + int EGL_OPENGL_ES2_BIT = 4; + int renderableType = 0; + if (majorVersion == 2) { + renderableType = EGL_OPENGL_ES2_BIT; + } else if (majorVersion == 1) { + renderableType = EGL_OPENGL_ES_BIT; + } int[] configSpec = { - //EGL10.EGL_DEPTH_SIZE, 16, - EGL10.EGL_NONE + //EGL10.EGL_DEPTH_SIZE, 16, + EGL10.EGL_RENDERABLE_TYPE, renderableType, + EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] num_config = new int[1]; - egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config); + if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) { + Log.e("SDL", "No EGL config available"); + return false; + } EGLConfig config = configs[0]; EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, null); + if (ctx == EGL10.EGL_NO_CONTEXT) { + Log.e("SDL", "Couldn't create context"); + return false; + } EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, null); + if (surface == EGL10.EGL_NO_SURFACE) { + Log.e("SDL", "Couldn't create surface"); + return false; + } - egl.eglMakeCurrent(dpy, surface, surface, ctx); + if (!egl.eglMakeCurrent(dpy, surface, surface, ctx)) { + Log.e("SDL", "Couldn't make context current"); + return false; + } mEGLContext = ctx; mEGLDisplay = dpy; diff --git a/src/core/android/SDL_android.cpp b/src/core/android/SDL_android.cpp index 0351007e3..f09601272 100644 --- a/src/core/android/SDL_android.cpp +++ b/src/core/android/SDL_android.cpp @@ -20,6 +20,7 @@ slouken@libsdl.org */ #include "SDL_config.h" +#include "SDL_stdinc.h" #include "SDL_android.h" @@ -80,7 +81,7 @@ extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls) mActivityClass = cls; midCreateGLContext = mEnv->GetStaticMethodID(mActivityClass, - "createGLContext","()V"); + "createGLContext","(II)Z"); midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass, "flipBuffers","()V"); midAudioInit = mEnv->GetStaticMethodID(mActivityClass, @@ -159,9 +160,13 @@ extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread( /******************************************************************************* Functions called by SDL into Java *******************************************************************************/ -extern "C" void Android_JNI_CreateContext() +extern "C" SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion) { - mEnv->CallStaticVoidMethod(mActivityClass, midCreateGLContext); + if (mEnv->CallStaticBooleanMethod(mActivityClass, midCreateGLContext, majorVersion, minorVersion)) { + return SDL_TRUE; + } else { + return SDL_FALSE; + } } extern "C" void Android_JNI_SwapWindow() diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index bc7a4ea27..7d97da115 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -29,7 +29,7 @@ extern "C" { #endif /* Interface from the SDL library into the Android Java activity */ -extern void Android_JNI_CreateContext(); +extern SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion); extern void Android_JNI_SwapWindow(); extern void Android_JNI_SetActivityTitle(const char *title); extern void Android_JNI_GetAccelerometerValues(float values[3]); diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 3019239c2..e171c8d3c 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -1071,11 +1071,19 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) { SDL_Renderer *renderer; GLES2_DriverContext *rdata; + Uint32 window_flags; GLint nFormats; #ifndef ZUNE_HD GLboolean hasCompiler; #endif + window_flags = SDL_GetWindowFlags(window); + if (!(window_flags & SDL_WINDOW_OPENGL)) { + if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) { + return NULL; + } + } + /* Create the renderer struct */ renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer)); if (!renderer) { diff --git a/src/video/android/SDL_androidgl.c b/src/video/android/SDL_androidgl.c index d7e4b6865..89edc88fa 100644 --- a/src/video/android/SDL_androidgl.c +++ b/src/video/android/SDL_androidgl.c @@ -55,7 +55,11 @@ Android_GL_UnloadLibrary(_THIS) SDL_GLContext Android_GL_CreateContext(_THIS, SDL_Window * window) { - Android_JNI_CreateContext(); + if (!Android_JNI_CreateContext(_this->gl_config.major_version, + _this->gl_config.minor_version)) { + SDL_SetError("Couldn't create OpenGL context - see Android log for details"); + return NULL; + } return (SDL_GLContext)1; } @@ -91,3 +95,5 @@ Android_GL_DeleteContext(_THIS, SDL_GLContext context) { __android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_DeleteContext\n"); } + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c index 397de1c0b..263c4d5f0 100644 --- a/src/video/android/SDL_androidwindow.c +++ b/src/video/android/SDL_androidwindow.c @@ -41,6 +41,12 @@ Android_CreateWindow(_THIS, SDL_Window * window) window->w = Android_ScreenWidth; window->h = Android_ScreenHeight; + window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */ + window->flags |= SDL_WINDOW_OPENGL; /* window is always OpenGL */ + window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */ + window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */ + window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */ + return 0; }