diff options
Diffstat (limited to 'opengl/tools/glgen/src/JniCodeEmitter.java')
-rw-r--r-- | opengl/tools/glgen/src/JniCodeEmitter.java | 206 |
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;"); } |