Почему мой вызов функции EGL изменяется при запуске ее в коде Java через JNI?

0

Я делаю некоторую работу в 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;
}
Теги:
jni
egl

2 ответа

0
Лучший ответ

Ага! Поэтому я нашел причину этого: я связывался с библиотеками 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.

1

В коде C++ EGL-дисплей представляет собой простое целое число. В Java-коде EGL-дисплей является объектом. Они печатаются по-разному.

Android в настоящее время определяет только экран по умолчанию.

  • 0
    Я полагаю, что EGL определяет EGLDisplay как пустоту *, которая выделяется драйвером. Android (или Java) инкапсулирует эту пустоту *, но «0» в конце «com.google.android.gles_jni.EGLDisplayImpl@0», похоже, соответствует значению указателя. disp равно EGL.EGL_NO_DISPLAY, когда внутри функции Java, и я не знаю почему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню