summaryrefslogtreecommitdiffstats
path: root/opengl/tools/glgen/src
diff options
context:
space:
mode:
authorThomas Tafertshofer <tafertth@google.com>2012-06-15 16:22:43 -0700
committerThomas Tafertshofer <tafertth@google.com>2012-07-10 15:49:43 -0700
commit66a42db8cbfba902f72f0ace5ac448ef4bfd3951 (patch)
tree5d53f4def4f58232259a22c3629179ffe936f6e2 /opengl/tools/glgen/src
parent3443b333f16cd356d7cc7322810fe6188f58f1d9 (diff)
downloadframeworks_native-66a42db8cbfba902f72f0ace5ac448ef4bfd3951.zip
frameworks_native-66a42db8cbfba902f72f0ace5ac448ef4bfd3951.tar.gz
frameworks_native-66a42db8cbfba902f72f0ace5ac448ef4bfd3951.tar.bz2
improve glgen tool to support EGL1.4
- added EGL1.4 bindings generation - fixed bugs in GLES bindings Bug: 6709865 Change-Id: I04ac63f652e1968a51eb833f47e00336ea449980
Diffstat (limited to 'opengl/tools/glgen/src')
-rw-r--r--opengl/tools/glgen/src/CFunc.java8
-rw-r--r--opengl/tools/glgen/src/CType.java10
-rw-r--r--opengl/tools/glgen/src/EGLCodeEmitter.java58
-rw-r--r--opengl/tools/glgen/src/GenerateEGL.java109
-rw-r--r--opengl/tools/glgen/src/JType.java30
-rw-r--r--opengl/tools/glgen/src/JniCodeEmitter.java513
6 files changed, 581 insertions, 147 deletions
diff --git a/opengl/tools/glgen/src/CFunc.java b/opengl/tools/glgen/src/CFunc.java
index 4847694..a192c00 100644
--- a/opengl/tools/glgen/src/CFunc.java
+++ b/opengl/tools/glgen/src/CFunc.java
@@ -28,6 +28,7 @@ public class CFunc {
boolean hasPointerArg = false;
boolean hasTypedPointerArg = false;
+ boolean hasEGLHandleArg = false;
public CFunc(String original) {
this.original = original;
@@ -63,6 +64,9 @@ public class CFunc {
if (argType.isTypedPointer()) {
hasTypedPointerArg = true;
}
+ if (argType.isEGLHandle()) {
+ hasEGLHandleArg = true;
+ }
}
public int getNumArgs() {
@@ -95,6 +99,10 @@ public class CFunc {
return hasTypedPointerArg;
}
+ public boolean hasEGLHandleArg() {
+ return hasEGLHandleArg;
+ }
+
@Override
public String toString() {
String s = "Function " + fname + " returns " + ftype + ": ";
diff --git a/opengl/tools/glgen/src/CType.java b/opengl/tools/glgen/src/CType.java
index e0f0ca6..92950ea 100644
--- a/opengl/tools/glgen/src/CType.java
+++ b/opengl/tools/glgen/src/CType.java
@@ -53,6 +53,16 @@ public class CType {
return isPointer;
}
+ public boolean isEGLHandle() {
+ if(baseType.equals("EGLContext")
+ || baseType.equals("EGLConfig")
+ || baseType.equals("EGLSurface")
+ || baseType.equals("EGLDisplay")) {
+ return true;
+ }
+ return false;
+ }
+
boolean isVoid() {
String baseType = getBaseType();
return baseType.equals("GLvoid") ||
diff --git a/opengl/tools/glgen/src/EGLCodeEmitter.java b/opengl/tools/glgen/src/EGLCodeEmitter.java
new file mode 100644
index 0000000..1691b65
--- /dev/null
+++ b/opengl/tools/glgen/src/EGLCodeEmitter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.PrintStream;
+
+/**
+ * Emits a Java interface and Java & C implementation for a C function.
+ *
+ * <p> The Java interface will have Buffer and array variants for functions that
+ * have a typed pointer argument. The array variant will convert a single "<type> *data"
+ * argument to a pair of arguments "<type>[] data, int offset".
+ */
+public class EGLCodeEmitter extends JniCodeEmitter {
+
+ PrintStream mJavaImplStream;
+ PrintStream mCStream;
+
+ PrintStream mJavaInterfaceStream;
+
+ /**
+ */
+ public EGLCodeEmitter(String classPathName,
+ ParameterChecker checker,
+ PrintStream javaImplStream,
+ PrintStream cStream) {
+ mClassPathName = classPathName;
+ mChecker = checker;
+
+ mJavaImplStream = javaImplStream;
+ mCStream = cStream;
+ mUseContextPointer = false;
+ mUseStaticMethods = true;
+ mUseSimpleMethodNames = true;
+ mUseHideCommentForAPI = true;
+ }
+
+ public void emitCode(CFunc cfunc, String original) {
+ emitCode(cfunc, original, null, mJavaImplStream,
+ mCStream);
+ }
+
+ public void emitNativeRegistration(String nativeRegistrationName) {
+ emitNativeRegistration(nativeRegistrationName, mCStream);
+ }
+}
diff --git a/opengl/tools/glgen/src/GenerateEGL.java b/opengl/tools/glgen/src/GenerateEGL.java
new file mode 100644
index 0000000..aaa748c
--- /dev/null
+++ b/opengl/tools/glgen/src/GenerateEGL.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+
+public class GenerateEGL {
+
+ private static void copy(String filename, PrintStream out) throws IOException {
+ BufferedReader br = new BufferedReader(new FileReader(filename));
+ String s;
+ while ((s = br.readLine()) != null) {
+ out.println(s);
+ }
+ }
+
+ private static void emit(EGLCodeEmitter emitter,
+ BufferedReader specReader,
+ PrintStream glStream,
+ PrintStream cStream) throws Exception {
+ String s = null;
+ while ((s = specReader.readLine()) != null) {
+ if (s.trim().startsWith("//")) {
+ continue;
+ }
+
+ CFunc cfunc = CFunc.parseCFunc(s);
+
+ String fname = cfunc.getName();
+ String stubRoot = "stubs/egl/" + fname;
+ String javaPath = stubRoot + ".java";
+ File f = new File(javaPath);
+ if (f.exists()) {
+ System.out.println("Special-casing function " + fname);
+ copy(javaPath, glStream);
+ copy(stubRoot + ".cpp", cStream);
+
+ // Register native function names
+ // This should be improved to require fewer discrete files
+ String filename = stubRoot + ".nativeReg";
+ BufferedReader br =
+ new BufferedReader(new FileReader(filename));
+ String nfunc;
+ while ((nfunc = br.readLine()) != null) {
+ emitter.addNativeRegistration(nfunc);
+ }
+ } else {
+ emitter.emitCode(cfunc, s);
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ int aidx = 0;
+ while ((aidx < args.length) && (args[aidx].charAt(0) == '-')) {
+ switch (args[aidx].charAt(1)) {
+ default:
+ System.err.println("Unknown flag: " + args[aidx]);
+ System.exit(1);
+ }
+
+ aidx++;
+ }
+
+ BufferedReader checksReader =
+ new BufferedReader(new FileReader("specs/egl/checks.spec"));
+ ParameterChecker checker = new ParameterChecker(checksReader);
+
+
+ BufferedReader specReader =
+ new BufferedReader(new FileReader("specs/egl/EGL14.spec"));
+
+ String egljFilename = "android/opengl/EGL14.java";
+ String eglcFilename = "android_opengl_EGL14.cpp";
+ PrintStream egljStream =
+ new PrintStream(new FileOutputStream("out/" + egljFilename));
+ PrintStream eglcStream =
+ new PrintStream(new FileOutputStream("out/" + eglcFilename));
+ egljStream.println("/*");
+ eglcStream.println("/*");
+ copy("stubs/egl/EGL14Header.java-if", egljStream);
+ copy("stubs/egl/EGL14cHeader.cpp", eglcStream);
+ EGLCodeEmitter emitter = new EGLCodeEmitter(
+ "android/opengl/EGL14",
+ checker, egljStream, eglcStream);
+ emit(emitter, specReader, egljStream, eglcStream);
+ emitter.emitNativeRegistration("register_android_opengl_jni_EGL14");
+ egljStream.println("}");
+ egljStream.close();
+ eglcStream.close();
+ }
+}
diff --git a/opengl/tools/glgen/src/JType.java b/opengl/tools/glgen/src/JType.java
index deb2f01..3f7cb73 100644
--- a/opengl/tools/glgen/src/JType.java
+++ b/opengl/tools/glgen/src/JType.java
@@ -48,6 +48,22 @@ public class JType {
typeMapping.put(new CType("char", true, true), new JType("String", false, false));
typeMapping.put(new CType("int"), new JType("int"));
+ // EGL primitive types
+ typeMapping.put(new CType("EGLint"), new JType("int"));
+ typeMapping.put(new CType("EGLBoolean"), new JType("boolean"));
+ typeMapping.put(new CType("EGLenum"), new JType("int"));
+ typeMapping.put(new CType("EGLNativePixmapType"), new JType("int"));
+ typeMapping.put(new CType("EGLNativeWindowType"), new JType("int"));
+ typeMapping.put(new CType("EGLNativeDisplayType"), new JType("int"));
+ typeMapping.put(new CType("EGLClientBuffer"), new JType("int"));
+
+ // EGL nonprimitive types
+ typeMapping.put(new CType("EGLConfig"), new JType("EGLConfig", true, false));
+ typeMapping.put(new CType("EGLContext"), new JType("EGLContext", true, false));
+ typeMapping.put(new CType("EGLDisplay"), new JType("EGLDisplay", true, false));
+ typeMapping.put(new CType("EGLSurface"), new JType("EGLSurface", true, false));
+
+
// Untyped pointers map to untyped Buffers
typeMapping.put(new CType("GLvoid", true, true),
new JType("java.nio.Buffer", true, false));
@@ -88,7 +104,7 @@ public class JType {
arrayTypeMapping.put(new CType("char", false, true),
new JType("byte", false, true));
arrayTypeMapping.put(new CType("GLboolean", false, true),
- new JType("boolean", false, true));
+ new JType("boolean", false, true));
arrayTypeMapping.put(new CType("GLenum", false, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLfixed", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLfixed", false, true), new JType("int", false, true));
@@ -103,6 +119,13 @@ public class JType {
arrayTypeMapping.put(new CType("GLuint", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLintptr"), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLsizeiptr"), new JType("int", false, true));
+
+ //EGL typed pointers map to arrays + offsets
+ arrayTypeMapping.put(new CType("EGLint", false, true), new JType("int", false, true));
+ arrayTypeMapping.put(new CType("EGLint", true, true), new JType("int", false, true));
+ arrayTypeMapping.put(new CType("EGLConfig", false, true), new JType("EGLConfig", true, true));
+ arrayTypeMapping.put(new CType("EGLConfig", true, true), new JType("EGLConfig", true, true));
+
}
public JType() {
@@ -158,6 +181,11 @@ public class JType {
(baseType.indexOf("Buffer") != -1);
}
+ public boolean isEGLHandle() {
+ return !isPrimitive() &&
+ (baseType.startsWith("EGL"));
+ }
+
public static JType convert(CType ctype, boolean useArray) {
JType javaType = null;
if (useArray) {
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index 9fa2b74..af98889 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -25,6 +25,8 @@ public class JniCodeEmitter {
static final boolean mUseCPlusPlus = true;
protected boolean mUseContextPointer = true;
protected boolean mUseStaticMethods = false;
+ protected boolean mUseSimpleMethodNames = false;
+ protected boolean mUseHideCommentForAPI = false;
protected String mClassPathName;
protected ParameterChecker mChecker;
protected List<String> nativeRegistrations = new ArrayList<String>();
@@ -34,7 +36,9 @@ public class JniCodeEmitter {
public static String getJniName(JType jType) {
String jniName = "";
- if (jType.isClass()) {
+ if (jType.isEGLHandle()) {
+ return (jType.isArray() ? "[" : "" ) + "Landroid/opengl/" + jType.getBaseType() + ";";
+ } else if (jType.isClass()) {
return "L" + jType.getBaseType() + ";";
} else if (jType.isArray()) {
jniName = "[";
@@ -63,7 +67,6 @@ public class JniCodeEmitter {
return jniName;
}
-
public void emitCode(CFunc cfunc, String original,
PrintStream javaInterfaceStream,
PrintStream javaImplStream,
@@ -96,6 +99,10 @@ public class JniCodeEmitter {
if (!duplicate) {
emitJniCode(jfunc, cStream);
}
+ // Don't create IOBuffer versions of the EGL functions
+ if (cfunc.hasEGLHandleArg()) {
+ return;
+ }
}
jfunc = JFunc.convert(cfunc, false);
@@ -121,8 +128,13 @@ public class JniCodeEmitter {
}
public void emitNativeDeclaration(JFunc jfunc, PrintStream out) {
- out.println(" // C function " + jfunc.getCFunc().getOriginal());
- out.println();
+ if (mUseHideCommentForAPI) {
+ out.println(" /* @hide C function " + jfunc.getCFunc().getOriginal() + " */");
+ out.println();
+ } else {
+ out.println(" // C function " + jfunc.getCFunc().getOriginal());
+ out.println();
+ }
emitFunction(jfunc, out, true, false);
}
@@ -197,15 +209,17 @@ public class JniCodeEmitter {
out.println(iii + "}");
out.println(iii + "if (" + remaining + " < _needed) {");
- if (emitExceptionCheck) {
- out.println(iii + indent + "_exception = 1;");
- }
- out.println(iii + indent + "jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", " +
- "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < needed\");");
+ out.println(iii + indent + "_exception = 1;");
+ out.println(iii + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(iii + indent +
+ "_exceptionMessage = \"" +
+ (isBuffer ? "remaining()" : "length - " + offset) +
+ " < needed\";");
out.println(iii + indent + "goto exit;");
- needsExit = true;
out.println(iii + "}");
+
+ needsExit = true;
}
boolean isNullAllowed(CFunc cfunc) {
@@ -213,28 +227,70 @@ public class JniCodeEmitter {
int index = 1;
if (checks != null) {
while (index < checks.length) {
- if (checks[index].equals("return")) {
- index += 2;
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("unsupported")) {
- index += 1;
- } else if (checks[index].equals("requires")) {
- index += 2;
- } else if (checks[index].equals("nullAllowed")) {
+ if (checks[index].equals("nullAllowed")) {
+ return true;
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ return false;
+ }
+
+ boolean hasCheckTest(CFunc cfunc) {
+ String[] checks = mChecker.getChecks(cfunc.getName());
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("check")) {
+ return true;
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ return false;
+ }
+
+ boolean hasIfTest(CFunc cfunc) {
+ String[] checks = mChecker.getChecks(cfunc.getName());
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("ifcheck")) {
return true;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
return false;
}
+ int skipOneCheck(String[] checks, int index) {
+ if (checks[index].equals("return")) {
+ index += 2;
+ } else if (checks[index].startsWith("check")) {
+ index += 3;
+ } else if (checks[index].startsWith("sentinel")) {
+ index += 3;
+ } else if (checks[index].equals("ifcheck")) {
+ index += 5;
+ } else if (checks[index].equals("unsupported")) {
+ index += 1;
+ } else if (checks[index].equals("requires")) {
+ index += 2;
+ } else if (checks[index].equals("nullAllowed")) {
+ index += 1;
+ } else {
+ System.out.println("Error: unknown keyword \"" +
+ checks[index] + "\"");
+ System.exit(0);
+ }
+
+ return index;
+ }
+
String getErrorReturnValue(CFunc cfunc) {
CType returnType = cfunc.getType();
boolean isVoid = returnType.isVoid();
@@ -242,6 +298,10 @@ public class JniCodeEmitter {
return null;
}
+ if (returnType.getBaseType().startsWith("EGL")) {
+ return "(" + returnType.getDeclaration() + ") 0";
+ }
+
String[] checks = mChecker.getChecks(cfunc.getName());
int index = 1;
@@ -249,20 +309,8 @@ public class JniCodeEmitter {
while (index < checks.length) {
if (checks[index].equals("return")) {
return checks[index + 1];
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("unsupported")) {
- index += 1;
- } else if (checks[index].equals("requires")) {
- index += 2;
- } else if (checks[index].equals("nullAllowed")) {
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -277,20 +325,8 @@ public class JniCodeEmitter {
while (index < checks.length) {
if (checks[index].equals("unsupported")) {
return true;
- } else if (checks[index].equals("requires")) {
- index += 2;
- } else if (checks[index].equals("return")) {
- index += 2;
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("nullAllowed")) {
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -302,22 +338,10 @@ public class JniCodeEmitter {
int index = 1;
if (checks != null) {
while (index < checks.length) {
- if (checks[index].equals("unsupported")) {
- index += 1;
- } else if (checks[index].equals("requires")) {
+ if (checks[index].equals("requires")) {
return checks[index+1];
- } else if (checks[index].equals("return")) {
- index += 2;
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("nullAllowed")) {
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -345,9 +369,7 @@ public class JniCodeEmitter {
continue;
}
out.println(iii + "if (" + remaining + " < " + checks[index + 2] + ") {");
- if (emitExceptionCheck) {
- out.println(iii + indent + "_exception = 1;");
- }
+ out.println(iii + indent + "_exception = 1;");
String exceptionClassName = "java/lang/IllegalArgumentException";
// If the "check" keyword was of the form
// "check_<class name>", use the class name in the
@@ -361,14 +383,19 @@ public class JniCodeEmitter {
throw new RuntimeException("unknown exception abbreviation: " + abbr);
}
}
- out.println(iii + indent + "jniThrowException(_env, " +
- "\"" + exceptionClassName + "\", " +
- "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < " + checks[index + 2] + "\");");
+ out.println(iii + indent +
+ "_exceptionType = \""+exceptionClassName+"\";");
+ out.println(iii + indent +
+ "_exceptionMessage = \"" +
+ (isBuffer ? "remaining()" : "length - " +
+ offset) + " < " + checks[index + 2] +
+ " < needed\";");
out.println(iii + indent + "goto exit;");
- needsExit = true;
out.println(iii + "}");
+ needsExit = true;
+
index += 3;
} else if (checks[index].equals("ifcheck")) {
String[] matches = checks[index + 4].split(",");
@@ -388,21 +415,8 @@ public class JniCodeEmitter {
lastWasIfcheck = true;
index += 5;
- } else if (checks[index].equals("return")) {
- // ignore
- index += 2;
- } else if (checks[index].equals("unsupported")) {
- // ignore
- index += 1;
- } else if (checks[index].equals("requires")) {
- // ignore
- index += 2;
- } else if (checks[index].equals("nullAllowed")) {
- // ignore
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" + checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -412,6 +426,69 @@ public class JniCodeEmitter {
}
}
+ void emitSentinelCheck(CFunc cfunc, String cname, PrintStream out,
+ boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) {
+
+ String[] checks = mChecker.getChecks(cfunc.getName());
+
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("sentinel")) {
+ if (cname != null && !cname.equals(checks[index + 1])) {
+ index += 3;
+ continue;
+ }
+
+ out.println(iii + cname + "_sentinel = false;");
+ out.println(iii + "for (int i = " + remaining +
+ " - 1; i >= 0; i--) {");
+ out.println(iii + indent + "if (" + cname +
+ "[i] == " + checks[index + 2] + "){");
+ out.println(iii + indent + indent +
+ cname + "_sentinel = true;");
+ out.println(iii + indent + indent + "break;");
+ out.println(iii + indent + "}");
+ out.println(iii + "}");
+ out.println(iii +
+ "if (" + cname + "_sentinel == false) {");
+ out.println(iii + indent + "_exception = 1;");
+ out.println(iii + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(iii + indent + "_exceptionMessage = \"" + cname +
+ " must contain " + checks[index + 2] + "!\";");
+ out.println(iii + indent + "goto exit;");
+ out.println(iii + "}");
+
+ needsExit = true;
+ index += 3;
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ }
+
+ void emitLocalVariablesForSentinel(CFunc cfunc, PrintStream out) {
+
+ String[] checks = mChecker.getChecks(cfunc.getName());
+
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("sentinel")) {
+ String cname = checks[index + 1];
+ out.println(indent + "bool " + cname + "_sentinel = false;");
+
+ index += 3;
+
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ }
+
boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) {
if (nonPrimitiveArgs.size() > 0) {
for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
@@ -638,7 +715,7 @@ public class JniCodeEmitter {
return "j" + baseType;
}
} else if (jType.isArray()) {
- return "j" + baseType + "Array";
+ return jType.isClass() ? "jobjectArray" : "j" + baseType + "Array";
} else {
return "jobject";
}
@@ -698,8 +775,10 @@ public class JniCodeEmitter {
// Append signature to function name
String sig = getJniMangledName(signature).replace('.', '_').replace('/', '_');
- out.print("__" + sig);
- outName += "__" + sig;
+ if (!mUseSimpleMethodNames) {
+ out.print("__" + sig);
+ outName += "__" + sig;
+ }
signature = signature.replace('.', '/');
rsignature = rsignature.replace('.', '/');
@@ -734,11 +813,11 @@ public class JniCodeEmitter {
for (int i = 0; i < numArgs; i++) {
out.print(", ");
JType argType = jfunc.getArgType(i);
- String suffix;
+ String suffix = "";
if (!argType.isPrimitive()) {
if (argType.isArray()) {
suffix = "_ref";
- } else {
+ } else if (argType.isBuffer()) {
suffix = "_buf";
}
nonPrimitiveArgs.add(new Integer(i));
@@ -748,9 +827,8 @@ public class JniCodeEmitter {
bufferArgNames.add(cname);
numBufferArgs++;
}
- } else {
- suffix = "";
}
+
if (argType.isString()) {
stringArgs.add(new Integer(i));
}
@@ -801,7 +879,14 @@ public class JniCodeEmitter {
" \"" + cfunc.getName() + "\");");
if (!isVoid) {
String retval = getErrorReturnValue(cfunc);
- out.println(indent + "return " + retval + ";");
+ if (cfunc.getType().isEGLHandle()) {
+ String baseType = cfunc.getType().getBaseType().toLowerCase();
+ out.println(indent +
+ "return toEGLHandle(_env, " + baseType + "Class, " +
+ baseType + "Constructor, " + retval + ");");
+ } else {
+ out.println(indent + "return " + retval + ";");
+ }
}
out.println("}");
out.println();
@@ -820,7 +905,14 @@ public class JniCodeEmitter {
out.println(indent + indent + " return;");
} else {
String retval = getErrorReturnValue(cfunc);
- out.println(indent + indent + " return " + retval + ";");
+ if (cfunc.getType().isEGLHandle()) {
+ String baseType = cfunc.getType().getBaseType().toLowerCase();
+ out.println(indent +
+ "return toEGLHandle(_env, " + baseType + "Class, " +
+ baseType + "Constructor, " + retval + ");");
+ } else {
+ out.println(indent + "return " + retval + ";");
+ }
}
out.println(indent + "}");
}
@@ -830,14 +922,18 @@ public class JniCodeEmitter {
}
boolean initializeReturnValue = stringArgs.size() > 0;
-
- boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0 || numStrings > 0) &&
- hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs);
+ boolean emitExceptionCheck = ((numArrays > 0 || numStrings > 0)
+ && (hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs)
+ || (cfunc.hasPointerArg() && numArrays > 0))
+ || hasCheckTest(cfunc)
+ || hasIfTest(cfunc))
+ || (stringArgs.size() > 0);
// mChecker.getChecks(cfunc.getName()) != null
-
// Emit an _exeption variable if there will be error checks
if (emitExceptionCheck) {
out.println(indent + "jint _exception = 0;");
+ out.println(indent + "const char * _exceptionType;");
+ out.println(indent + "const char * _exceptionMessage;");
}
// Emit a single _array or multiple _XXXArray variables
@@ -856,13 +952,49 @@ public class JniCodeEmitter {
" _returnValue = " + retval + ";");
} else if (initializeReturnValue) {
out.println(indent + returnType.getDeclaration() +
- " _returnValue = 0;");
+ " _returnValue = 0;");
} else {
out.println(indent + returnType.getDeclaration() +
" _returnValue;");
}
}
+ // Emit local variable declarations for EGL Handles
+ //
+ // Example:
+ //
+ // EGLSurface surface_native = (EGLHandle)fromEGLHandle(_env, surfaceClass, surfaceConstructor, surface);
+ //
+ if (nonPrimitiveArgs.size() > 0) {
+ for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
+ int idx = nonPrimitiveArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ if (jfunc.getArgType(idx).isBuffer()
+ || jfunc.getArgType(idx).isArray()
+ || !jfunc.getArgType(idx).isEGLHandle())
+ continue;
+
+ CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
+ String decl = type.getDeclaration();
+ out.println(indent +
+ decl + " " + cname + "_native = (" +
+ decl + ") fromEGLHandle(_env, " +
+ type.getBaseType().toLowerCase() +
+ "GetHandleID, " + jfunc.getArgName(idx) +
+ ");");
+ }
+ }
+
+ // Emit local variable declarations for element/sentinel checks
+ //
+ // Example:
+ //
+ // bool attrib_list_sentinel_found = false;
+ //
+ emitLocalVariablesForSentinel(cfunc, out);
+
// Emit local variable declarations for pointer arguments
//
// Example:
@@ -878,9 +1010,12 @@ public class JniCodeEmitter {
int cIndex = jfunc.getArgCIndex(idx);
String cname = cfunc.getArgName(cIndex);
+ if (!jfunc.getArgType(idx).isBuffer() && !jfunc.getArgType(idx).isArray())
+ continue;
+
CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
String decl = type.getDeclaration();
- if (jfunc.getArgType(idx).isArray()) {
+ if (jfunc.getArgType(idx).isArray() && !jfunc.getArgType(idx).isClass()) {
out.println(indent +
decl +
(decl.endsWith("*") ? "" : " ") +
@@ -892,10 +1027,10 @@ public class JniCodeEmitter {
out.println(indent +
"jint " + remaining + ";");
out.println(indent +
- decl +
- (decl.endsWith("*") ? "" : " ") +
- jfunc.getArgName(idx) +
- " = (" + decl + ") 0;");
+ decl +
+ (decl.endsWith("*") ? "" : " ") +
+ jfunc.getArgName(idx) +
+ " = (" + decl + ") 0;");
}
out.println();
@@ -923,11 +1058,13 @@ public class JniCodeEmitter {
CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
String decl = type.getDeclaration();
- out.println(indent + "if (!" + cname + ") {");
- out.println(indent + " jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", \"" + cname + " == null\");");
- out.println(indent + " goto exit;");
needsExit = true;
+ out.println(indent + "if (!" + cname + ") {");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent +
+ "_exceptionMessage = \"" + cname + " == null\";");
+ out.println(indent + indent + "goto exit;");
out.println(indent + "}");
out.println(indent + "_native" + cname + " = _env->GetStringUTFChars(" + cname + ", 0);");
@@ -936,7 +1073,7 @@ public class JniCodeEmitter {
out.println();
}
- // Emit 'GetPrimitiveArrayCritical' for arrays
+ // Emit 'GetPrimitiveArrayCritical' for non-object arrays
// Emit 'GetPointer' calls for Buffer pointers
int bufArgIdx = 0;
if (nonPrimitiveArgs.size() > 0) {
@@ -950,29 +1087,24 @@ public class JniCodeEmitter {
remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
"_" + cname + "Remaining";
- if (jfunc.getArgType(idx).isArray()) {
- out.println(indent +
- "if (!" +
- cname +
- "_ref) {");
- if (emitExceptionCheck) {
- out.println(indent + indent + "_exception = 1;");
- }
- out.println(indent + " jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", " +
- "\"" + cname + " == null\");");
- out.println(indent + " goto exit;");
+ if (jfunc.getArgType(idx).isArray()
+ && !jfunc.getArgType(idx).isEGLHandle()) {
needsExit = true;
+ out.println(indent + "if (!" + cname + "_ref) {");
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent +
+ "_exceptionMessage = \"" + cname +" == null\";");
+ out.println(indent + indent + "goto exit;");
out.println(indent + "}");
-
out.println(indent + "if (" + offset + " < 0) {");
- if (emitExceptionCheck) {
- out.println(indent + indent + "_exception = 1;");
- }
- out.println(indent + " jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", \"" + offset + " < 0\");");
- out.println(indent + " goto exit;");
- needsExit = true;
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent +
+ "_exceptionMessage = \"" + offset +" < 0\";");
+ out.println(indent + indent + "goto exit;");
out.println(indent + "}");
out.println(indent + remaining + " = " +
@@ -997,10 +1129,44 @@ public class JniCodeEmitter {
jfunc.getArgName(idx) +
"_ref, (jboolean *)0);");
out.println(indent +
- cname + " = " + cname + "_base + " + offset +
- ";");
+ cname + " = " + cname + "_base + " + offset + ";");
+
+ emitSentinelCheck(cfunc, cname, out, false,
+ emitExceptionCheck, offset,
+ remaining, indent);
out.println();
- } else {
+ } else if (jfunc.getArgType(idx).isArray()
+ && jfunc.getArgType(idx).isEGLHandle()) {
+ needsExit = true;
+ out.println(indent + "if (!" + cname + "_ref) {");
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent + "_exceptionMessage = \"" + cname +" == null\";");
+ out.println(indent + indent + "goto exit;");
+ out.println(indent + "}");
+ out.println(indent + "if (" + offset + " < 0) {");
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent + "_exceptionMessage = \"" + offset +" < 0\";");
+ out.println(indent + indent + "goto exit;");
+ out.println(indent + "}");
+
+ out.println(indent + remaining + " = " +
+ (mUseCPlusPlus ? "_env" : "(*_env)") +
+ "->GetArrayLength(" +
+ (mUseCPlusPlus ? "" : "_env, ") +
+ cname + "_ref) - " + offset + ";");
+ emitNativeBoundsChecks(cfunc, cname, out, false,
+ emitExceptionCheck,
+ offset, remaining, " ");
+ out.println(indent +
+ jfunc.getArgName(idx) + " = new " +
+ cfunc.getArgType(cIndex).getBaseType() +
+ "["+ remaining + "];");
+ out.println();
+ } else if (jfunc.getArgType(idx).isBuffer()) {
String array = numBufferArgs <= 1 ? "_array" :
"_" + bufferArgNames.get(bufArgIdx++) + "Array";
@@ -1019,7 +1185,7 @@ public class JniCodeEmitter {
cname + "_buf);");
String iii = " ";
out.println(iii + indent + "if ( ! " + cname + " ) {");
- out.println(iii + iii + indent + "return;");
+ out.println(iii + indent + indent + "return;");
out.println(iii + indent + "}");
} else {
out.println(indent +
@@ -1075,18 +1241,23 @@ public class JniCodeEmitter {
for (int i = 0; i < numArgs; i++) {
String typecast;
if (i == numArgs - 1 && isVBOPointerFunc) {
- typecast = "const GLvoid *";
+ typecast = "(const GLvoid *)";
} else {
- typecast = cfunc.getArgType(i).getDeclaration();
+ typecast = "(" + cfunc.getArgType(i).getDeclaration() + ")";
}
out.print(indent + indent +
- "(" +
- typecast +
- ")");
+ typecast);
+
if (cfunc.getArgType(i).isConstCharPointer()) {
out.print("_native");
}
- out.print(cfunc.getArgName(i));
+
+ if (cfunc.getArgType(i).isEGLHandle() &&
+ !cfunc.getArgType(i).isPointer()){
+ out.print(cfunc.getArgName(i)+"_native");
+ } else {
+ out.print(cfunc.getArgName(i));
+ }
if (i == numArgs - 1) {
if (isPointerFunc) {
@@ -1114,7 +1285,7 @@ public class JniCodeEmitter {
int idx = nonPrimitiveArgs.get(i).intValue();
int cIndex = jfunc.getArgCIndex(idx);
- if (jfunc.getArgType(idx).isArray()) {
+ if (jfunc.getArgType(idx).isArray() && !jfunc.getArgType(idx).isClass()) {
// If the argument is 'const', GL will not write to it.
// In this case, we can use the 'JNI_ABORT' flag to avoid
@@ -1130,8 +1301,7 @@ public class JniCodeEmitter {
"_base,");
out.println(indent + indent + indent +
(cfunc.getArgType(cIndex).isConst() ?
- "JNI_ABORT" :
- "_exception ? JNI_ABORT: 0") +
+ "JNI_ABORT" : "_exception ? JNI_ABORT: 0" ) +
");");
out.println(indent + "}");
} else if (jfunc.getArgType(idx).isBuffer()) {
@@ -1144,8 +1314,8 @@ public class JniCodeEmitter {
cfunc.getArgName(cIndex) +
", " +
(cfunc.getArgType(cIndex).isConst() ?
- "JNI_FALSE" : "_exception ? JNI_FALSE :" +
- " JNI_TRUE") +
+ "JNI_FALSE" : (emitExceptionCheck ?
+ "_exception ? JNI_FALSE : JNI_TRUE" : "JNI_TRUE")) +
");");
out.println(indent + "}");
}
@@ -1168,9 +1338,60 @@ public class JniCodeEmitter {
out.println();
}
+ // Copy results back to java arrays
+ if (nonPrimitiveArgs.size() > 0) {
+ for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
+ int idx = nonPrimitiveArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String baseType = cfunc.getArgType(cIndex).getBaseType().toLowerCase();
+ if (jfunc.getArgType(idx).isArray() && jfunc.getArgType(idx).isClass()) {
+ remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
+ "_" + cfunc.getArgName(cIndex) + "Remaining";
+ offset = numArrays <= 1 ? "offset" : cfunc.getArgName(cIndex) + "Offset";
+ out.println(indent +
+ "if (" + jfunc.getArgName(idx) + ") {");
+ out.println(indent + indent +
+ "for (int i = 0; i < " + remaining + "; i++) {");
+ out.println(indent + indent + indent +
+ "jobject " + cfunc.getArgName(cIndex) +
+ "_new = toEGLHandle(_env, " + baseType +
+ "Class, " + baseType + "Constructor, " +
+ cfunc.getArgName(cIndex) + "[i]);");
+ out.println(indent + indent + indent +
+ (mUseCPlusPlus ? "_env" : "(*_env)") +
+ "->SetObjectArrayElement(" +
+ (mUseCPlusPlus ? "" : "_env, ") +
+ cfunc.getArgName(cIndex) +
+ "_ref, i + " + offset + ", " +
+ cfunc.getArgName(cIndex) + "_new);");
+ out.println(indent + indent + "}");
+ out.println(indent + indent +
+ "delete[] " + jfunc.getArgName(idx) + ";");
+ out.println(indent + "}");
+ }
+ }
+ }
+
+
+ // Throw exception if there is one
+ if (emitExceptionCheck) {
+ out.println(indent + "if (_exception) {");
+ out.println(indent + indent +
+ "jniThrowException(_env, _exceptionType, _exceptionMessage);");
+ out.println(indent + "}");
+
+ }
+
if (!isVoid) {
- out.println(indent + "return _returnValue;");
+ if (cfunc.getType().isEGLHandle()) {
+ String baseType = cfunc.getType().getBaseType().toLowerCase();
+ out.println(indent +
+ "return toEGLHandle(_env, " + baseType + "Class, " +
+ baseType + "Constructor, _returnValue);");
+ } else {
+ out.println(indent + "return _returnValue;");
+ }
}
out.println("}");