Fix multithread issue. Do not use Global JNI env in C++

This commit is contained in:
Victor Shcherb 2012-04-28 14:22:56 +02:00
parent 00f3a870e7
commit dfb28d3670
9 changed files with 293 additions and 334 deletions

View file

@ -23,6 +23,8 @@
using namespace google::protobuf;
using namespace google::protobuf::internal;
static const int MAP_VERSION = 2;
struct BinaryMapFile;
@ -65,6 +67,7 @@ struct SearchQuery {
int bottom;
int zoom;
std::vector< MapDataObject*> result;
JNIEnv* env;
jobject o;
jfieldID interruptedField;
@ -78,15 +81,19 @@ struct SearchQuery {
int numberOfReadSubtrees;
int numberOfAcceptedSubtrees;
SearchQuery(int l, int r, int t, int b, RenderingRuleSearchRequest* req, jobject o, jfieldID interruptedField) :
SearchQuery(int l, int r, int t, int b, RenderingRuleSearchRequest* req, jobject o, jfieldID interruptedField, JNIEnv* env) :
req(req), left(l), right(r), top(t), bottom(b), o(o), interruptedField(interruptedField) {
numberOfAcceptedObjects = numberOfVisitedObjects = 0;
numberOfAcceptedSubtrees = numberOfReadSubtrees = 0;
ocean = land = false;
this->env = env;
}
bool isCancelled(){
return getGlobalJniEnv()->GetBooleanField(o, interruptedField);
if(env != NULL) {
return env->GetBooleanField(o, interruptedField);
}
return false;
}
};
@ -424,23 +431,21 @@ bool initMapStructure(io::CodedInputStream* input, BinaryMapFile* file) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Corrupted file. It should be ended as it starts with version");
return false;
}
if (version != 2) {
if (version != MAP_VERSION) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Version of the file is not supported.");
return false;
}
return true;
}
void loadJniBinaryRead() {
}
extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_deleteSearchResult(JNIEnv* ienv,
jobject obj, jint searchResult) {
// DO NOT DO IT it can leads to messing thread that is not allowed
// setGlobalJniEnv(ienv);
SearchResult* result = (SearchResult*) searchResult;
if(result != NULL){
deleteObjects(result->basemapCoastLines);
deleteObjects(result->result);
deleteObjects(result->coastLines);
deleteObjects(result->result);
delete result;
}
@ -849,22 +854,21 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
jobject obj, jint sleft, jint sright, jint stop, jint sbottom, jint zoom, jstring mapName,
jobject renderingRuleSearchRequest, bool skipDuplicates, jint searchResult, jobject objInterrupted) {
// TODO skipDuplicates not supported
setGlobalJniEnv(ienv);
SearchResult* result = (SearchResult*) searchResult;
if(result == NULL) {
result = new SearchResult();
}
std::string map = getString(mapName);
std::string map = getString(ienv, mapName);
std::map<std::string, BinaryMapFile*>::iterator i = openFiles.find(map);
if(i == openFiles.end()) {
return (jint) result;
}
BinaryMapFile* file = i->second;
RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest);
jclass clObjInterrupted = getGlobalJniEnv()->GetObjectClass(objInterrupted);
jfieldID interruptedField = getFid(clObjInterrupted, "interrupted", "Z");
getGlobalJniEnv()->DeleteLocalRef(clObjInterrupted);
SearchQuery q(sleft,sright, stop, sbottom, req, objInterrupted, interruptedField);
RenderingRuleSearchRequest* req = initSearchRequest(ienv, renderingRuleSearchRequest);
jclass clObjInterrupted = ienv->GetObjectClass(objInterrupted);
jfieldID interruptedField = getFid(ienv, clObjInterrupted, "interrupted", "Z");
ienv->DeleteLocalRef(clObjInterrupted);
SearchQuery q(sleft,sright, stop, sbottom, req, objInterrupted, interruptedField, ienv);
q.zoom = zoom;
fseek(file->f, 0, 0);
@ -919,7 +923,6 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
extern "C" JNIEXPORT jboolean JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_initBinaryMapFile(JNIEnv* ienv,
jobject obj, jobject path) {
// Verify that the version of the library that we linked against is
setGlobalJniEnv(ienv);
const char* utf = ienv->GetStringUTFChars((jstring) path, NULL);
std::string inputName(utf);
ienv->ReleaseStringUTFChars((jstring) path, utf);

View file

@ -12,109 +12,91 @@
const char* const LOG_TAG = "net.osmand:native";
JavaVM* globalJVM = NULL;
JNIEnv* globalJniEnv = NULL;
JNIEnv* getGlobalJniEnv()
{
return globalJniEnv;
}
JNIEnv* setGlobalJniEnv(JNIEnv* e)
{
if(!globalJVM)
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "No globalJVM set");
globalJVM->GetEnv((void**)&globalJniEnv, JNI_VERSION_1_6);
return globalJniEnv;
}
// Forward declarations
void loadJniCommon();
void loadJniRendering();
void loadJniRenderingRules();
void loadJniMapObjects();
void loadJniBinaryRead();
void loadJniCommon(JNIEnv* env);
void loadJniRendering(JNIEnv* env);
void loadJniRenderingRules(JNIEnv* env);
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv* globalJniEnv;
if(vm->GetEnv((void **)&globalJniEnv, JNI_VERSION_1_6))
return JNI_ERR; /* JNI version not supported */
globalJVM = vm;
loadJniCommon();
loadJniRendering();
loadJniRenderingRules();
loadJniMapObjects();
loadJniBinaryRead();
loadJniCommon(globalJniEnv);
loadJniRendering(globalJniEnv);
loadJniRenderingRules(globalJniEnv);
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI_OnLoad completed");
return JNI_VERSION_1_6;
}
void throwNewException(const char* msg)
void throwNewException(JNIEnv* env, const char* msg)
{
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, msg);
getGlobalJniEnv()->ThrowNew(getGlobalJniEnv()->FindClass("java/lang/Exception"), msg);
env->ThrowNew(env->FindClass("java/lang/Exception"), msg);
}
jclass findClass(const char* className, bool mustHave/* = true*/)
jclass findClass(JNIEnv* env, const char* className, bool mustHave/* = true*/)
{
jclass javaClass = getGlobalJniEnv()->FindClass(className);
jclass javaClass = env->FindClass(className);
if(!javaClass && mustHave)
throwNewException((std::string("Failed to find class ") + className).c_str());
return (jclass)newGlobalRef(javaClass);
throwNewException(env, (std::string("Failed to find class ") + className).c_str());
return (jclass)newGlobalRef(env, javaClass);
}
jobject newGlobalRef(jobject o)
jobject newGlobalRef(JNIEnv* env, jobject o)
{
return getGlobalJniEnv()->NewGlobalRef(o);
return env->NewGlobalRef(o);
}
jfieldID getFid(jclass cls, const char* fieldName, const char* sig)
jfieldID getFid(JNIEnv* env, jclass cls, const char* fieldName, const char* sig)
{
jfieldID jfield = getGlobalJniEnv()->GetFieldID(cls, fieldName, sig);
jfieldID jfield = env->GetFieldID(cls, fieldName, sig);
if(!jfield)
throwNewException((std::string("Failed to find field ") + fieldName + std::string(" with signature ") + sig).c_str());
throwNewException(env, (std::string("Failed to find field ") + fieldName + std::string(" with signature ") + sig).c_str());
return jfield;
}
std::string getStringField(jobject o, jfieldID fid)
std::string getStringField(JNIEnv* env, jobject o, jfieldID fid)
{
jstring jstr = (jstring)getGlobalJniEnv()->GetObjectField(o, fid);
jstring jstr = (jstring)env->GetObjectField(o, fid);
if(!jstr)
{
throwNewException("Failed to get object from field");
throwNewException(env, "Failed to get object from field");
return std::string();
}
const char* utfBytes = getGlobalJniEnv()->GetStringUTFChars(jstr, NULL);
const char* utfBytes = env->GetStringUTFChars(jstr, NULL);
//TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
std::string result(utfBytes);
getGlobalJniEnv()->ReleaseStringUTFChars(jstr, utfBytes);
getGlobalJniEnv()->DeleteLocalRef(jstr);
env->ReleaseStringUTFChars(jstr, utfBytes);
env->DeleteLocalRef(jstr);
return result;
}
std::string getString(jstring jstr)
std::string getString(JNIEnv* env, jstring jstr)
{
if(!jstr)
{
throwNewException("NULL jstring passed in");
throwNewException(env, "NULL jstring passed in");
return std::string();
}
const char* utfBytes = getGlobalJniEnv()->GetStringUTFChars(jstr, NULL);
const char* utfBytes = env->GetStringUTFChars(jstr, NULL);
//TODO: I'm not quite sure that if real unicode will happen here, this will work as expected
std::string result(utfBytes);
getGlobalJniEnv()->ReleaseStringUTFChars(jstr, utfBytes);
env->ReleaseStringUTFChars(jstr, utfBytes);
return result;
}
std::string getStringMethod(jobject o, jmethodID fid)
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid)
{
return getString((jstring)getGlobalJniEnv()->CallObjectMethod(o, fid));
return getString(env, (jstring)env->CallObjectMethod(o, fid));
}
std::string getStringMethod(jobject o, jmethodID fid, int i)
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid, int i)
{
return getString((jstring)getGlobalJniEnv()->CallObjectMethod(o, fid, i));
return getString(env, (jstring)env->CallObjectMethod(o, fid, i));
}
jclass jclass_RenderingContext = NULL;
@ -144,89 +126,82 @@ jfieldID jfield_RenderingContext_ctx = NULL;
jfieldID jfield_RenderingContext_textRenderingTime = NULL;
jfieldID jfield_RenderingContext_lastRenderedKey = NULL;
void loadJniCommon()
void loadJniCommon(JNIEnv* env)
{
jclass_RenderingContext = findClass("net/osmand/plus/render/OsmandRenderer$RenderingContext");
jfield_RenderingContext_interrupted = getFid(jclass_RenderingContext, "interrupted", "Z");
jfield_RenderingContext_leftX = getFid( jclass_RenderingContext, "leftX", "F" );
jfield_RenderingContext_topY = getFid( jclass_RenderingContext, "topY", "F" );
jfield_RenderingContext_width = getFid( jclass_RenderingContext, "width", "I" );
jfield_RenderingContext_height = getFid( jclass_RenderingContext, "height", "I" );
jfield_RenderingContext_zoom = getFid( jclass_RenderingContext, "zoom", "I" );
jfield_RenderingContext_rotate = getFid( jclass_RenderingContext, "rotate", "F" );
jfield_RenderingContext_tileDivisor = getFid( jclass_RenderingContext, "tileDivisor", "F" );
jfield_RenderingContext_pointCount = getFid( jclass_RenderingContext, "pointCount", "I" );
jfield_RenderingContext_pointInsideCount = getFid( jclass_RenderingContext, "pointInsideCount", "I" );
jfield_RenderingContext_visible = getFid( jclass_RenderingContext, "visible", "I" );
jfield_RenderingContext_allObjects = getFid( jclass_RenderingContext, "allObjects", "I" );
jfield_RenderingContext_cosRotateTileSize = getFid( jclass_RenderingContext, "cosRotateTileSize", "F" );
jfield_RenderingContext_sinRotateTileSize = getFid( jclass_RenderingContext, "sinRotateTileSize", "F" );
jfield_RenderingContext_density = getFid( jclass_RenderingContext, "density", "F" );
jfield_RenderingContext_highResMode = getFid( jclass_RenderingContext, "highResMode", "Z" );
jfield_RenderingContext_mapTextSize = getFid( jclass_RenderingContext, "mapTextSize", "F" );
jfield_RenderingContext_shadowRenderingMode = getFid( jclass_RenderingContext, "shadowRenderingMode", "I" );
jfield_RenderingContext_shadowLevelMin = getFid( jclass_RenderingContext, "shadowLevelMin", "I" );
jfield_RenderingContext_shadowLevelMax = getFid( jclass_RenderingContext, "shadowLevelMax", "I" );
jfield_RenderingContext_ctx = getFid( jclass_RenderingContext, "ctx", "Landroid/content/Context;" );
jfield_RenderingContext_textRenderingTime = getFid( jclass_RenderingContext, "textRenderingTime", "I" );
jfield_RenderingContext_lastRenderedKey = getFid( jclass_RenderingContext, "lastRenderedKey", "I" );
jclass_RenderingContext = findClass(env, "net/osmand/plus/render/OsmandRenderer$RenderingContext");
jfield_RenderingContext_interrupted = getFid(env, jclass_RenderingContext, "interrupted", "Z");
jfield_RenderingContext_leftX = getFid(env, jclass_RenderingContext, "leftX", "F" );
jfield_RenderingContext_topY = getFid(env, jclass_RenderingContext, "topY", "F" );
jfield_RenderingContext_width = getFid(env, jclass_RenderingContext, "width", "I" );
jfield_RenderingContext_height = getFid(env, jclass_RenderingContext, "height", "I" );
jfield_RenderingContext_zoom = getFid(env, jclass_RenderingContext, "zoom", "I" );
jfield_RenderingContext_rotate = getFid(env, jclass_RenderingContext, "rotate", "F" );
jfield_RenderingContext_tileDivisor = getFid(env, jclass_RenderingContext, "tileDivisor", "F" );
jfield_RenderingContext_pointCount = getFid(env, jclass_RenderingContext, "pointCount", "I" );
jfield_RenderingContext_pointInsideCount = getFid(env, jclass_RenderingContext, "pointInsideCount", "I" );
jfield_RenderingContext_visible = getFid(env, jclass_RenderingContext, "visible", "I" );
jfield_RenderingContext_allObjects = getFid(env, jclass_RenderingContext, "allObjects", "I" );
jfield_RenderingContext_cosRotateTileSize = getFid(env, jclass_RenderingContext, "cosRotateTileSize", "F" );
jfield_RenderingContext_sinRotateTileSize = getFid(env, jclass_RenderingContext, "sinRotateTileSize", "F" );
jfield_RenderingContext_density = getFid(env, jclass_RenderingContext, "density", "F" );
jfield_RenderingContext_highResMode = getFid(env, jclass_RenderingContext, "highResMode", "Z" );
jfield_RenderingContext_mapTextSize = getFid(env, jclass_RenderingContext, "mapTextSize", "F" );
jfield_RenderingContext_shadowRenderingMode = getFid(env, jclass_RenderingContext, "shadowRenderingMode", "I" );
jfield_RenderingContext_shadowLevelMin = getFid(env, jclass_RenderingContext, "shadowLevelMin", "I" );
jfield_RenderingContext_shadowLevelMax = getFid(env, jclass_RenderingContext, "shadowLevelMax", "I" );
jfield_RenderingContext_ctx = getFid(env, jclass_RenderingContext, "ctx", "Landroid/content/Context;" );
jfield_RenderingContext_textRenderingTime = getFid(env, jclass_RenderingContext, "textRenderingTime", "I" );
jfield_RenderingContext_lastRenderedKey = getFid(env, jclass_RenderingContext, "lastRenderedKey", "I" );
jclass_RenderingIcons = findClass("net/osmand/plus/render/RenderingIcons");
jmethod_RenderingIcons_getIconRawData = getGlobalJniEnv()->GetStaticMethodID(jclass_RenderingIcons,
jclass_RenderingIcons = findClass(env, "net/osmand/plus/render/RenderingIcons");
jmethod_RenderingIcons_getIconRawData = env->GetStaticMethodID(jclass_RenderingIcons,
"getIconRawData",
"(Landroid/content/Context;Ljava/lang/String;)[B");
}
//TODO: Dead code
/*
void unloadJniCommon() {
getGlobalJniEnv()->DeleteGlobalRef(jclass_RenderingIcons);
getGlobalJniEnv()->DeleteGlobalRef(jclass_RenderingContext);
}
*/
void pullFromJavaRenderingContext(jobject jrc, RenderingContext* rc)
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc)
{
rc->leftX = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_leftX );
rc->topY = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_topY );
rc->width = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_width );
rc->height = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_height );
rc->env = env;
rc->leftX = env->GetFloatField( jrc, jfield_RenderingContext_leftX );
rc->topY = env->GetFloatField( jrc, jfield_RenderingContext_topY );
rc->width = env->GetIntField( jrc, jfield_RenderingContext_width );
rc->height = env->GetIntField( jrc, jfield_RenderingContext_height );
rc->zoom = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_zoom );
rc->rotate = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_rotate );
rc->tileDivisor = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_tileDivisor );
rc->zoom = env->GetIntField( jrc, jfield_RenderingContext_zoom );
rc->rotate = env->GetFloatField( jrc, jfield_RenderingContext_rotate );
rc->tileDivisor = env->GetFloatField( jrc, jfield_RenderingContext_tileDivisor );
rc->pointCount = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_pointCount );
rc->pointInsideCount = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_pointInsideCount );
rc->visible = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_visible );
rc->allObjects = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_allObjects );
rc->pointCount = env->GetIntField( jrc, jfield_RenderingContext_pointCount );
rc->pointInsideCount = env->GetIntField( jrc, jfield_RenderingContext_pointInsideCount );
rc->visible = env->GetIntField( jrc, jfield_RenderingContext_visible );
rc->allObjects = env->GetIntField( jrc, jfield_RenderingContext_allObjects );
rc->cosRotateTileSize = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_cosRotateTileSize );
rc->sinRotateTileSize = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_sinRotateTileSize );
rc->density = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_density );
rc->highResMode = getGlobalJniEnv()->GetBooleanField( jrc, jfield_RenderingContext_highResMode );
rc->mapTextSize = getGlobalJniEnv()->GetFloatField( jrc, jfield_RenderingContext_mapTextSize );
rc->cosRotateTileSize = env->GetFloatField( jrc, jfield_RenderingContext_cosRotateTileSize );
rc->sinRotateTileSize = env->GetFloatField( jrc, jfield_RenderingContext_sinRotateTileSize );
rc->density = env->GetFloatField( jrc, jfield_RenderingContext_density );
rc->highResMode = env->GetBooleanField( jrc, jfield_RenderingContext_highResMode );
rc->mapTextSize = env->GetFloatField( jrc, jfield_RenderingContext_mapTextSize );
rc->shadowRenderingMode = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_shadowRenderingMode );
rc->shadowLevelMin = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_shadowLevelMin );
rc->shadowLevelMax = getGlobalJniEnv()->GetIntField( jrc, jfield_RenderingContext_shadowLevelMax );
rc->androidContext = getGlobalJniEnv()->GetObjectField(jrc, jfield_RenderingContext_ctx );
rc->shadowRenderingMode = env->GetIntField( jrc, jfield_RenderingContext_shadowRenderingMode );
rc->shadowLevelMin = env->GetIntField( jrc, jfield_RenderingContext_shadowLevelMin );
rc->shadowLevelMax = env->GetIntField( jrc, jfield_RenderingContext_shadowLevelMax );
rc->androidContext = env->GetObjectField(jrc, jfield_RenderingContext_ctx );
rc->lastRenderedKey = 0;
rc->javaRenderingContext = jrc;
}
void pushToJavaRenderingContext(jobject jrc, RenderingContext* rc)
void pushToJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc)
{
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_pointCount, rc->pointCount);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_pointInsideCount, rc->pointInsideCount);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_visible, rc->visible);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_allObjects, rc->allObjects);
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_textRenderingTime, rc->textRendering.getElapsedTime());
getGlobalJniEnv()->SetIntField( jrc, jfield_RenderingContext_lastRenderedKey, rc->lastRenderedKey);
env->SetIntField( jrc, jfield_RenderingContext_pointCount, rc->pointCount);
env->SetIntField( jrc, jfield_RenderingContext_pointInsideCount, rc->pointInsideCount);
env->SetIntField( jrc, jfield_RenderingContext_visible, rc->visible);
env->SetIntField( jrc, jfield_RenderingContext_allObjects, rc->allObjects);
env->SetIntField( jrc, jfield_RenderingContext_textRenderingTime, rc->textRendering.getElapsedTime());
env->SetIntField( jrc, jfield_RenderingContext_lastRenderedKey, rc->lastRenderedKey);
getGlobalJniEnv()->DeleteLocalRef(rc->androidContext);
env->DeleteLocalRef(rc->androidContext);
}
TextDrawInfo::TextDrawInfo(std::string itext)
@ -263,7 +238,7 @@ RenderingContext::~RenderingContext()
bool RenderingContext::interrupted()
{
return getGlobalJniEnv()->GetBooleanField(javaRenderingContext, jfield_RenderingContext_interrupted);
return env->GetBooleanField(javaRenderingContext, jfield_RenderingContext_interrupted);
}
float getDensityValue(RenderingContext* rc, float val)
@ -323,6 +298,7 @@ int ElapsedTimer::getElapsedTime()
std::hash_map<std::string, SkBitmap*> cachedBitmaps;
SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResource)
{
JNIEnv* env = rc->env;
if(bitmapResource.size() == 0)
return NULL;
@ -333,13 +309,13 @@ SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResourc
rc->nativeOperations.pause();
jstring jstr = getGlobalJniEnv()->NewStringUTF(bitmapResource.c_str());
jbyteArray javaIconRawData = (jbyteArray)getGlobalJniEnv()->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconRawData, rc->androidContext, jstr);
jstring jstr = env->NewStringUTF(bitmapResource.c_str());
jbyteArray javaIconRawData = (jbyteArray)env->CallStaticObjectMethod(jclass_RenderingIcons, jmethod_RenderingIcons_getIconRawData, rc->androidContext, jstr);
if(!javaIconRawData)
return NULL;
jbyte* bitmapBuffer = getGlobalJniEnv()->GetByteArrayElements(javaIconRawData, NULL);
size_t bufferLen = getGlobalJniEnv()->GetArrayLength(javaIconRawData);
jbyte* bitmapBuffer = env->GetByteArrayElements(javaIconRawData, NULL);
size_t bufferLen = env->GetArrayLength(javaIconRawData);
// Decode bitmap
SkBitmap* iconBitmap = new SkBitmap();
@ -350,11 +326,11 @@ SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResourc
delete iconBitmap;
rc->nativeOperations.start();
getGlobalJniEnv()->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(javaIconRawData);
getGlobalJniEnv()->DeleteLocalRef(jstr);
env->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
env->DeleteLocalRef(javaIconRawData);
env->DeleteLocalRef(jstr);
throwNewException((std::string("Failed to decode ") + bitmapResource).c_str());
throwNewException(env, (std::string("Failed to decode ") + bitmapResource).c_str());
return NULL;
}
@ -362,9 +338,9 @@ SkBitmap* getCachedBitmap(RenderingContext* rc, const std::string& bitmapResourc
rc->nativeOperations.start();
getGlobalJniEnv()->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(javaIconRawData);
getGlobalJniEnv()->DeleteLocalRef(jstr);
env->ReleaseByteArrayElements(javaIconRawData, bitmapBuffer, JNI_ABORT);
env->DeleteLocalRef(javaIconRawData);
env->DeleteLocalRef(jstr);
return iconBitmap;
}

View file

@ -17,24 +17,22 @@
struct RenderingContext;
JNIEnv* getGlobalJniEnv();
JNIEnv* setGlobalJniEnv(JNIEnv*);
// Android helpers
extern const char* const LOG_TAG;
// JNI Helpers
void throwNewException(const char* msg);
jclass findClass(const char* className, bool mustHave = true);
std::string getString(jstring st);
std::string getStringMethod(jobject o, jmethodID fid, int i);
std::string getStringMethod(jobject o, jmethodID fid);
std::string getStringField(jobject o, jfieldID fid);
jobject newGlobalRef(jobject o);
jfieldID getFid(jclass cls, const char* fieldName, const char* sig);
void throwNewException(JNIEnv* env, const char* msg);
jclass findClass(JNIEnv* env, const char* className, bool mustHave = true);
std::string getString(JNIEnv* env, jstring st);
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid, int i);
std::string getStringMethod(JNIEnv* env, jobject o, jmethodID fid);
std::string getStringField(JNIEnv* env, jobject o, jfieldID fid);
jobject newGlobalRef(JNIEnv* env, jobject o);
jfieldID getFid(JNIEnv* env, jclass cls, const char* fieldName, const char* sig);
void pullFromJavaRenderingContext(jobject jrc, RenderingContext* rc);
void pushToJavaRenderingContext(jobject jrc, RenderingContext* rc);
void pullFromJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc);
void pushToJavaRenderingContext(JNIEnv* env, jobject jrc, RenderingContext* rc);
class ElapsedTimer
{
@ -101,6 +99,7 @@ struct RenderingContext
jobject javaRenderingContext;
jobject androidContext;
JNIEnv* env;
bool useEnglishNames;
std::vector<TextDrawInfo*> textToDraw;

View file

@ -1,14 +1,9 @@
#ifndef _OSMAND_MAP_OBJECTSTagValuePairClass
#ifndef _OSMAND_MAP_OBJECTS
#define _OSMAND_MAP_OBJECTS
#include <jni.h>
#include <vector>
#include "common.h"
#include "mapObjects.h"
void deleteObjects(std::vector <MapDataObject* > & v)
{
for(size_t i = 0; i< v.size(); i++)
@ -18,15 +13,4 @@ void deleteObjects(std::vector <MapDataObject* > & v)
v.clear();
}
void loadJniMapObjects()
{
}
void unloadJniMapObjects()
{
}
#endif /*_OSMAND_MAP_OBJECTS*/

View file

@ -68,16 +68,16 @@ public:
struct SearchResult {
std::vector< MapDataObject* > result;
int count;
std::vector< MapDataObject* > tempResult;
std::vector< MapDataObject* > basemapResult;
std::vector< MapDataObject* > coastLines;
std::vector< MapDataObject* > basemapCoastLines;
};
//std::vector <BaseMapDataObject* > marshalObjects(jobjectArray binaryMapDataObjects);
void deleteObjects(std::vector <MapDataObject* > & v);
void loadJniMapObjects();
void unloadJniMapObjects();
#endif /*_OSMAND_MAP_OBJECTS_H*/

View file

@ -78,55 +78,55 @@ int RenderingRulesStorage::getDictionaryValue(std::string s) {
return dictionaryMap[s];
}
void RenderingRulesStorage::initDictionary() {
jobject listDictionary = getGlobalJniEnv()->GetObjectField(javaStorage, RenderingRulesStorageClass_dictionary);
uint sz = getGlobalJniEnv()->CallIntMethod(listDictionary, List_size);
void RenderingRulesStorage::initDictionary(JNIEnv* env) {
jobject listDictionary = env->GetObjectField(javaStorage, RenderingRulesStorageClass_dictionary);
uint sz = env->CallIntMethod(listDictionary, List_size);
uint i = 0;
for (; i < sz; i++) {
jstring st = (jstring) getGlobalJniEnv()->CallObjectMethod(listDictionary, List_get, i);
jstring st = (jstring) env->CallObjectMethod(listDictionary, List_get, i);
// if(st != NULL)
// {
const char* utf = getGlobalJniEnv()->GetStringUTFChars(st, NULL);
const char* utf = env->GetStringUTFChars(st, NULL);
std::string d = std::string(utf);
getGlobalJniEnv()->ReleaseStringUTFChars(st, utf);
getGlobalJniEnv()->DeleteLocalRef(st);
env->ReleaseStringUTFChars(st, utf);
env->DeleteLocalRef(st);
dictionary.push_back(d);
dictionaryMap[d] = i;
// }
}
getGlobalJniEnv()->DeleteLocalRef(listDictionary);
env->DeleteLocalRef(listDictionary);
}
void RenderingRulesStorage::initProperties() {
jobject props = getGlobalJniEnv()->GetObjectField(javaStorage, RenderingRulesStorage_PROPS);
jobject listProps = getGlobalJniEnv()->GetObjectField(props, RenderingRuleStorageProperties_rules);
uint sz = getGlobalJniEnv()->CallIntMethod(listProps, List_size);
void RenderingRulesStorage::initProperties(JNIEnv* env) {
jobject props = env->GetObjectField(javaStorage, RenderingRulesStorage_PROPS);
jobject listProps = env->GetObjectField(props, RenderingRuleStorageProperties_rules);
uint sz = env->CallIntMethod(listProps, List_size);
uint i = 0;
for (; i < sz; i++) {
jobject rulePrope = getGlobalJniEnv()->CallObjectMethod(listProps, List_get, i);
bool input = (getGlobalJniEnv()->GetBooleanField(rulePrope, RenderingRuleProperty_input) == JNI_TRUE);
int type = getGlobalJniEnv()->GetIntField(rulePrope, RenderingRuleProperty_type);
std::string name = getStringField(rulePrope, RenderingRuleProperty_attrName);
jobject rulePrope = env->CallObjectMethod(listProps, List_get, i);
bool input = (env->GetBooleanField(rulePrope, RenderingRuleProperty_input) == JNI_TRUE);
int type = env->GetIntField(rulePrope, RenderingRuleProperty_type);
std::string name = getStringField(env, rulePrope, RenderingRuleProperty_attrName);
RenderingRuleProperty* prop = new RenderingRuleProperty(type, input, name, i);
properties.push_back(*prop);
propertyMap[name] = prop;
getGlobalJniEnv()->DeleteLocalRef(rulePrope);
env->DeleteLocalRef(rulePrope);
}
getGlobalJniEnv()->DeleteLocalRef(props);
getGlobalJniEnv()->DeleteLocalRef(listProps);
env->DeleteLocalRef(props);
env->DeleteLocalRef(listProps);
}
void RenderingRulesStorage::initRules() {
void RenderingRulesStorage::initRules(JNIEnv* env) {
for (int i = 1; i < SIZE_STATES; i++) {
jobjectArray rules = (jobjectArray) getGlobalJniEnv()->CallObjectMethod(javaStorage, RenderingRulesStorage_getRules,
jobjectArray rules = (jobjectArray) env->CallObjectMethod(javaStorage, RenderingRulesStorage_getRules,
i);
jsize len = getGlobalJniEnv()->GetArrayLength(rules);
jsize len = env->GetArrayLength(rules);
for (jsize j = 0; j < len; j++) {
jobject rRule = getGlobalJniEnv()->GetObjectArrayElement(rules, j);
RenderingRule* rule = createRenderingRule(rRule);
getGlobalJniEnv()->DeleteLocalRef(rRule);
jobject rRule = env->GetObjectArrayElement(rules, j);
RenderingRule* rule = createRenderingRule(env, rRule);
env->DeleteLocalRef(rRule);
if (rule != NULL) {
jsize psz = rule->properties.size();
@ -145,69 +145,69 @@ void RenderingRulesStorage::initRules() {
}
}
}
getGlobalJniEnv()->DeleteLocalRef(rules);
env->DeleteLocalRef(rules);
}
}
RenderingRule* RenderingRulesStorage::createRenderingRule(jobject rRule) {
RenderingRule* RenderingRulesStorage::createRenderingRule(JNIEnv* env, jobject rRule) {
RenderingRule* rule = new RenderingRule;
jobjectArray props = (jobjectArray) getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_properties);
jintArray intProps = (jintArray) getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_intProperties);
jfloatArray floatProps = (jfloatArray) getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_floatProperties);
jobject ifChildren = getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_ifChildren);
jobject ifElseChildren = getGlobalJniEnv()->GetObjectField(rRule, RenderingRule_ifElseChildren);
jobjectArray props = (jobjectArray) env->GetObjectField(rRule, RenderingRule_properties);
jintArray intProps = (jintArray) env->GetObjectField(rRule, RenderingRule_intProperties);
jfloatArray floatProps = (jfloatArray) env->GetObjectField(rRule, RenderingRule_floatProperties);
jobject ifChildren = env->GetObjectField(rRule, RenderingRule_ifChildren);
jobject ifElseChildren = env->GetObjectField(rRule, RenderingRule_ifElseChildren);
jsize sz = getGlobalJniEnv()->GetArrayLength(props);
jsize sz = env->GetArrayLength(props);
if (floatProps != NULL) {
jfloat* fe = getGlobalJniEnv()->GetFloatArrayElements(floatProps, NULL);
jfloat* fe = env->GetFloatArrayElements(floatProps, NULL);
for (int j = 0; j < sz; j++) {
rule->floatProperties.push_back(fe[j]);
}
getGlobalJniEnv()->ReleaseFloatArrayElements(floatProps, fe, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(floatProps);
env->ReleaseFloatArrayElements(floatProps, fe, JNI_ABORT);
env->DeleteLocalRef(floatProps);
} else {
rule->floatProperties.assign(sz, 0);
}
if (intProps != NULL) {
jint* ie = getGlobalJniEnv()->GetIntArrayElements(intProps, NULL);
jint* ie = env->GetIntArrayElements(intProps, NULL);
for (int j = 0; j < sz; j++) {
rule->intProperties.push_back(ie[j]);
}
getGlobalJniEnv()->ReleaseIntArrayElements(intProps, ie, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(intProps);
env->ReleaseIntArrayElements(intProps, ie, JNI_ABORT);
env->DeleteLocalRef(intProps);
} else {
rule->intProperties.assign(sz, -1);
}
for (jsize i = 0; i < sz; i++) {
jobject prop = getGlobalJniEnv()->GetObjectArrayElement(props, i);
std::string attr = getStringField(prop, RenderingRuleProperty_attrName);
jobject prop = env->GetObjectArrayElement(props, i);
std::string attr = getStringField(env, prop, RenderingRuleProperty_attrName);
RenderingRuleProperty* p = getProperty(attr.c_str());
rule->properties.push_back(p);
getGlobalJniEnv()->DeleteLocalRef(prop);
env->DeleteLocalRef(prop);
}
getGlobalJniEnv()->DeleteLocalRef(props);
env->DeleteLocalRef(props);
if (ifChildren != NULL) {
sz = getGlobalJniEnv()->CallIntMethod(ifChildren, List_size);
sz = env->CallIntMethod(ifChildren, List_size);
for (jsize i = 0; i < sz; i++) {
jobject o = getGlobalJniEnv()->CallObjectMethod(ifChildren, List_get, i);
rule->ifChildren.push_back(*createRenderingRule(o));
getGlobalJniEnv()->DeleteLocalRef(o);
jobject o = env->CallObjectMethod(ifChildren, List_get, i);
rule->ifChildren.push_back(*createRenderingRule(env, o));
env->DeleteLocalRef(o);
}
getGlobalJniEnv()->DeleteLocalRef(ifChildren);
env->DeleteLocalRef(ifChildren);
}
if (ifElseChildren != NULL) {
sz = getGlobalJniEnv()->CallIntMethod(ifElseChildren, List_size);
sz = env->CallIntMethod(ifElseChildren, List_size);
for (jsize i = 0; i < sz; i++) {
jobject o = getGlobalJniEnv()->CallObjectMethod(ifElseChildren, List_get, i);
rule->ifElseChildren.push_back(*createRenderingRule(o));
getGlobalJniEnv()->DeleteLocalRef(o);
jobject o = env->CallObjectMethod(ifElseChildren, List_get, i);
rule->ifElseChildren.push_back(*createRenderingRule(env, o));
env->DeleteLocalRef(o);
}
getGlobalJniEnv()->DeleteLocalRef(ifElseChildren);
env->DeleteLocalRef(ifElseChildren);
}
return rule;
@ -216,93 +216,92 @@ RenderingRule* RenderingRulesStorage::createRenderingRule(jobject rRule) {
// Global object
RenderingRulesStorage* defaultStorage = NULL;
void RenderingRuleSearchRequest::initObject(jobject rrs) {
void RenderingRuleSearchRequest::initObject(JNIEnv* env, jobject rrs) {
jsize sz;
jobjectArray oa = (jobjectArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_props);
sz = getGlobalJniEnv()->GetArrayLength(oa);
jobjectArray oa = (jobjectArray) env->GetObjectField(rrs, RenderingRuleSearchRequest_props);
sz = env->GetArrayLength(oa);
std::vector<RenderingRuleProperty*> requestProps;
for (jsize i = 0; i < sz; i++) {
jobject prop = getGlobalJniEnv()->GetObjectArrayElement(oa, i);
std::string attr = getStringField(prop, RenderingRuleProperty_attrName);
jobject prop = env->GetObjectArrayElement(oa, i);
std::string attr = getStringField(env, prop, RenderingRuleProperty_attrName);
RenderingRuleProperty* p = storage->getProperty(attr.c_str());
requestProps.push_back(p);
getGlobalJniEnv()->DeleteLocalRef(prop);
env->DeleteLocalRef(prop);
}
getGlobalJniEnv()->DeleteLocalRef(oa);
env->DeleteLocalRef(oa);
sz = storage->getPropertiesSize();
{
values = new int[sz];
jintArray ia = (jintArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_values);
jint* ie = getGlobalJniEnv()->GetIntArrayElements(ia, NULL);
jintArray ia = (jintArray) env->GetObjectField(rrs, RenderingRuleSearchRequest_values);
jint* ie = env->GetIntArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) {
values[requestProps.at(i)->id] = ie[i];
}
getGlobalJniEnv()->ReleaseIntArrayElements(ia, ie, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(ia);
env->ReleaseIntArrayElements(ia, ie, JNI_ABORT);
env->DeleteLocalRef(ia);
}
{
fvalues = new float[sz];
jfloatArray ia = (jfloatArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues);
jfloat* ie = getGlobalJniEnv()->GetFloatArrayElements(ia, NULL);
jfloatArray ia = (jfloatArray) env->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues);
jfloat* ie = env->GetFloatArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) {
fvalues[requestProps.at(i)->id] = ie[i];
}
getGlobalJniEnv()->ReleaseFloatArrayElements(ia, ie, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(ia);
env->ReleaseFloatArrayElements(ia, ie, JNI_ABORT);
env->DeleteLocalRef(ia);
}
{
savedValues = new int[sz];
jintArray ia = (jintArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_values);
jint* ie = getGlobalJniEnv()->GetIntArrayElements(ia, NULL);
jintArray ia = (jintArray) env->GetObjectField(rrs, RenderingRuleSearchRequest_values);
jint* ie = env->GetIntArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) {
savedValues[requestProps.at(i)->id] = ie[i];
}
getGlobalJniEnv()->ReleaseIntArrayElements(ia, ie, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(ia);
env->ReleaseIntArrayElements(ia, ie, JNI_ABORT);
env->DeleteLocalRef(ia);
}
{
savedFvalues = new float[sz];
jfloatArray ia = (jfloatArray) getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues);
jfloat* ie = getGlobalJniEnv()->GetFloatArrayElements(ia, NULL);
jfloatArray ia = (jfloatArray) env->GetObjectField(rrs, RenderingRuleSearchRequest_fvalues);
jfloat* ie = env->GetFloatArrayElements(ia, NULL);
for (int i = 0; i < sz; i++) {
savedFvalues[requestProps.at(i)->id] = ie[i];
}
getGlobalJniEnv()->ReleaseFloatArrayElements(ia, ie, JNI_ABORT);
getGlobalJniEnv()->DeleteLocalRef(ia);
env->ReleaseFloatArrayElements(ia, ie, JNI_ABORT);
env->DeleteLocalRef(ia);
}
}
extern "C" JNIEXPORT void JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_initRenderingRulesStorage(JNIEnv* ienv,
jobject obj, jobject storage) {
setGlobalJniEnv(ienv);
if (defaultStorage == NULL || defaultStorage->javaStorage != storage) {
// multi thread will not work?
if (defaultStorage != NULL) {
delete defaultStorage;
}
defaultStorage = new RenderingRulesStorage(storage);
defaultStorage = new RenderingRulesStorage(ienv, storage);
}
}
RenderingRuleSearchRequest::RenderingRuleSearchRequest(jobject rrs) :
RenderingRuleSearchRequest::RenderingRuleSearchRequest(JNIEnv* env, jobject rrs) :
renderingRuleSearch(rrs) {
jobject storage = getGlobalJniEnv()->GetObjectField(rrs, RenderingRuleSearchRequest_storage);
jobject storage = env->GetObjectField(rrs, RenderingRuleSearchRequest_storage);
if (defaultStorage == NULL || defaultStorage->javaStorage != storage) {
// multi thread will not work?
if (defaultStorage != NULL) {
delete defaultStorage;
}
defaultStorage = new RenderingRulesStorage(storage);
defaultStorage = new RenderingRulesStorage(env, storage);
}
getGlobalJniEnv()->DeleteLocalRef(storage);
env->DeleteLocalRef(storage);
this->storage = defaultStorage;
PROPS = new RenderingRulesStorageProperties(this->storage);
initObject(rrs);
initObject(env, rrs);
clearState();
}
@ -495,62 +494,62 @@ void RenderingRuleSearchRequest::setTagValueZoomLayer(std::string tag, std::stri
setStringFilter(PROPS->R_VALUE, val);
}
RenderingRuleSearchRequest* initSearchRequest(jobject renderingRuleSearchRequest) {
return new RenderingRuleSearchRequest(renderingRuleSearchRequest);
RenderingRuleSearchRequest* initSearchRequest(JNIEnv* env, jobject renderingRuleSearchRequest) {
return new RenderingRuleSearchRequest(env, renderingRuleSearchRequest);
}
void loadJniRenderingRules() {
RenderingRuleClass = findClass("net/osmand/render/RenderingRule");
RenderingRule_properties = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "properties",
void loadJniRenderingRules(JNIEnv* env) {
RenderingRuleClass = findClass(env, "net/osmand/render/RenderingRule");
RenderingRule_properties = env->GetFieldID(RenderingRuleClass, "properties",
"[Lnet/osmand/render/RenderingRuleProperty;");
RenderingRule_intProperties = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "intProperties", "[I");
RenderingRule_floatProperties = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "floatProperties", "[F");
RenderingRule_ifElseChildren = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "ifElseChildren", "Ljava/util/List;");
RenderingRule_ifChildren = getGlobalJniEnv()->GetFieldID(RenderingRuleClass, "ifChildren", "Ljava/util/List;");
RenderingRule_intProperties = env->GetFieldID(RenderingRuleClass, "intProperties", "[I");
RenderingRule_floatProperties = env->GetFieldID(RenderingRuleClass, "floatProperties", "[F");
RenderingRule_ifElseChildren = env->GetFieldID(RenderingRuleClass, "ifElseChildren", "Ljava/util/List;");
RenderingRule_ifChildren = env->GetFieldID(RenderingRuleClass, "ifChildren", "Ljava/util/List;");
RenderingRuleStoragePropertiesClass = findClass("net/osmand/render/RenderingRuleStorageProperties");
RenderingRuleStorageProperties_rules = getGlobalJniEnv()->GetFieldID(RenderingRuleStoragePropertiesClass, "rules",
RenderingRuleStoragePropertiesClass = findClass(env, "net/osmand/render/RenderingRuleStorageProperties");
RenderingRuleStorageProperties_rules = env->GetFieldID(RenderingRuleStoragePropertiesClass, "rules",
"Ljava/util/List;");
RenderingRulePropertyClass = findClass("net/osmand/render/RenderingRuleProperty");
RenderingRuleProperty_type = getGlobalJniEnv()->GetFieldID(RenderingRulePropertyClass, "type", "I");
RenderingRuleProperty_input = getGlobalJniEnv()->GetFieldID(RenderingRulePropertyClass, "input", "Z");
RenderingRuleProperty_attrName = getGlobalJniEnv()->GetFieldID(RenderingRulePropertyClass, "attrName",
RenderingRulePropertyClass = findClass(env, "net/osmand/render/RenderingRuleProperty");
RenderingRuleProperty_type = env->GetFieldID(RenderingRulePropertyClass, "type", "I");
RenderingRuleProperty_input = env->GetFieldID(RenderingRulePropertyClass, "input", "Z");
RenderingRuleProperty_attrName = env->GetFieldID(RenderingRulePropertyClass, "attrName",
"Ljava/lang/String;");
RenderingRulesStorageClass = findClass("net/osmand/render/RenderingRulesStorage");
RenderingRulesStorageClass_dictionary = getGlobalJniEnv()->GetFieldID(RenderingRulesStorageClass, "dictionary",
RenderingRulesStorageClass = findClass(env, "net/osmand/render/RenderingRulesStorage");
RenderingRulesStorageClass_dictionary = env->GetFieldID(RenderingRulesStorageClass, "dictionary",
"Ljava/util/List;");
RenderingRulesStorage_PROPS = getGlobalJniEnv()->GetFieldID(RenderingRulesStorageClass, "PROPS",
RenderingRulesStorage_PROPS = env->GetFieldID(RenderingRulesStorageClass, "PROPS",
"Lnet/osmand/render/RenderingRuleStorageProperties;");
RenderingRulesStorage_getRules = getGlobalJniEnv()->GetMethodID(RenderingRulesStorageClass, "getRules",
RenderingRulesStorage_getRules = env->GetMethodID(RenderingRulesStorageClass, "getRules",
"(I)[Lnet/osmand/render/RenderingRule;");
ListClass = findClass("java/util/List");
List_size = getGlobalJniEnv()->GetMethodID(ListClass, "size", "()I");
List_get = getGlobalJniEnv()->GetMethodID(ListClass, "get", "(I)Ljava/lang/Object;");
ListClass = findClass(env, "java/util/List");
List_size = env->GetMethodID(ListClass, "size", "()I");
List_get = env->GetMethodID(ListClass, "get", "(I)Ljava/lang/Object;");
RenderingRuleSearchRequestClass = findClass("net/osmand/render/RenderingRuleSearchRequest");
RenderingRuleSearchRequest_storage = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "storage",
RenderingRuleSearchRequestClass = findClass(env, "net/osmand/render/RenderingRuleSearchRequest");
RenderingRuleSearchRequest_storage = env->GetFieldID(RenderingRuleSearchRequestClass, "storage",
"Lnet/osmand/render/RenderingRulesStorage;");
RenderingRuleSearchRequest_props = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "props",
RenderingRuleSearchRequest_props = env->GetFieldID(RenderingRuleSearchRequestClass, "props",
"[Lnet/osmand/render/RenderingRuleProperty;");
RenderingRuleSearchRequest_values = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "values", "[I");
RenderingRuleSearchRequest_fvalues = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "fvalues", "[F");
RenderingRuleSearchRequest_savedValues = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "savedValues",
RenderingRuleSearchRequest_values = env->GetFieldID(RenderingRuleSearchRequestClass, "values", "[I");
RenderingRuleSearchRequest_fvalues = env->GetFieldID(RenderingRuleSearchRequestClass, "fvalues", "[F");
RenderingRuleSearchRequest_savedValues = env->GetFieldID(RenderingRuleSearchRequestClass, "savedValues",
"[I");
RenderingRuleSearchRequest_savedFvalues = getGlobalJniEnv()->GetFieldID(RenderingRuleSearchRequestClass, "savedFvalues",
RenderingRuleSearchRequest_savedFvalues = env->GetFieldID(RenderingRuleSearchRequestClass, "savedFvalues",
"[F");
}
void unloadJniRenderRules() {
getGlobalJniEnv()->DeleteGlobalRef(RenderingRuleSearchRequestClass);
getGlobalJniEnv()->DeleteGlobalRef(RenderingRuleClass);
getGlobalJniEnv()->DeleteGlobalRef(RenderingRulePropertyClass);
getGlobalJniEnv()->DeleteGlobalRef(RenderingRuleStoragePropertiesClass);
getGlobalJniEnv()->DeleteGlobalRef(RenderingRulesStorageClass);
getGlobalJniEnv()->DeleteGlobalRef(ListClass);
void unloadJniRenderRules(JNIEnv* env) {
env->DeleteGlobalRef(RenderingRuleSearchRequestClass);
env->DeleteGlobalRef(RenderingRuleClass);
env->DeleteGlobalRef(RenderingRulePropertyClass);
env->DeleteGlobalRef(RenderingRuleStoragePropertiesClass);
env->DeleteGlobalRef(RenderingRulesStorageClass);
env->DeleteGlobalRef(ListClass);
}

View file

@ -59,10 +59,10 @@ private:
std::hash_map<std::string, RenderingRuleProperty*> propertyMap;
RenderingRule* createRenderingRule(jobject rRule);
void initDictionary();
void initProperties();
void initRules();
RenderingRule* createRenderingRule(JNIEnv* env, jobject rRule);
void initDictionary(JNIEnv* env);
void initProperties(JNIEnv* env);
void initRules(JNIEnv* env);
public:
// No rules for multipolygon !!!
@ -73,12 +73,12 @@ public:
const static int POLYGON_RULES = 3;
const static int TEXT_RULES = 4;
const static int ORDER_RULES = 5;
RenderingRulesStorage(jobject storage) :
RenderingRulesStorage(JNIEnv* env, jobject storage) :
javaStorage(storage) {
tagValueGlobalRules = new std::hash_map<int, RenderingRule >[SIZE_STATES];
initDictionary();
initProperties();
initRules();
initDictionary(env);
initProperties(env);
initRules(env);
}
~RenderingRulesStorage() {
@ -211,10 +211,10 @@ private :
MapDataObject* obj;
bool searchInternal(int state, int tagKey, int valueKey, bool loadOutput);
void initObject(jobject rrs);
void initObject(JNIEnv* env, jobject rrs);
bool visitRule(RenderingRule* rule, bool loadOutput);
public:
RenderingRuleSearchRequest(jobject rrs);
RenderingRuleSearchRequest(JNIEnv* env, jobject rrs);
~RenderingRuleSearchRequest();
@ -249,10 +249,10 @@ public:
};
RenderingRuleSearchRequest* initSearchRequest(jobject renderingRuleSearchRequest);
RenderingRuleSearchRequest* initSearchRequest(JNIEnv* env, jobject renderingRuleSearchRequest);
void loadJNIRenderingRules();
void loadJNIRenderingRules(JNIEnv* env);
void unloadJniRenderRules();
void unloadJniRenderRules(JNIEnv* env);
#endif

View file

@ -191,11 +191,11 @@ void renderText(MapDataObject* obj, RenderingRuleSearchRequest* req, RenderingCo
if (it->second.length() > 0) {
std::string name = it->second;
if (rc->useEnglishNames) {
jstring n = getGlobalJniEnv()->NewStringUTF(name.c_str());
name = getString(
(jstring) getGlobalJniEnv()->CallStaticObjectMethod(jclass_JUnidecode,
jstring n = rc->env->NewStringUTF(name.c_str());
name = getString(rc->env,
(jstring) rc->env->CallStaticObjectMethod(jclass_JUnidecode,
jmethod_JUnidecode_unidecode, n));
getGlobalJniEnv()->DeleteLocalRef(n);
rc->env->DeleteLocalRef(n);
}
req->setInitialTagValueZoom(tag, value, rc->zoom, obj);
req->setIntFilter(req->props()->R_TEXT_LENGTH, name.length());
@ -597,17 +597,16 @@ void doRendering(std::vector <MapDataObject* > mapDataObjects, SkCanvas* canvas,
rc->textRendering.pause();
}
void loadJniRendering()
void loadJniRendering(JNIEnv* env)
{
jclass_JUnidecode = findClass("net/sf/junidecode/Junidecode");
jmethod_JUnidecode_unidecode = getGlobalJniEnv()->GetStaticMethodID(jclass_JUnidecode, "unidecode", "(Ljava/lang/String;)Ljava/lang/String;");
jclass_JUnidecode = findClass(env, "net/sf/junidecode/Junidecode");
jmethod_JUnidecode_unidecode = env->GetStaticMethodID(jclass_JUnidecode, "unidecode", "(Ljava/lang/String;)Ljava/lang/String;");
}
extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_generateRendering_1Direct( JNIEnv* ienv, jobject obj,
jobject renderingContext, jint searchResult,
jobject targetBitmap,
jboolean useEnglishNames, jobject renderingRuleSearchRequest, jint defaultColor) {
setGlobalJniEnv(ienv);
// libJniGraphics interface
typedef int (*PTR_AndroidBitmap_getInfo)(JNIEnv*, jobject, AndroidBitmapInfo*);
@ -642,7 +641,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
// Gain information about bitmap
AndroidBitmapInfo bitmapInfo;
if(dl_AndroidBitmap_getInfo(getGlobalJniEnv(), targetBitmap, &bitmapInfo) != ANDROID_BITMAP_RESUT_SUCCESS)
if(dl_AndroidBitmap_getInfo(ienv, targetBitmap, &bitmapInfo) != ANDROID_BITMAP_RESUT_SUCCESS)
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to execute AndroidBitmap_getInfo");
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Creating SkBitmap in native w:%d h:%d s:%d f:%d!", bitmapInfo.width, bitmapInfo.height, bitmapInfo.stride, bitmapInfo.format);
@ -661,7 +660,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
}
void* lockedBitmapData = NULL;
if(dl_AndroidBitmap_lockPixels(getGlobalJniEnv(), targetBitmap, &lockedBitmapData) != ANDROID_BITMAP_RESUT_SUCCESS || !lockedBitmapData) {
if(dl_AndroidBitmap_lockPixels(ienv, targetBitmap, &lockedBitmapData) != ANDROID_BITMAP_RESUT_SUCCESS || !lockedBitmapData) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to execute AndroidBitmap_lockPixels");
}
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Locked %d bytes at %p", bitmap->getSize(), lockedBitmapData);
@ -677,9 +676,9 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
ElapsedTimer initObjects;
initObjects.start();
RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest);
RenderingRuleSearchRequest* req = initSearchRequest(ienv, renderingRuleSearchRequest);
RenderingContext rc;
pullFromJavaRenderingContext(renderingContext, &rc);
pullFromJavaRenderingContext(ienv, renderingContext, &rc);
rc.useEnglishNames = useEnglishNames;
SearchResult* result = ((SearchResult*) searchResult);
// std::vector <BaseMapDataObject* > mapDataObjects = marshalObjects(binaryMapDataObjects);
@ -695,7 +694,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
}
rc.nativeOperations.pause();
pushToJavaRenderingContext(renderingContext, &rc);
pushToJavaRenderingContext(ienv, renderingContext, &rc);
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "End Rendering image");
if(dl_AndroidBitmap_unlockPixels(ienv, targetBitmap) != ANDROID_BITMAP_RESUT_SUCCESS) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to execute AndroidBitmap_unlockPixels");
@ -708,9 +707,9 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
delete bitmap;
// deleteObjects(mapDataObjects);
jclass resultClass = findClass("net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult");
jclass resultClass = findClass(ienv, "net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult");
jmethodID resultClassCtorId = getGlobalJniEnv()->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;)V");
jmethodID resultClassCtorId = ienv->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;)V");
#ifdef DEBUG_NAT_OPERATIONS
__android_log_print(ANDROID_LOG_INFO, LOG_TAG,"Native ok (init %d, native op %d) ", initObjects.getElapsedTime(), rc.nativeOperations.getElapsedTime());
@ -719,7 +718,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
#endif
/* Construct a result object */
jobject resultObject = getGlobalJniEnv()->NewObject(resultClass, resultClassCtorId, NULL);
jobject resultObject = ienv->NewObject(resultClass, resultClassCtorId, NULL);
return resultObject;
}
@ -730,7 +729,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
jobject renderingContext, jint searchResult,
jint requestedBitmapWidth, jint requestedBitmapHeight, jint rowBytes, jboolean isTransparent,
jboolean useEnglishNames, jobject renderingRuleSearchRequest, jint defaultColor) {
setGlobalJniEnv(ienv);
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Creating SkBitmap in native w:%d h:%d!", requestedBitmapWidth, requestedBitmapHeight);
@ -763,9 +761,9 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
ElapsedTimer initObjects;
initObjects.start();
RenderingRuleSearchRequest* req = initSearchRequest(renderingRuleSearchRequest);
RenderingRuleSearchRequest* req = initSearchRequest(ienv, renderingRuleSearchRequest);
RenderingContext rc;
pullFromJavaRenderingContext(renderingContext, &rc);
pullFromJavaRenderingContext(ienv, renderingContext, &rc);
rc.useEnglishNames = useEnglishNames;
SearchResult* result = ((SearchResult*) searchResult);
// std::vector <BaseMapDataObject* > mapDataObjects = marshalObjects(binaryMapDataObjects);
@ -781,7 +779,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
}
rc.nativeOperations.pause();
pushToJavaRenderingContext(renderingContext, &rc);
pushToJavaRenderingContext(ienv, renderingContext, &rc);
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "End Rendering image");
// delete variables
@ -791,7 +789,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_plus_render_NativeOsmandLib
delete bitmap;
// deleteObjects(mapDataObjects);
jclass resultClass = findClass("net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult");
jclass resultClass = findClass(ienv, "net/osmand/plus/render/NativeOsmandLibrary$RenderingGenerationResult");
jmethodID resultClassCtorId = ienv->GetMethodID(resultClass, "<init>", "(Ljava/nio/ByteBuffer;)V");

View file

@ -274,7 +274,7 @@ public class MapRenderRepositories {
return true;
}
private boolean loadVectorData(RectF dataBox, final int zoom, final RenderingRuleSearchRequest renderingReq, final boolean nightMode) {
private boolean loadVectorData(RectF dataBox, final int zoom, final RenderingRuleSearchRequest renderingReq) {
double cBottomLatitude = dataBox.bottom;
double cTopLatitude = dataBox.top;
double cLeftLongitude = dataBox.left;
@ -288,10 +288,10 @@ public class MapRenderRepositories {
return true;
}
try {
System.gc(); // to clear previous objects
int count = 0;
ArrayList<BinaryMapDataObject> tempResult = new ArrayList<BinaryMapDataObject>();
ArrayList<BinaryMapDataObject> basemapResult = new ArrayList<BinaryMapDataObject>();
System.gc(); // to clear previous objects
TLongSet ids = new TLongHashSet();
List<BinaryMapDataObject> coastLines = new ArrayList<BinaryMapDataObject>();
List<BinaryMapDataObject> basemapCoastLines = new ArrayList<BinaryMapDataObject>();
@ -507,7 +507,7 @@ public class MapRenderRepositories {
loaded = loadVectorDataNative(dataBox, requestedBox.getZoom(), renderingReq, nativeLib);
} else {
cNativeObjects = null;
loaded = loadVectorData(dataBox, requestedBox.getZoom(), renderingReq, nightMode);
loaded = loadVectorData(dataBox, requestedBox.getZoom(), renderingReq);
}
if (!loaded || checkWhetherInterrupted()) {