Merge change 4299 into donut

* changes:
  Allow pre-Donut apps to use indirect Buffers in GL11 Pointer methods.
This commit is contained in:
Android (Google) Code Review
2009-06-15 21:55:01 -07:00
5 changed files with 157 additions and 16 deletions

View File

@@ -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

View File

@@ -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 )

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}