Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2180c6e authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 174 into donut

* changes:
  Improve glgen
parents 967f7c16 4e70a9e4
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
#!/bin/sh
#!/bin/bash
set -u
rm -rf out generated

mkdir out
@@ -12,12 +13,18 @@ echo "public interface Canvas {}" >> out/android/graphics/Canvas.java
GLFILE=out/javax/microedition/khronos/opengles/GL.java
cp stubs/GLHeader.java-if $GLFILE

GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java JFunc.java JType.java JniCodeEmitter.java ParameterChecker.java"
GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java JFunc.java JniCodeEmitter.java JType.java Jsr239CodeEmitter.java ParameterChecker.java"

pushd src > /dev/null
javac ${GLGEN_FILES}
JAVAC_RESULT=$?
if [ $JAVAC_RESULT -ne 0 ]; then
    echo "Could not compile glgen."
    exit $JAVAC_RESULT
fi
popd > /dev/null
java -classpath src GenerateGL -c glspec-1.0 glspec-1.0ext glspec-1.1 glspec-1.1ext glspec-1.1extpack glspec-checks
rm src/*.class

pushd out > /dev/null
mkdir classes
+1 −2
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ public class GenerateGL {
                             PrintStream glImplStream,
                             PrintStream cStream) throws Exception {
        String s = null;
        int counter = 0;
        while ((s = specReader.readLine()) != null) {
            if (s.trim().startsWith("//")) {
                continue;
@@ -120,7 +119,7 @@ public class GenerateGL {
        ParameterChecker checker = new ParameterChecker(checksReader);

        CodeEmitter emitter =
            new JniCodeEmitter(classPathName,
            new Jsr239CodeEmitter(classPathName,
                               checker,
                               gl10Stream, gl10ExtStream,
                               gl11Stream, gl11ExtStream, gl11ExtPackStream,
+200 −279
Original line number Diff line number Diff line
@@ -4,90 +4,47 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

/**
 * 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 JniCodeEmitter implements CodeEmitter {
public class JniCodeEmitter {

    // If true, use C++ style for calling through a JNIEnv *:
    // env->Func(...)
    // If false, use C style:
    // (*env)->Func(env, ...)
    static final boolean mUseCPlusPlus = true;

    boolean mUseContextPointer = true;

    String mClassPathName;

    ParameterChecker mChecker;
    PrintStream mJava10InterfaceStream;
    PrintStream mJava10ExtInterfaceStream;
    PrintStream mJava11InterfaceStream;
    PrintStream mJava11ExtInterfaceStream;
    PrintStream mJava11ExtPackInterfaceStream;
    PrintStream mJavaImplStream;
    PrintStream mCStream;

    PrintStream mJavaInterfaceStream;

    List<String> nativeRegistrations = new ArrayList<String>();

    protected boolean mUseContextPointer = true;
    protected String mClassPathName;
    protected ParameterChecker mChecker;
    protected List<String> nativeRegistrations = new ArrayList<String>();
    boolean needsExit;

    static String indent = "    ";

    protected static String indent = "    ";
    HashSet<String> mFunctionsEmitted = new HashSet<String>();

    /**
     * @param java10InterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 functions
     * @param java10ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 extension functions
     * @param java11InterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 functions
     * @param java11ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension functions
     * @param java11ExtPackInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension Pack functions
     * @param javaImplStream the PrintStream to which to emit the Java implementation
     * @param cStream the PrintStream to which to emit the C implementation
     */
    public JniCodeEmitter(String classPathName,
                          ParameterChecker checker,
                          PrintStream java10InterfaceStream,
                          PrintStream java10ExtInterfaceStream,
                          PrintStream java11InterfaceStream,
                          PrintStream java11ExtInterfaceStream,
                          PrintStream java11ExtPackInterfaceStream,
                          PrintStream javaImplStream,
                          PrintStream cStream,
                          boolean useContextPointer) {
        mClassPathName = classPathName;
        mChecker = checker;
        mJava10InterfaceStream = java10InterfaceStream;
        mJava10ExtInterfaceStream = java10ExtInterfaceStream;
        mJava11InterfaceStream = java11InterfaceStream;
        mJava11ExtInterfaceStream = java11ExtInterfaceStream;
        mJava11ExtPackInterfaceStream = java11ExtPackInterfaceStream;
        mJavaImplStream = javaImplStream;
        mCStream = cStream;
        mUseContextPointer = useContextPointer;
    }

    public void setVersion(int version, boolean ext, boolean pack) {
        if (version == 0) {
            mJavaInterfaceStream = ext ? mJava10ExtInterfaceStream :
                mJava10InterfaceStream;
        } else if (version == 1) {
            mJavaInterfaceStream = ext ?
                (pack ? mJava11ExtPackInterfaceStream :
                 mJava11ExtInterfaceStream) :
                mJava11InterfaceStream;
        } else {
            throw new RuntimeException("Bad version: " + version);
    public static String getJniName(JType jType) {
        String jniName = "";
        if (jType.isClass()) {
            return "L" + jType.getBaseType() + ";";
        } else if (jType.isArray()) {
            jniName = "[";
        }

        String baseType = jType.getBaseType();
        if (baseType.equals("int")) {
            jniName += "I";
        } else if (baseType.equals("float")) {
            jniName += "F";
        } else if (baseType.equals("boolean")) {
            jniName += "Z";
        } else if (baseType.equals("short")) {
            jniName += "S";
        } else if (baseType.equals("long")) {
            jniName += "L";
        } else if (baseType.equals("byte")) {
            jniName += "B";
        }
        return jniName;
    }

    public void emitCode(CFunc cfunc, String original) {

    public void emitCode(CFunc cfunc, String original,
            PrintStream javaInterfaceStream,
            PrintStream javaImplStream,
            PrintStream cStream) {
        JFunc jfunc;
        String signature;
        boolean duplicate;
@@ -107,12 +64,12 @@ public class JniCodeEmitter implements CodeEmitter {
            }

            if (!duplicate) {
                emitNativeDeclaration(jfunc, mJavaImplStream);
                emitJavaCode(jfunc, mJavaImplStream);
                emitNativeDeclaration(jfunc, javaImplStream);
                emitJavaCode(jfunc, javaImplStream);
            }
            emitJavaInterfaceCode(jfunc, mJavaInterfaceStream);
            emitJavaInterfaceCode(jfunc, javaInterfaceStream);
            if (!duplicate) {
                emitJniCode(jfunc, mCStream);
                emitJniCode(jfunc, cStream);
            }
        }

@@ -127,12 +84,12 @@ public class JniCodeEmitter implements CodeEmitter {
        }

        if (!duplicate) {
            emitNativeDeclaration(jfunc, mJavaImplStream);
            emitNativeDeclaration(jfunc, javaImplStream);
        }
        emitJavaInterfaceCode(jfunc, mJavaInterfaceStream);
        emitJavaInterfaceCode(jfunc, javaInterfaceStream);
        if (!duplicate) {
            emitJavaCode(jfunc, mJavaImplStream);
            emitJniCode(jfunc, mCStream);
            emitJavaCode(jfunc, javaImplStream);
            emitJniCode(jfunc, cStream);
        }
    }

@@ -194,14 +151,13 @@ public class JniCodeEmitter implements CodeEmitter {
        out.println(iii + ");");
    }

    void printIfcheckPostamble(PrintStream out, boolean isBuffer,
                               boolean emitExceptionCheck, String iii) {
    void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck,
            String iii) {
                printIfcheckPostamble(out, isBuffer, emitExceptionCheck,
                                      "offset", "_remaining", iii);
            }

    void printIfcheckPostamble(PrintStream out, boolean isBuffer,
                               boolean emitExceptionCheck,
    void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck,
            String offset, String remaining, String iii) {
                out.println(iii + "    default:");
                out.println(iii + "        _needed = 0;");
@@ -310,22 +266,14 @@ public class JniCodeEmitter implements CodeEmitter {
    }

    void emitNativeBoundsChecks(CFunc cfunc, String cname, PrintStream out,
                                boolean isBuffer, boolean emitExceptionCheck,
                                String offset, String remaining, String iii) {
        CType returnType = cfunc.getType();
        boolean isVoid = returnType.isVoid();
            boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) {

                String[] checks = mChecker.getChecks(cfunc.getName());
        String checkVar;
        String retval = getErrorReturnValue(cfunc);

                boolean lastWasIfcheck = false;

                int index = 1;
                if (checks != null) {
            boolean remainingDeclared = false;
            boolean nullCheckDeclared = false;
            boolean offsetChecked = false;
                    while (index < checks.length) {
                        if (checks[index].startsWith("check")) {
                            if (lastWasIfcheck) {
@@ -417,8 +365,7 @@ public class JniCodeEmitter implements CodeEmitter {
                }
            }

    boolean hasNonConstArg(JFunc jfunc, CFunc cfunc,
        List<Integer> nonPrimitiveArgs) {
    boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) {
        if (nonPrimitiveArgs.size() > 0) {
            for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
                int idx = nonPrimitiveArgs.get(i).intValue();
@@ -447,9 +394,7 @@ public class JniCodeEmitter implements CodeEmitter {
     *   if interfaceDecl:  public <returntype> func(args);
     *   if !interfaceDecl: public <returntype> func(args) { body }
     */
    void emitFunction(JFunc jfunc,
                      PrintStream out,
                      boolean nativeDecl, boolean interfaceDecl) {
    void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) {
        boolean isPointerFunc =
            jfunc.getName().endsWith("Pointer") &&
            jfunc.getCFunc().hasPointerArg();
@@ -559,29 +504,43 @@ public class JniCodeEmitter implements CodeEmitter {
        out.println();
    }

    public static String getJniName(JType jType) {
        String jniName = "";
        if (jType.isClass()) {
            return "L" + jType.getBaseType() + ";";
        } else if (jType.isArray()) {
            jniName = "[";
    public void addNativeRegistration(String s) {
        nativeRegistrations.add(s);
    }

        String baseType = jType.getBaseType();
        if (baseType.equals("int")) {
            jniName += "I";
        } else if (baseType.equals("float")) {
            jniName += "F";
        } else if (baseType.equals("boolean")) {
            jniName += "Z";
        } else if (baseType.equals("short")) {
            jniName += "S";
        } else if (baseType.equals("long")) {
            jniName += "L";
        } else if (baseType.equals("byte")) {
            jniName += "B";
    public void emitNativeRegistration(PrintStream cStream) {
        cStream.println("static const char *classPathName = \"" +
                        mClassPathName +
                        "\";");
        cStream.println();

        cStream.println("static JNINativeMethod methods[] = {");

        cStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },");

        Iterator<String> i = nativeRegistrations.iterator();
        while (i.hasNext()) {
            cStream.println(i.next());
        }
        return jniName;

        cStream.println("};");
        cStream.println();


        cStream.println("int register_com_google_android_gles_jni_GLImpl(JNIEnv *_env)");
        cStream.println("{");
        cStream.println(indent +
                        "int err;");

        cStream.println(indent +
                        "err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));");

        cStream.println(indent + "return err;");
        cStream.println("}");
    }

    public JniCodeEmitter() {
        super();
    }

    String getJniType(JType jType) {
@@ -721,8 +680,6 @@ public class JniCodeEmitter implements CodeEmitter {
        int numBuffers = 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).isArray()) {
                ++numArrays;
            }
@@ -832,8 +789,6 @@ public class JniCodeEmitter implements CodeEmitter {
            out.println();
        }

        String retval = isVoid ? "" : " _returnValue";

        // Emit 'GetPrimitiveArrayCritical' for arrays
        // Emit 'GetPointer' calls for Buffer pointers
        int bufArgIdx = 0;
@@ -1047,38 +1002,4 @@ public class JniCodeEmitter implements CodeEmitter {
        out.println();
    }

    public void addNativeRegistration(String s) {
        nativeRegistrations.add(s);
    }

    public void emitNativeRegistration() {
        mCStream.println("static const char *classPathName = \"" +
                        mClassPathName +
                        "\";");
        mCStream.println();

        mCStream.println("static JNINativeMethod methods[] = {");

        mCStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },");

        Iterator<String> i = nativeRegistrations.iterator();
        while (i.hasNext()) {
            mCStream.println(i.next());
        }

        mCStream.println("};");
        mCStream.println();


        mCStream.println("int register_com_google_android_gles_jni_GLImpl(JNIEnv *_env)");
        mCStream.println("{");
        mCStream.println(indent +
                        "int err;");

        mCStream.println(indent +
                        "err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));");

        mCStream.println(indent + "return err;");
        mCStream.println("}");
    }
}
+74 −0
Original line number Diff line number Diff line
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 Jsr239CodeEmitter extends JniCodeEmitter implements CodeEmitter {

    PrintStream mJava10InterfaceStream;
    PrintStream mJava10ExtInterfaceStream;
    PrintStream mJava11InterfaceStream;
    PrintStream mJava11ExtInterfaceStream;
    PrintStream mJava11ExtPackInterfaceStream;
    PrintStream mJavaImplStream;
    PrintStream mCStream;

    PrintStream mJavaInterfaceStream;

    /**
     * @param java10InterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 functions
     * @param java10ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 extension functions
     * @param java11InterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 functions
     * @param java11ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension functions
     * @param java11ExtPackInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension Pack functions
     * @param javaImplStream the PrintStream to which to emit the Java implementation
     * @param cStream the PrintStream to which to emit the C implementation
     */
    public Jsr239CodeEmitter(String classPathName,
                          ParameterChecker checker,
                          PrintStream java10InterfaceStream,
                          PrintStream java10ExtInterfaceStream,
                          PrintStream java11InterfaceStream,
                          PrintStream java11ExtInterfaceStream,
                          PrintStream java11ExtPackInterfaceStream,
                          PrintStream javaImplStream,
                          PrintStream cStream,
                          boolean useContextPointer) {
        mClassPathName = classPathName;
        mChecker = checker;
        mJava10InterfaceStream = java10InterfaceStream;
        mJava10ExtInterfaceStream = java10ExtInterfaceStream;
        mJava11InterfaceStream = java11InterfaceStream;
        mJava11ExtInterfaceStream = java11ExtInterfaceStream;
        mJava11ExtPackInterfaceStream = java11ExtPackInterfaceStream;
        mJavaImplStream = javaImplStream;
        mCStream = cStream;
        mUseContextPointer = useContextPointer;
    }

    public void setVersion(int version, boolean ext, boolean pack) {
        if (version == 0) {
            mJavaInterfaceStream = ext ? mJava10ExtInterfaceStream :
                mJava10InterfaceStream;
        } else if (version == 1) {
            mJavaInterfaceStream = ext ?
                (pack ? mJava11ExtPackInterfaceStream :
                 mJava11ExtInterfaceStream) :
                mJava11InterfaceStream;
        } else {
            throw new RuntimeException("Bad version: " + version);
        }
    }

    public void emitCode(CFunc cfunc, String original) {
        emitCode(cfunc, original, mJavaInterfaceStream, mJavaImplStream, mCStream);
    }

    public void emitNativeRegistration() {
        emitNativeRegistration(mCStream);
    }
}