summaryrefslogtreecommitdiffstats
path: root/opengl/tools/glgen/src/JniCodeEmitter.java
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/tools/glgen/src/JniCodeEmitter.java')
-rw-r--r--opengl/tools/glgen/src/JniCodeEmitter.java206
1 files changed, 189 insertions, 17 deletions
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index 2cdb244..ebaca90 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2006 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;
import java.util.ArrayList;
import java.util.HashSet;
@@ -37,6 +53,12 @@ public class JniCodeEmitter {
jniName += "L";
} else if (baseType.equals("byte")) {
jniName += "B";
+ } else if (baseType.equals("String")) {
+ jniName += "Ljava/lang/String;";
+ } else if (baseType.equals("void")) {
+ // nothing.
+ } else {
+ throw new RuntimeException("Uknown primitive basetype " + baseType);
}
return jniName;
}
@@ -113,10 +135,15 @@ public class JniCodeEmitter {
emitFunction(jfunc, out, false, false);
}
+ boolean isPointerFunc(JFunc jfunc) {
+ String name = jfunc.getName();
+ return (name.endsWith("Pointer") || name.endsWith("PointerOES"))
+ && jfunc.getCFunc().hasPointerArg();
+ }
+
void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray) {
boolean isVoid = jfunc.getType().isVoid();
- boolean isPointerFunc = jfunc.getName().endsWith("Pointer") &&
- jfunc.getCFunc().hasPointerArg();
+ boolean isPointerFunc = isPointerFunc(jfunc);
if (!isVoid) {
out.println(iii +
@@ -200,6 +227,8 @@ public class JniCodeEmitter {
index += 5;
} else if (checks[index].equals("unsupported")) {
index += 1;
+ } else if (checks[index].equals("requires")) {
+ index += 2;
} else if (checks[index].equals("nullAllowed")) {
return true;
} else {
@@ -232,6 +261,8 @@ public class JniCodeEmitter {
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 {
@@ -252,6 +283,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")) {
@@ -269,7 +302,34 @@ public class JniCodeEmitter {
}
return false;
}
-
+
+ String isRequiresFunc(CFunc cfunc) {
+ String[] checks = mChecker.getChecks(cfunc.getName());
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].equals("unsupported")) {
+ index += 1;
+ } else 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);
+ }
+ }
+ }
+ return null;
+ }
+
void emitNativeBoundsChecks(CFunc cfunc, String cname, PrintStream out,
boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) {
@@ -354,6 +414,9 @@ public class JniCodeEmitter {
} 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;
@@ -400,9 +463,7 @@ public class JniCodeEmitter {
* if !interfaceDecl: public <returntype> func(args) { body }
*/
void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) {
- boolean isPointerFunc =
- jfunc.getName().endsWith("Pointer") &&
- jfunc.getCFunc().hasPointerArg();
+ boolean isPointerFunc = isPointerFunc(jfunc);
if (!nativeDecl && !interfaceDecl && !isPointerFunc) {
// If it's not a pointer function, we've already emitted it
@@ -504,6 +565,34 @@ public class JniCodeEmitter {
out.println(iii + " (stride >= 0)) {");
out.println(iii + indent + "_vertexPointer = pointer;");
out.println(iii + "}");
+ } else if (fname.equals("glPointSizePointerOES")) {
+ out.println(iii + "if (((type == GL_FLOAT) ||");
+ out.println(iii + " (type == GL_FIXED)) &&");
+ out.println(iii + " (stride >= 0)) {");
+ out.println(iii + indent + "_pointSizePointerOES = pointer;");
+ out.println(iii + "}");
+ } else if (fname.equals("glMatrixIndexPointerOES")) {
+ out.println(iii + "if (((size == 2) ||");
+ out.println(iii + " (size == 3) ||");
+ out.println(iii + " (size == 4)) &&");
+ out.println(iii + " ((type == GL_FLOAT) ||");
+ out.println(iii + " (type == GL_BYTE) ||");
+ out.println(iii + " (type == GL_SHORT) ||");
+ out.println(iii + " (type == GL_FIXED)) &&");
+ out.println(iii + " (stride >= 0)) {");
+ out.println(iii + indent + "_matrixIndexPointerOES = pointer;");
+ out.println(iii + "}");
+ } else if (fname.equals("glWeightPointer")) {
+ out.println(iii + "if (((size == 2) ||");
+ out.println(iii + " (size == 3) ||");
+ out.println(iii + " (size == 4)) &&");
+ out.println(iii + " ((type == GL_FLOAT) ||");
+ out.println(iii + " (type == GL_BYTE) ||");
+ out.println(iii + " (type == GL_SHORT) ||");
+ out.println(iii + " (type == GL_FIXED)) &&");
+ out.println(iii + " (stride >= 0)) {");
+ out.println(iii + indent + "_weightPointerOES = pointer;");
+ out.println(iii + "}");
}
}
@@ -603,9 +692,9 @@ public class JniCodeEmitter {
//
String outName = "android_" + jfunc.getName();
- boolean isPointerFunc = outName.endsWith("Pointer") &&
- jfunc.getCFunc().hasPointerArg();
+ boolean isPointerFunc = isPointerFunc(jfunc);
boolean isVBOPointerFunc = (outName.endsWith("Pointer") ||
+ outName.endsWith("PointerOES") ||
outName.endsWith("DrawElements")) &&
!jfunc.getCFunc().hasPointerArg();
if (isPointerFunc) {
@@ -629,7 +718,7 @@ public class JniCodeEmitter {
}
// Append signature to function name
- String sig = getJniMangledName(signature).replace('.', '_');
+ String sig = getJniMangledName(signature).replace('.', '_').replace('/', '_');
out.print("__" + sig);
outName += "__" + sig;
@@ -652,6 +741,7 @@ public class JniCodeEmitter {
nativeRegistrations.add(s);
List<Integer> nonPrimitiveArgs = new ArrayList<Integer>();
+ List<Integer> stringArgs = new ArrayList<Integer>();
int numBufferArgs = 0;
List<String> bufferArgNames = new ArrayList<String>();
@@ -682,6 +772,9 @@ public class JniCodeEmitter {
} else {
suffix = "";
}
+ if (argType.isString()) {
+ stringArgs.add(new Integer(i));
+ }
out.print(getJniType(argType) + " " + jfunc.getArgName(i) + suffix);
}
@@ -692,14 +785,19 @@ public class JniCodeEmitter {
int numArrays = 0;
int numBuffers = 0;
+ int numStrings = 0;
for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
int idx = nonPrimitiveArgs.get(i).intValue();
- if (jfunc.getArgType(idx).isArray()) {
+ JType argType = jfunc.getArgType(idx);
+ if (argType.isArray()) {
++numArrays;
}
- if (jfunc.getArgType(idx).isBuffer()) {
+ if (argType.isBuffer()) {
++numBuffers;
}
+ if (argType.isString()) {
+ ++numStrings;
+ }
}
// Emit method body
@@ -730,13 +828,31 @@ public class JniCodeEmitter {
out.println();
return;
}
-
+
+ String requiresExtension = isRequiresFunc(cfunc);
+ if (requiresExtension != null) {
+ out.println(indent +
+ "if (! supportsExtension(_env, _this, have_" + requiresExtension + "ID)) {");
+ out.println(indent + indent +
+ "_env->ThrowNew(UOEClass,");
+ out.println(indent + indent +
+ " \"" + cfunc.getName() + "\");");
+ if (isVoid) {
+ out.println(indent + indent + " return;");
+ } else {
+ String retval = getErrorReturnValue(cfunc);
+ out.println(indent + indent + " return " + retval + ";");
+ }
+ out.println(indent + "}");
+ }
if (mUseContextPointer) {
out.println(indent +
"android::gl::ogles_context_t *ctx = getContext(_env, _this);");
}
- boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0) &&
+ boolean initializeReturnValue = stringArgs.size() > 0;
+
+ boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0 || numStrings > 0) &&
hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs);
// mChecker.getChecks(cfunc.getName()) != null
@@ -759,6 +875,9 @@ public class JniCodeEmitter {
if (retval != null) {
out.println(indent + returnType.getDeclaration() +
" _returnValue = " + retval + ";");
+ } else if (initializeReturnValue) {
+ out.println(indent + returnType.getDeclaration() +
+ " _returnValue = 0;");
} else {
out.println(indent + returnType.getDeclaration() +
" _returnValue;");
@@ -789,7 +908,7 @@ public class JniCodeEmitter {
jfunc.getArgName(idx) +
"_base = (" + decl + ") 0;");
}
- remaining = (numArrays <= 1 && numBuffers <= 1) ? "_remaining" :
+ remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
"_" + cname + "Remaining";
out.println(indent +
"jint " + remaining + ";");
@@ -803,6 +922,40 @@ public class JniCodeEmitter {
out.println();
}
+ // Emit local variable declaration for strings
+ if (stringArgs.size() > 0) {
+ for (int i = 0; i < stringArgs.size(); i++) {
+ int idx = stringArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ out.println(indent + "const char* _native" + cname + " = 0;");
+ }
+
+ out.println();
+ }
+
+ // Null pointer checks and GetStringUTFChars
+ if (stringArgs.size() > 0) {
+ for (int i = 0; i < stringArgs.size(); i++) {
+ int idx = stringArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
+ String decl = type.getDeclaration();
+ out.println(indent + "if (!" + cname + ") {");
+ out.println(indent + " _env->ThrowNew(IAEClass, \"" + cname + " == null\");");
+ out.println(indent + " goto exit;");
+ needsExit = true;
+ out.println(indent + "}");
+
+ out.println(indent + "_native" + cname + " = _env->GetStringUTFChars(" + cname + ", 0);");
+ }
+
+ out.println();
+ }
+
// Emit 'GetPrimitiveArrayCritical' for arrays
// Emit 'GetPointer' calls for Buffer pointers
int bufArgIdx = 0;
@@ -814,7 +967,7 @@ public class JniCodeEmitter {
String cname = cfunc.getArgName(cIndex);
offset = numArrays <= 1 ? "offset" :
cname + "Offset";
- remaining = (numArrays <= 1 && numBuffers <= 1) ? "_remaining" :
+ remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
"_" + cname + "Remaining";
if (jfunc.getArgType(idx).isArray()) {
@@ -957,8 +1110,11 @@ public class JniCodeEmitter {
out.print(indent + indent +
"(" +
typecast +
- ")" +
- cfunc.getArgName(i));
+ ")");
+ if (cfunc.getArgType(i).isConstCharPointer()) {
+ out.print("_native");
+ }
+ out.print(cfunc.getArgName(i));
if (i == numArgs - 1) {
if (isPointerFunc) {
@@ -1025,6 +1181,22 @@ public class JniCodeEmitter {
}
}
+ // Emit local variable declaration for strings
+ if (stringArgs.size() > 0) {
+ for (int i = 0; i < stringArgs.size(); i++) {
+ int idx = stringArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ out.println(indent + "if (_native" + cname + ") {");
+ out.println(indent + " _env->ReleaseStringUTFChars(" + cname + ", _native" + cname + ");");
+ out.println(indent + "}");
+ }
+
+ out.println();
+ }
+
+
if (!isVoid) {
out.println(indent + "return _returnValue;");
}