Merge change 4299 into donut
* changes: Allow pre-Donut apps to use indirect Buffers in GL11 Pointer methods.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
|
||||
package com.google.android.gles_jni;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import javax.microedition.khronos.opengles.GL10Ext;
|
||||
@@ -43,9 +49,30 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack {
|
||||
public GLImpl() {
|
||||
}
|
||||
|
||||
public void glGetPointerv(int pname, java.nio.Buffer[] params) {
|
||||
throw new UnsupportedOperationException("glGetPointerv");
|
||||
}
|
||||
public void glGetPointerv(int pname, java.nio.Buffer[] params) {
|
||||
throw new UnsupportedOperationException("glGetPointerv");
|
||||
}
|
||||
|
||||
private static boolean allowIndirectBuffers(String appName) {
|
||||
boolean result = false;
|
||||
int version = 0;
|
||||
IPackageManager pm = ActivityThread.getPackageManager();
|
||||
try {
|
||||
ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0);
|
||||
if (applicationInfo != null) {
|
||||
version = applicationInfo.targetSdkVersion;
|
||||
}
|
||||
} catch (android.os.RemoteException e) {
|
||||
// ignore
|
||||
}
|
||||
Log.e("OpenGLES", String.format(
|
||||
"Application %s (SDK target %d) called a GL11 Pointer method with an indirect Buffer.",
|
||||
appName, version));
|
||||
if (version <= Build.VERSION_CODES.CUPCAKE) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// C function void glActiveTexture ( GLenum texture )
|
||||
|
||||
|
||||
@@ -4,14 +4,31 @@ set -e
|
||||
rm -rf out generated
|
||||
|
||||
mkdir out
|
||||
|
||||
# Create dummy Java files for Android APIs that are used by the code we generate.
|
||||
# This allows us to test the generated code without building the rest of Android.
|
||||
|
||||
mkdir -p out/javax/microedition/khronos/opengles
|
||||
mkdir -p out/com/google/android/gles_jni
|
||||
mkdir -p out/android/app
|
||||
mkdir -p out/android/graphics
|
||||
mkdir -p out/android/opengl
|
||||
mkdir -p out/android/content
|
||||
mkdir -p out/android/content/pm
|
||||
mkdir -p out/android/os
|
||||
mkdir -p out/android/util
|
||||
|
||||
echo "package android.graphics;" > out/android/graphics/Canvas.java
|
||||
echo "public interface Canvas {}" >> out/android/graphics/Canvas.java
|
||||
|
||||
echo "package android.app; import android.content.pm.IPackageManager; public class ActivityThread { public static final ActivityThread currentActivityThread() { return null; } public static final String currentPackageName(){ return null; } public static IPackageManager getPackageManager() { return null;} }" > out/android/app/ActivityThread.java
|
||||
# echo "package android.content; import android.content.pm.PackageManager; public interface Context { public PackageManager getPackageManager(); }" > out/android/content/Context.java
|
||||
echo "package android.content.pm; public class ApplicationInfo {public int targetSdkVersion;}" > out/android/content/pm/ApplicationInfo.java
|
||||
echo "package android.content.pm; public interface IPackageManager {ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags) throws android.os.RemoteException;}" > out/android/content/pm/IPackageManager.java
|
||||
echo "package android.os; public class Build {public static class VERSION_CODES { public static final int CUPCAKE = 3;}; }" > out/android/os/Build.java
|
||||
echo "package android.os; public class RemoteException extends Exception {}" > out/android/os/RemoteException.java
|
||||
echo "package android.util; public class Log {public static void w(String a, String b) {} public static void e(String a, String b) {}}" > out/android/util/Log.java
|
||||
|
||||
GLFILE=out/javax/microedition/khronos/opengles/GL.java
|
||||
cp stubs/jsr239/GLHeader.java-if $GLFILE
|
||||
|
||||
|
||||
@@ -44,9 +44,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;
|
||||
@@ -62,13 +64,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 =
|
||||
@@ -118,6 +124,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);
|
||||
@@ -132,17 +141,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
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
|
||||
package com.google.android.gles_jni;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import javax.microedition.khronos.opengles.GL10Ext;
|
||||
@@ -42,7 +48,28 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack {
|
||||
public GLImpl() {
|
||||
}
|
||||
|
||||
public void glGetPointerv(int pname, java.nio.Buffer[] params) {
|
||||
throw new UnsupportedOperationException("glGetPointerv");
|
||||
}
|
||||
public void glGetPointerv(int pname, java.nio.Buffer[] params) {
|
||||
throw new UnsupportedOperationException("glGetPointerv");
|
||||
}
|
||||
|
||||
private static boolean allowIndirectBuffers(String appName) {
|
||||
boolean result = false;
|
||||
int version = 0;
|
||||
IPackageManager pm = ActivityThread.getPackageManager();
|
||||
try {
|
||||
ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0);
|
||||
if (applicationInfo != null) {
|
||||
version = applicationInfo.targetSdkVersion;
|
||||
}
|
||||
} catch (android.os.RemoteException e) {
|
||||
// ignore
|
||||
}
|
||||
Log.e("OpenGLES", String.format(
|
||||
"Application %s (SDK target %d) called a GL11 Pointer method with an indirect Buffer.",
|
||||
appName, version));
|
||||
if (version <= Build.VERSION_CODES.CUPCAKE) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user