From 6b1985d95f79c8976898d27259dbdf4417af86ee Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 27 Aug 2011 18:29:40 +0000 Subject: [PATCH] android: keep a pointer on the global Java VM instead of the current environment, so back-to-jvm techniques can work from any thread. --- src/Makefile.am | 4 ++- src/androidapp.cpp | 11 +++---- src/core.h | 2 +- src/{ => image}/image.cpp | 66 +++++++++++++++++++++++++-------------- src/{ => image}/image.h | 0 5 files changed, 50 insertions(+), 33 deletions(-) rename src/{ => image}/image.cpp (83%) rename src/{ => image}/image.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index d62b2cd3..6bc44af5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ liblol_a_SOURCES = \ timer.cpp timer.h bitfield.h profiler.cpp profiler.h input.h input.cpp \ world.cpp world.h sample.cpp sample.h sampler.cpp sampler.h \ text.cpp text.h emitter.cpp emitter.h numeric.h hash.cpp hash.h \ - worldentity.cpp worldentity.h image.cpp image.h gradient.cpp gradient.h \ + worldentity.cpp worldentity.h gradient.cpp gradient.h \ platform.cpp platform.h sprite.cpp sprite.h \ \ sdlapp.cpp sdlapp.h sdlinput.cpp sdlinput.h \ @@ -20,6 +20,8 @@ liblol_a_SOURCES = \ \ shader/shader.cpp shader/shader.h \ \ + image/image.cpp image/image.h \ + \ loldebug.h \ debug/fps.cpp debug/fps.h debug/sphere.cpp debug/sphere.h \ debug/record.cpp debug/record.h debug/stats.cpp debug/stats.h \ diff --git a/src/androidapp.cpp b/src/androidapp.cpp index dbc5f537..dd48bd73 100644 --- a/src/androidapp.cpp +++ b/src/androidapp.cpp @@ -25,13 +25,14 @@ using namespace lol; namespace lol { -jobject g_ctx; -JNIEnv *g_env; +JavaVM *g_vm; +jobject g_activity; }; extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) { + g_vm = vm; return JNI_VERSION_1_4; } @@ -39,16 +40,12 @@ extern "C" void Java_org_zoy_LolEngine_LolActivity_nativeInit(JNIEnv* env, jobject thiz) { env->NewGlobalRef(thiz); /* FIXME: never released! */ - g_ctx = thiz; + g_activity = thiz; } extern "C" void Java_org_zoy_LolEngine_LolRenderer_nativeInit(JNIEnv* env) { - /* We cannot use JNI_OnLoad for this because we're in a different - * thread now. */ - g_env = env; - Log::Info("initialising renderer"); Ticker::Setup(30.0f); Video::Setup(ivec2(320, 200)); diff --git a/src/core.h b/src/core.h index 63b116ae..5741c042 100644 --- a/src/core.h +++ b/src/core.h @@ -49,7 +49,7 @@ #include "map.h" #include "layer.h" #include "shader/shader.h" -#include "image.h" +#include "image/image.h" // Managers #include "ticker.h" diff --git a/src/image.cpp b/src/image/image.cpp similarity index 83% rename from src/image.cpp rename to src/image/image.cpp index cf9c5bba..6f4c179a 100644 --- a/src/image.cpp +++ b/src/image/image.cpp @@ -35,8 +35,8 @@ namespace lol { #if defined ANDROID_NDK -extern JNIEnv *g_env; -extern jobject g_ctx; +extern JavaVM *g_vm; +extern jobject g_activity; #endif /* @@ -126,14 +126,23 @@ Image::Image(char const *path) data->size = ivec2(data->img->w, data->img->h); data->format = data->img->format->Amask ? FORMAT_RGBA : FORMAT_RGB; #elif defined ANDROID_NDK - jclass cls = g_env->GetObjectClass(g_ctx); + JNIEnv *env; + jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); + if (res < 0) + { +#if !LOL_RELEASE + Log::Error("could not get JVM environment\n"); +#endif + exit(1); + } + jclass cls = env->GetObjectClass(g_activity); jmethodID mid; - mid = g_env->GetMethodID(cls, "openImage", - "(Ljava/lang/String;)Landroid/graphics/Bitmap;"); - jstring name = g_env->NewStringUTF(path); - data->bmp = g_env->CallObjectMethod(g_ctx, mid, name); - g_env->DeleteLocalRef(name); + mid = env->GetMethodID(cls, "openImage", + "(Ljava/lang/String;)Landroid/graphics/Bitmap;"); + jstring name = env->NewStringUTF(path); + data->bmp = env->CallObjectMethod(g_activity, mid, name); + env->DeleteLocalRef(name); if (!data->bmp) { #if !LOL_RELEASE @@ -141,21 +150,21 @@ Image::Image(char const *path) #endif exit(1); } - g_env->NewGlobalRef(data->bmp); + env->NewGlobalRef(data->bmp); /* Get image dimensions */ - mid = g_env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); - data->size.x = g_env->CallIntMethod(g_ctx, mid, data->bmp); - mid = g_env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); - data->size.y = g_env->CallIntMethod(g_ctx, mid, data->bmp); + mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); + data->size.x = env->CallIntMethod(g_activity, mid, data->bmp); + mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); + data->size.y = env->CallIntMethod(g_activity, mid, data->bmp); /* Get pixels */ - data->array = g_env->NewIntArray(data->size.x * data->size.y); - g_env->NewGlobalRef(data->array); - mid = g_env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); - g_env->CallVoidMethod(g_ctx, mid, data->bmp, data->array); + data->array = env->NewIntArray(data->size.x * data->size.y); + env->NewGlobalRef(data->array); + mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); + env->CallVoidMethod(g_activity, mid, data->bmp, data->array); - data->pixels = g_env->GetIntArrayElements(data->array, 0); + data->pixels = env->GetIntArrayElements(data->array, 0); for (int n = 0; n < data->size.x * data->size.y; n++) { uint32_t u = data->pixels[n]; @@ -343,16 +352,25 @@ Image::~Image() #elif defined USE_SDL SDL_FreeSurface(data->img); #elif defined ANDROID_NDK - jclass cls = g_env->GetObjectClass(g_ctx); + JNIEnv *env; + jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); + if (res < 0) + { +#if !LOL_RELEASE + Log::Error("could not get JVM environment\n"); +#endif + exit(1); + } + jclass cls = env->GetObjectClass(g_activity); jmethodID mid; - g_env->ReleaseIntArrayElements(data->array, data->pixels, 0); - g_env->DeleteGlobalRef(data->array); + env->ReleaseIntArrayElements(data->array, data->pixels, 0); + env->DeleteGlobalRef(data->array); /* Free image */ - mid = g_env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); - g_env->CallVoidMethod(g_ctx, mid, data->bmp); - g_env->DeleteGlobalRef(data->bmp); + mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); + env->CallVoidMethod(g_activity, mid, data->bmp); + env->DeleteGlobalRef(data->bmp); #elif defined __CELLOS_LV2__ free(data->pixels); #else diff --git a/src/image.h b/src/image/image.h similarity index 100% rename from src/image.h rename to src/image/image.h