diff options
author | Jack Palevich <jackpal@google.com> | 2009-06-15 21:03:24 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-06-15 21:03:24 -0700 |
commit | 91a27ae2fec23b420244258636d2370117e86f5e (patch) | |
tree | 5b2b1b47724a16dfb5b0b3f1850ff8e6c5606808 /core | |
parent | 7d143b89b714e077f8fd7dbac80945c76bfd9814 (diff) | |
download | frameworks_base-91a27ae2fec23b420244258636d2370117e86f5e.zip frameworks_base-91a27ae2fec23b420244258636d2370117e86f5e.tar.gz frameworks_base-91a27ae2fec23b420244258636d2370117e86f5e.tar.bz2 |
Allow pre-Donut apps to use indirect Buffers in GL11 Pointer methods.
Apps targeting Donut and newer will throw an exception.
We use a heuristic to determine whether an app is pre-Donut or not:
We take the address space's __progname, and use that as the application's
package name. For simple applications this is correct.
Diffstat (limited to 'core')
-rw-r--r-- | core/jni/com_google_android_gles_jni_GLImpl.cpp | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp index 15e3a81..89b1f96 100644 --- a/core/jni/com_google_android_gles_jni_GLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp @@ -45,9 +45,11 @@ static jclass OOMEClass; static jclass UOEClass; static jclass IAEClass; static jclass AIOOBEClass; +static jclass G11ImplClass; static jmethodID getBasePointerID; static jmethodID getBaseArrayID; static jmethodID getBaseArrayOffsetID; +static jmethodID allowIndirectBuffersID; static jfieldID positionID; static jfieldID limitID; static jfieldID elementSizeShiftID; @@ -63,13 +65,17 @@ nativeClassInitBuffer(JNIEnv *_env) jclass bufferClassLocal = _env->FindClass("java/nio/Buffer"); bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal); + jclass g11impClassLocal = _env->FindClass("com/google/android/gles_jni/GLImpl"); + G11ImplClass = (jclass) _env->NewGlobalRef(g11impClassLocal); + getBasePointerID = _env->GetStaticMethodID(nioAccessClass, "getBasePointer", "(Ljava/nio/Buffer;)J"); getBaseArrayID = _env->GetStaticMethodID(nioAccessClass, "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;"); getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass, "getBaseArrayOffset", "(Ljava/nio/Buffer;)I"); - + allowIndirectBuffersID = _env->GetStaticMethodID(g11impClassLocal, + "allowIndirectBuffers", "(Ljava/lang/String;)Z"); positionID = _env->GetFieldID(bufferClass, "position", "I"); limitID = _env->GetFieldID(bufferClass, "limit", "I"); elementSizeShiftID = @@ -119,6 +125,9 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass, getBaseArrayID, buffer); + if (*array == NULL) { + return (void*) NULL; + } offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer); data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); @@ -133,17 +142,43 @@ releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit) commit ? 0 : JNI_ABORT); } +extern "C" { +extern char* __progname; +} + +static bool +allowIndirectBuffers(JNIEnv *_env) { + static jint sIndirectBufferCompatability; + if (sIndirectBufferCompatability == 0) { + jobject appName = _env->NewStringUTF(::__progname); + sIndirectBufferCompatability = _env->CallStaticBooleanMethod(G11ImplClass, allowIndirectBuffersID, appName) ? 2 : 1; + } + return sIndirectBufferCompatability == 2; +} + static void * getDirectBufferPointer(JNIEnv *_env, jobject buffer) { - char* buf = (char*) _env->GetDirectBufferAddress(buffer); + if (!buffer) { + return NULL; + } + void* buf = _env->GetDirectBufferAddress(buffer); if (buf) { jint position = _env->GetIntField(buffer, positionID); jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID); - buf += position << elementSizeShift; + buf = ((char*) buf) + (position << elementSizeShift); } else { - _env->ThrowNew(IAEClass, "Must use a native order direct Buffer"); + if (allowIndirectBuffers(_env)) { + jarray array = 0; + jint remaining; + buf = getPointer(_env, buffer, &array, &remaining); + if (array) { + releasePointer(_env, array, buf, 0); + } + } else { + _env->ThrowNew(IAEClass, "Must use a native order direct Buffer"); + } } - return (void*) buf; + return buf; } static int |