Я делаю некоторую работу в OpenGL и Java / Android. У меня есть код на C ++, и я использую JNI для взаимодействия между ними. Я получаю результаты:
D/App ( 2966): eglGetCurrentDisplay() 1
D/App ( 2966): thread id from c++ 2920
D/dalvikvm( 2966): threadid=11: interp stack at 0x613c5000
D/dalvikvm( 2966): init ref table
D/dalvikvm( 2966): init mutex
D/dalvikvm( 2966): create JNI env
D/dalvikvm( 2966): create fake frame
D/dalvikvm( 2966): threadid=11: adding to list (attached)
D/dalvikvm( 2966): threadid=11: attached from native, name=(null)
D/App ( 2966): thread id 2920
D/App ( 2966): EGL.eglGetCurrentDisplay is com.google.android.gles_jni.EGLDisplayImpl@0
Из кода ниже. Что означает, что текущий дисплей меняется, когда я вхожу в JNI. Почему это происходит? Поток не меняется, и я считаю, что локальное хранилище потока — это место, где драйвер будет хранить эту информацию.
код C ++:
printf("eglGetCurrentDisplay() %x\n", eglGetCurrentDisplay());
printf("thread id from c++ %d\n", (int)gettid());
int ret = Call_Java<int>("JNITest", "(I)I", 0 );
template<typename T>
T Call_Java(const char* sMethodName, const char* sMethodArgs, ...)
{
JavaVM *g_javaVMcached;
va_list argp;
jint res;
jobject obj;
getJavaCache(&obj, &g_javaVMcached);
assert(obj != 0);
JNIEnv * env = 0;
res = g_javaVMcached->AttachCurrentThread( &env, 0 );
assert( res == 0 && env != 0 )
jclass clazz = 0;
clazz = env->GetObjectClass( obj );
assert( clazz != 0 )
jmethodID methodID = env->GetMethodID( clazz, sMethodName, sMethodArgs ); // Name + Args
assert( methodID != 0 )
va_start(argp, sMethodArgs);
T result=0;
result = callJNIMethod<T>(obj, env, methodID, argp);
va_end(argp);
env->DeleteLocalRef( clazz );
return result;
}
template <>
int callJNIMethod(const jobject & obj, JNIEnv *env, jmethodID methodID, va_list args)
{
return env->CallIntMethodV(obj, methodID, args);
}
Java-код:
int JNITest(int test)
{
Log.d(TAG, "thread id " + (int)android.os.Process.myTid());
EGLDisplay disp = EGL.eglGetCurrentDisplay();
Log.d(TAG, "EGL.eglGetCurrentDisplay is " + disp);
return 0;
}
В коде C ++ отображение EGL представляет собой простое целое число. В коде Java отображение EGL является объектом. Это случается, чтобы напечатать по-другому.
Android в настоящее время определяет только отображение по умолчанию.
Ага! Поэтому я нашел причину этого: я связывался с библиотеками EGL в / vendor / lib / вместо библиотек в / system / lib /.
Индикатором этого было то, что когда я вызывал eglInitialize (), я НЕ получал следующий вывод журнала:
D/libEGL ( 4599): loaded /vendor/lib/egl/libEGL...
D/libEGL ( 4599): loaded /vendor/lib/egl/libGLESv1...
D/libEGL ( 4599): loaded /vendor/lib/egl/libGLESv2...
В то время как рабочая версия должна иметь эти строки в выходных данных журнала. Теперь это дает мне правильный вызов eglGetCurrentDisplay (), который не дает EGL_NO_DISPLAY.