Replace JNI primitive array critical calls with non-critical ones.
The glgen part.
Bug: 19235243
Change-Id: I69dfa84f15366808b964517c1ba270ddeb3c5940
diff --git a/opengl/tools/glgen/src/JType.java b/opengl/tools/glgen/src/JType.java
index c6e227e..5803a44 100644
--- a/opengl/tools/glgen/src/JType.java
+++ b/opengl/tools/glgen/src/JType.java
@@ -191,6 +191,84 @@
(baseType.indexOf("Buffer") != -1);
}
+ public JType getArrayTypeForTypedBuffer() {
+ if (!isTypedBuffer()) {
+ throw new RuntimeException("Not typed buffer type " + this);
+ }
+ switch (baseType) {
+ case "java.nio.ByteBuffer":
+ return new JType("byte", false, true);
+ case "java.nio.BooleanBuffer":
+ return new JType("boolean", false, true);
+ case "java.nio.ShortBuffer":
+ return new JType("short", false, true);
+ case "java.nio.CharBuffer":
+ return new JType("char", false, true);
+ case "java.nio.IntBuffer":
+ return new JType("int", false, true);
+ case "java.nio.LongBuffer":
+ return new JType("long", false, true);
+ case "java.nio.FloatBuffer":
+ return new JType("float", false, true);
+ case "java.nio.DoubleBuffer":
+ return new JType("double", false, true);
+ default:
+ throw new RuntimeException("Unknown typed buffer type " + this);
+ }
+ }
+
+ public String getArrayGetterForPrimitiveArray() {
+ if (!isArray() || isClass()) {
+ throw new RuntimeException("Not array type " + this);
+ }
+ switch (baseType) {
+ case "byte":
+ return "GetByteArrayElements";
+ case "boolean":
+ return "GetBooleanArrayElements";
+ case "short":
+ return "GetShortArrayElements";
+ case "char":
+ return "GetCharArrayElements";
+ case "int":
+ return "GetIntArrayElements";
+ case "long":
+ return "GetLongArrayElements";
+ case "float":
+ return "GetFloatArrayElements";
+ case "double":
+ return "GetDoubleArrayElements";
+ default:
+ throw new RuntimeException("Unknown array type " + this);
+ }
+ }
+
+ public String getArrayReleaserForPrimitiveArray() {
+ if (!isArray() || isClass()) {
+ throw new RuntimeException("Not array type " + this);
+ }
+ switch (baseType) {
+ case "byte":
+ return "ReleaseByteArrayElements";
+ case "boolean":
+ return "ReleaseBooleanArrayElements";
+ case "short":
+ return "ReleaseShortArrayElements";
+ case "char":
+ return "ReleaseCharArrayElements";
+ case "int":
+ return "ReleaseIntArrayElements";
+ case "long":
+ return "ReleaseLongArrayElements";
+ case "float":
+ return "ReleaseFloatArrayElements";
+ case "double":
+ return "ReleaseDoubleArrayElements";
+ default:
+ throw new RuntimeException("Unknown array type " + this);
+ }
+ }
+
public boolean isEGLHandle() {
return !isPrimitive() &&
(baseType.startsWith("EGL"));
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index e51b7a2..1bed05b 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -812,6 +812,7 @@
List<Integer> stringArgs = new ArrayList<Integer>();
int numBufferArgs = 0;
List<String> bufferArgNames = new ArrayList<String>();
+ List<JType> bufferArgTypes = new ArrayList<JType>();
// Emit JNI signature (arguments)
//
@@ -835,6 +836,7 @@
int cIndex = jfunc.getArgCIndex(i);
String cname = cfunc.getArgName(cIndex);
bufferArgNames.add(cname);
+ bufferArgTypes.add(jfunc.getArgType(i));
numBufferArgs++;
}
}
@@ -948,12 +950,25 @@
// Emit a single _array or multiple _XXXArray variables
if (numBufferArgs == 1) {
+ JType bufferType = bufferArgTypes.get(0);
+ if (bufferType.isTypedBuffer()) {
+ String typedArrayType = getJniType(bufferType.getArrayTypeForTypedBuffer());
+ out.println(indent + typedArrayType + " _array = (" + typedArrayType + ") 0;");
+ } else {
out.println(indent + "jarray _array = (jarray) 0;");
- out.println(indent + "jint _bufferOffset = (jint) 0;");
+ }
+ out.println(indent + "jint _bufferOffset = (jint) 0;");
} else {
for (int i = 0; i < numBufferArgs; i++) {
- out.println(indent + "jarray _" + bufferArgNames.get(i) +
- "Array = (jarray) 0;");
+ JType bufferType = bufferArgTypes.get(0);
+ if (bufferType.isTypedBuffer()) {
+ String typedArrayType = getJniType(bufferType.getArrayTypeForTypedBuffer());
+ out.println(indent + typedArrayType + " _" + bufferArgNames.get(i) +
+ "Array = (" + typedArrayType + ") 0;");
+ } else {
+ out.println(indent + "jarray _" + bufferArgNames.get(i) +
+ "Array = (jarray) 0;");
+ }
out.println(indent + "jint _" + bufferArgNames.get(i) +
"BufferOffset = (jint) 0;");
}
@@ -1135,9 +1150,10 @@
"_base = (" +
cfunc.getArgType(cIndex).getDeclaration() +
")");
+ String arrayGetter = jfunc.getArgType(idx).getArrayGetterForPrimitiveArray();
out.println(indent + " " +
(mUseCPlusPlus ? "_env" : "(*_env)") +
- "->GetPrimitiveArrayCritical(" +
+ "->" + arrayGetter + "(" +
(mUseCPlusPlus ? "" : "_env, ") +
jfunc.getArgName(idx) +
"_ref, (jboolean *)0);");
@@ -1209,7 +1225,7 @@
cfunc.getArgType(cIndex).getDeclaration() +
")getPointer(_env, " +
cname +
- "_buf, &" + array + ", &" + remaining + ", &" + bufferOffset +
+ "_buf, (jarray*)&" + array + ", &" + remaining + ", &" + bufferOffset +
");");
}
@@ -1244,9 +1260,17 @@
} else {
out.println(indent + "if (" + cname +" == NULL) {");
}
- out.println(indent + indent + "char * _" + cname + "Base = (char *)_env->GetPrimitiveArrayCritical(" + array + ", (jboolean *) 0);");
- out.println(indent + indent + cname + " = (" +cfunc.getArgType(cIndex).getDeclaration() +") (_" + cname + "Base + " + bufferOffset + ");");
- out.println(indent + "}");
+ JType argType = jfunc.getArgType(idx);
+ if (argType.isTypedBuffer()) {
+ String arrayGetter = argType.getArrayTypeForTypedBuffer().getArrayGetterForPrimitiveArray();
+ out.println(indent + indent + "char * _" + cname + "Base = (char *)_env->" + arrayGetter + "(" + array + ", (jboolean *) 0);");
+ out.println(indent + indent + cname + " = (" +cfunc.getArgType(cIndex).getDeclaration() +") (_" + cname + "Base + " + bufferOffset + ");");
+ out.println(indent + "}");
+ } else {
+ out.println(indent + indent + "char * _" + cname + "Base = (char *)_env->GetPrimitiveArrayCritical(" + array + ", (jboolean *) 0);");
+ out.println(indent + indent + cname + " = (" +cfunc.getArgType(cIndex).getDeclaration() +") (_" + cname + "Base + " + bufferOffset + ");");
+ out.println(indent + "}");
+ }
}
}
@@ -1336,12 +1360,13 @@
// the need to write back to the Java array
out.println(indent +
"if (" + jfunc.getArgName(idx) + "_base) {");
+ String arrayReleaser = jfunc.getArgType(idx).getArrayReleaserForPrimitiveArray();
out.println(indent + indent +
(mUseCPlusPlus ? "_env" : "(*_env)") +
- "->ReleasePrimitiveArrayCritical(" +
+ "->" + arrayReleaser + "(" +
(mUseCPlusPlus ? "" : "_env, ") +
jfunc.getArgName(idx) + "_ref, " +
- cfunc.getArgName(cIndex) +
+ "(j" + jfunc.getArgType(idx).getBaseType() + "*)" + cfunc.getArgName(cIndex) +
"_base,");
out.println(indent + indent + indent +
(cfunc.getArgType(cIndex).isConst() ?
@@ -1350,17 +1375,32 @@
out.println(indent + "}");
} else if (jfunc.getArgType(idx).isBuffer()) {
if (! isPointerFunc) {
+ JType argType = jfunc.getArgType(idx);
String array = numBufferArgs <= 1 ? "_array" :
"_" + cfunc.getArgName(cIndex) + "Array";
out.println(indent + "if (" + array + ") {");
- out.println(indent + indent +
- "releasePointer(_env, " + array + ", " +
- cfunc.getArgName(cIndex) +
- ", " +
- (cfunc.getArgType(cIndex).isConst() ?
- "JNI_FALSE" : (emitExceptionCheck ?
- "_exception ? JNI_FALSE : JNI_TRUE" : "JNI_TRUE")) +
- ");");
+ if (argType.isTypedBuffer()) {
+ String arrayReleaser =
+ argType.getArrayTypeForTypedBuffer().getArrayReleaserForPrimitiveArray();
+ out.println(indent + indent +
+ "_env->" + arrayReleaser + "(" + array + ", " +
+ "(j" + argType.getArrayTypeForTypedBuffer().getBaseType() + "*)" +
+ cfunc.getArgName(cIndex) +
+ ", " +
+ (cfunc.getArgType(cIndex).isConst() ?
+ "JNI_ABORT" : (emitExceptionCheck ?
+ "_exception ? JNI_ABORT : 0" : "0")) +
+ ");");
+ } else {
+ out.println(indent + indent +
+ "releasePointer(_env, " + array + ", " +
+ cfunc.getArgName(cIndex) +
+ ", " +
+ (cfunc.getArgType(cIndex).isConst() ?
+ "JNI_FALSE" : (emitExceptionCheck ?
+ "_exception ? JNI_FALSE : JNI_TRUE" : "JNI_TRUE")) +
+ ");");
+ }
out.println(indent + "}");
}
}