From 66a42db8cbfba902f72f0ace5ac448ef4bfd3951 Mon Sep 17 00:00:00 2001 From: Thomas Tafertshofer Date: Fri, 15 Jun 2012 16:22:43 -0700 Subject: [PATCH] improve glgen tool to support EGL1.4 - added EGL1.4 bindings generation - fixed bugs in GLES bindings Bug: 6709865 Change-Id: I04ac63f652e1968a51eb833f47e00336ea449980 --- opengl/tools/glgen/gen | 46 +- opengl/tools/glgen/specs/egl/EGL14.spec | 33 ++ opengl/tools/glgen/specs/egl/checks.spec | 13 + opengl/tools/glgen/src/CFunc.java | 8 + opengl/tools/glgen/src/CType.java | 10 + opengl/tools/glgen/src/EGLCodeEmitter.java | 58 ++ opengl/tools/glgen/src/GenerateEGL.java | 109 ++++ opengl/tools/glgen/src/JType.java | 30 +- opengl/tools/glgen/src/JniCodeEmitter.java | 513 +++++++++++++----- opengl/tools/glgen/static/egl/EGLConfig.java | 41 ++ opengl/tools/glgen/static/egl/EGLContext.java | 41 ++ opengl/tools/glgen/static/egl/EGLDisplay.java | 41 ++ .../glgen/static/egl/EGLObjectHandle.java | 33 ++ opengl/tools/glgen/static/egl/EGLSurface.java | 41 ++ .../tools/glgen/stubs/egl/EGL14Header.java-if | 151 ++++++ opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp | 132 +++++ .../stubs/egl/eglCreateWindowSurface.cpp | 154 ++++++ .../stubs/egl/eglCreateWindowSurface.java | 48 ++ .../egl/eglCreateWindowSurface.nativeReg | 2 + .../tools/glgen/stubs/egl/eglQueryString.cpp | 10 + .../tools/glgen/stubs/egl/eglQueryString.java | 6 + .../glgen/stubs/egl/eglQueryString.nativeReg | 1 + .../glgen/stubs/jsr239/GLImplHeader.java-impl | 3 +- 23 files changed, 1367 insertions(+), 157 deletions(-) create mode 100644 opengl/tools/glgen/specs/egl/EGL14.spec create mode 100644 opengl/tools/glgen/specs/egl/checks.spec create mode 100644 opengl/tools/glgen/src/EGLCodeEmitter.java create mode 100644 opengl/tools/glgen/src/GenerateEGL.java create mode 100644 opengl/tools/glgen/static/egl/EGLConfig.java create mode 100644 opengl/tools/glgen/static/egl/EGLContext.java create mode 100644 opengl/tools/glgen/static/egl/EGLDisplay.java create mode 100644 opengl/tools/glgen/static/egl/EGLObjectHandle.java create mode 100644 opengl/tools/glgen/static/egl/EGLSurface.java create mode 100644 opengl/tools/glgen/stubs/egl/EGL14Header.java-if create mode 100644 opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp create mode 100644 opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp create mode 100644 opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.java create mode 100644 opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.nativeReg create mode 100644 opengl/tools/glgen/stubs/egl/eglQueryString.cpp create mode 100644 opengl/tools/glgen/stubs/egl/eglQueryString.java create mode 100644 opengl/tools/glgen/stubs/egl/eglQueryString.nativeReg diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen index 31f41906f..3359a2272 100755 --- a/opengl/tools/glgen/gen +++ b/opengl/tools/glgen/gen @@ -12,6 +12,7 @@ mkdir -p out/javax/microedition/khronos/opengles mkdir -p out/com/google/android/gles_jni mkdir -p out/android/app mkdir -p out/android/graphics +mkdir -p out/android/view mkdir -p out/android/opengl mkdir -p out/android/content mkdir -p out/android/content/pm @@ -24,15 +25,33 @@ echo "public interface Canvas {}" >> out/android/graphics/Canvas.java echo "package android.app; import android.content.pm.IPackageManager; public class AppGlobals { public static IPackageManager getPackageManager() { return null;} }" > out/android/app/AppGlobals.java # echo "package android.content; import android.content.pm.PackageManager; public interface Context { public PackageManager getPackageManager(); }" > out/android/content/Context.java echo "package android.content.pm; public class ApplicationInfo {public int targetSdkVersion;}" > out/android/content/pm/ApplicationInfo.java -echo "package android.content.pm; public interface IPackageManager {ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags) throws android.os.RemoteException;}" > out/android/content/pm/IPackageManager.java +echo "package android.content.pm; public interface IPackageManager {ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags, java.lang.String userId) throws android.os.RemoteException;}" > out/android/content/pm/IPackageManager.java echo "package android.os; public class Build {public static class VERSION_CODES { public static final int CUPCAKE = 3;}; }" > out/android/os/Build.java +echo "package android.os; public class UserId {public static String myUserId() { return \"\"; } }" > out/android/os/UserId.java echo "package android.os; public class RemoteException extends Exception {}" > out/android/os/RemoteException.java echo "package android.util; public class Log {public static void w(String a, String b) {} public static void e(String a, String b) {}}" > out/android/util/Log.java +echo "package android.opengl; public abstract class EGLObjectHandle { public int getHandle() { return 0; } }" > out/android/opengl/EGLObjectHandle.java +echo "package android.opengl; public class EGLSurface extends EGLObjectHandle { }" > out/android/opengl/EGLSurface.java +echo "package android.opengl; public class EGLContext extends EGLObjectHandle { }" > out/android/opengl/EGLContext.java +echo "package android.opengl; public class EGLDisplay extends EGLObjectHandle { }" > out/android/opengl/EGLDisplay.java +echo "package android.opengl; public class EGLConfig extends EGLObjectHandle { }" > out/android/opengl/EGLConfig.java + + +echo "package android.graphics;" > out/android/graphics/SurfaceTexture.java +echo "public interface SurfaceTexture {}" >> out/android/graphics/SurfaceTexture.java +echo "package android.view;" > out/android/view/SurfaceView.java +echo "public interface SurfaceView { SurfaceHolder getHolder(); }" >> out/android/view/SurfaceView.java +echo "package android.view;" > out/android/view/Surface.java +echo "public interface Surface {}" >> out/android/view/Surface.java +echo "package android.view;" > out/android/view/SurfaceHolder.java +echo "public interface SurfaceHolder { Surface getSurface(); }" >> out/android/view/SurfaceHolder.java + + GLFILE=out/javax/microedition/khronos/opengles/GL.java cp stubs/jsr239/GLHeader.java-if $GLFILE -GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java GenerateGLES.java GLESCodeEmitter.java JFunc.java JniCodeEmitter.java JType.java Jsr239CodeEmitter.java ParameterChecker.java" +GLGEN_FILES="CFunc.java CType.java CodeEmitter.java EGLCodeEmitter.java GenerateEGL.java GenerateGL.java GenerateGLES.java GLESCodeEmitter.java JFunc.java JniCodeEmitter.java JType.java Jsr239CodeEmitter.java ParameterChecker.java" pushd src > /dev/null javac ${GLGEN_FILES} @@ -59,11 +78,19 @@ if [ $JAVA_RESULT -ne 0 ]; then exit $JAVA_RESULT fi +echo "Generating static EGL 1.4 bindings" +java -classpath src GenerateEGL +JAVA_RESULT=$? +if [ $JAVA_RESULT -ne 0 ]; then + echo "Could not run GenerateEGL." + exit $JAVA_RESULT +fi + rm src/*.class pushd out > /dev/null mkdir classes -javac -d classes com/google/android/gles_jni/GLImpl.java javax/microedition/khronos/opengles/GL10.java javax/microedition/khronos/opengles/GL10Ext.java javax/microedition/khronos/opengles/GL11.java javax/microedition/khronos/opengles/GL11Ext.java javax/microedition/khronos/opengles/GL11ExtensionPack.java android/opengl/GLES10.java android/opengl/GLES10Ext.java android/opengl/GLES11.java android/opengl/GLES11Ext.java android/opengl/GLES20.java +javac -d classes android/opengl/EGL14.java com/google/android/gles_jni/GLImpl.java javax/microedition/khronos/opengles/GL10.java javax/microedition/khronos/opengles/GL10Ext.java javax/microedition/khronos/opengles/GL11.java javax/microedition/khronos/opengles/GL11Ext.java javax/microedition/khronos/opengles/GL11ExtensionPack.java android/opengl/GLES10.java android/opengl/GLES10Ext.java android/opengl/GLES11.java android/opengl/GLES11Ext.java android/opengl/GLES20.java popd > /dev/null JAVA_RESULT=$? if [ $JAVA_RESULT -ne 0 ]; then @@ -90,6 +117,7 @@ compareGenerated() { if cmp -s $1/$3 $2/$3 ; then echo "# " $3 unchanged else + echo "# " $3 changed if [ $SAID_PLEASE == "0" ] ; then echo Please evaluate the following commands: echo @@ -101,18 +129,18 @@ compareGenerated() { fi } -compareGenerated ../../../core/jni generated/C com_google_android_gles_jni_GLImpl.cpp -compareGenerated ../../java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java +compareGenerated ../../../../base/core/jni generated/C com_google_android_gles_jni_GLImpl.cpp +compareGenerated ../../../../base/opengl/java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java for x in GL.java GL10.java GL10Ext.java GL11.java GL11Ext.java GL11ExtensionPack.java do - compareGenerated ../../java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x + compareGenerated ../../../../base/opengl/java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x done -for x in GLES10 GLES10Ext GLES11 GLES11Ext GLES20 +for x in EGL14 GLES10 GLES10Ext GLES11 GLES11Ext GLES20 do - compareGenerated ../../java/android/opengl generated/android/opengl ${x}.java - compareGenerated ../../../core/jni generated/C android_opengl_${x}.cpp + compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java + compareGenerated ../../../../base/core/jni generated/C android_opengl_${x}.cpp done if [ $KEEP_GENERATED == "0" ] ; then diff --git a/opengl/tools/glgen/specs/egl/EGL14.spec b/opengl/tools/glgen/specs/egl/EGL14.spec new file mode 100644 index 000000000..828e11485 --- /dev/null +++ b/opengl/tools/glgen/specs/egl/EGL14.spec @@ -0,0 +1,33 @@ +EGLint eglGetError ( void ) +EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) +EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor ) +EGLBoolean eglTerminate ( EGLDisplay dpy ) +const char * eglQueryString ( EGLDisplay dpy, EGLint name ) +EGLBoolean eglGetConfigs ( EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config ) +EGLBoolean eglChooseConfig ( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config ) +EGLBoolean eglGetConfigAttrib ( EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value ) +EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) +EGLSurface eglCreatePbufferSurface ( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list ) +EGLSurface eglCreatePixmapSurface ( EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list ) +EGLBoolean eglDestroySurface ( EGLDisplay dpy, EGLSurface surface ) +EGLBoolean eglQuerySurface ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value ) +EGLBoolean eglBindAPI ( EGLenum api ) +EGLenum eglQueryAPI ( void ) +EGLBoolean eglWaitClient ( void ) +EGLBoolean eglReleaseThread ( void ) +EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) +EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value ) +EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) +EGLBoolean eglReleaseTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) +EGLBoolean eglSwapInterval ( EGLDisplay dpy, EGLint interval ) +EGLContext eglCreateContext ( EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list ) +EGLBoolean eglDestroyContext ( EGLDisplay dpy, EGLContext ctx ) +EGLBoolean eglMakeCurrent ( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx ) +EGLContext eglGetCurrentContext ( void ) +EGLSurface eglGetCurrentSurface ( EGLint readdraw ) +EGLDisplay eglGetCurrentDisplay ( void ) +EGLBoolean eglQueryContext ( EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value ) +EGLBoolean eglWaitGL ( void ) +EGLBoolean eglWaitNative ( EGLint engine ) +EGLBoolean eglSwapBuffers ( EGLDisplay dpy, EGLSurface surface ) +EGLBoolean eglCopyBuffers ( EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target ) diff --git a/opengl/tools/glgen/specs/egl/checks.spec b/opengl/tools/glgen/specs/egl/checks.spec new file mode 100644 index 000000000..34fb1ee01 --- /dev/null +++ b/opengl/tools/glgen/specs/egl/checks.spec @@ -0,0 +1,13 @@ +eglInitialize check major 1 check minor 1 +eglGetConfigs check configs config_size +eglChooseConfig check configs config_size check num_config 1 sentinel attrib_list EGL_NONE +eglGetConfigAttrib check value 1 +//STUB function: //eglCreateWindowSurface sentinel attrib_list EGL_NONE +eglCreatePbufferSurface sentinel attrib_list EGL_NONE +//unsupported: eglCreatePixmapSurface sentinel attrib_list EGL_NONE +eglCreatePixmapSurface unsupported +eglCopyBuffers unsupported +eglQuerySurface check value 1 +eglCreatePbufferFromClientBuffer sentinel attrib_list EGL_NONE +eglCreateContext sentinel attrib_list EGL_NONE +eglQueryContext check value 1 diff --git a/opengl/tools/glgen/src/CFunc.java b/opengl/tools/glgen/src/CFunc.java index 4847694df..a192c0039 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 e0f0ca625..92950ea07 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 000000000..1691b65c2 --- /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. + * + *

The Java interface will have Buffer and array variants for functions that + * have a typed pointer argument. The array variant will convert a single " *data" + * argument to a pair of arguments "[] 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 000000000..aaa748cb6 --- /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 deb2f0165..3f7cb7392 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 9fa2b7418..af9888963 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 nativeRegistrations = new ArrayList(); @@ -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 { - System.out.println("Error: unknown keyword \"" + - checks[index] + "\""); - System.exit(0); + 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 { + 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_", 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 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("}"); diff --git a/opengl/tools/glgen/static/egl/EGLConfig.java b/opengl/tools/glgen/static/egl/EGLConfig.java new file mode 100644 index 000000000..d9aebfc34 --- /dev/null +++ b/opengl/tools/glgen/static/egl/EGLConfig.java @@ -0,0 +1,41 @@ +/* +** +** 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. +*/ + +package android.opengl; + +/** + * @hide + */ +public class EGLConfig extends EGLObjectHandle { + public EGLConfig(int handle) { + super(handle); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + EGLConfig that = (EGLConfig) o; + return getHandle() == that.getHandle(); + } + + @Override + public int hashCode() { + return getHandle(); + } +} diff --git a/opengl/tools/glgen/static/egl/EGLContext.java b/opengl/tools/glgen/static/egl/EGLContext.java new file mode 100644 index 000000000..7b194f377 --- /dev/null +++ b/opengl/tools/glgen/static/egl/EGLContext.java @@ -0,0 +1,41 @@ +/* +** +** 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. +*/ + +package android.opengl; + +/** + * @hide + */ +public class EGLContext extends EGLObjectHandle { + public EGLContext(int handle) { + super(handle); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + EGLContext that = (EGLContext) o; + return getHandle() == that.getHandle(); + } + + @Override + public int hashCode() { + return getHandle(); + } +} diff --git a/opengl/tools/glgen/static/egl/EGLDisplay.java b/opengl/tools/glgen/static/egl/EGLDisplay.java new file mode 100644 index 000000000..a090cf034 --- /dev/null +++ b/opengl/tools/glgen/static/egl/EGLDisplay.java @@ -0,0 +1,41 @@ +/* +** +** 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. +*/ + +package android.opengl; + +/** + * @hide + */ +public class EGLDisplay extends EGLObjectHandle { + public EGLDisplay(int handle) { + super(handle); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + EGLDisplay that = (EGLDisplay) o; + return getHandle() == that.getHandle(); + } + + @Override + public int hashCode() { + return getHandle(); + } +} diff --git a/opengl/tools/glgen/static/egl/EGLObjectHandle.java b/opengl/tools/glgen/static/egl/EGLObjectHandle.java new file mode 100644 index 000000000..01f9bd4af --- /dev/null +++ b/opengl/tools/glgen/static/egl/EGLObjectHandle.java @@ -0,0 +1,33 @@ +/* +** +** 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. +*/ + +package android.opengl; + +/** + * @hide + */ +public abstract class EGLObjectHandle { + private final int mHandle; + + public EGLObjectHandle(int handle) { + mHandle = handle; + } + + public int getHandle() { + return mHandle; + } +} diff --git a/opengl/tools/glgen/static/egl/EGLSurface.java b/opengl/tools/glgen/static/egl/EGLSurface.java new file mode 100644 index 000000000..4800a6491 --- /dev/null +++ b/opengl/tools/glgen/static/egl/EGLSurface.java @@ -0,0 +1,41 @@ +/* +** +** 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. +*/ + +package android.opengl; + +/** + * @hide + */ +public class EGLSurface extends EGLObjectHandle { + public EGLSurface(int handle) { + super(handle); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + EGLSurface that = (EGLSurface) o; + return getHandle() == that.getHandle(); + } + + @Override + public int hashCode() { + return getHandle(); + } +} diff --git a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if new file mode 100644 index 000000000..9330c99ff --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if @@ -0,0 +1,151 @@ +** +** 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. +*/ + +// This source file is automatically generated + +package android.opengl; + +import android.graphics.SurfaceTexture; +import android.view.Surface; +import android.view.SurfaceView; +import android.view.SurfaceHolder; + + +/** +* @hide +*/ +public class EGL14 { + +public static final int EGL_DEFAULT_DISPLAY = 0; +public static EGLContext EGL_NO_CONTEXT = null; +public static EGLDisplay EGL_NO_DISPLAY = null; +public static EGLSurface EGL_NO_SURFACE = null; + +public static final int EGL_FALSE = 0; +public static final int EGL_TRUE = 1; +public static final int EGL_SUCCESS = 0x3000; +public static final int EGL_NOT_INITIALIZED = 0x3001; +public static final int EGL_BAD_ACCESS = 0x3002; +public static final int EGL_BAD_ALLOC = 0x3003; +public static final int EGL_BAD_ATTRIBUTE = 0x3004; +public static final int EGL_BAD_CONFIG = 0x3005; +public static final int EGL_BAD_CONTEXT = 0x3006; +public static final int EGL_BAD_CURRENT_SURFACE = 0x3007; +public static final int EGL_BAD_DISPLAY = 0x3008; +public static final int EGL_BAD_MATCH = 0x3009; +public static final int EGL_BAD_NATIVE_PIXMAP = 0x300A; +public static final int EGL_BAD_NATIVE_WINDOW = 0x300B; +public static final int EGL_BAD_PARAMETER = 0x300C; +public static final int EGL_BAD_SURFACE = 0x300D; +public static final int EGL_CONTEXT_LOST = 0x300E; +public static final int EGL_BUFFER_SIZE = 0x3020; +public static final int EGL_ALPHA_SIZE = 0x3021; +public static final int EGL_BLUE_SIZE = 0x3022; +public static final int EGL_GREEN_SIZE = 0x3023; +public static final int EGL_RED_SIZE = 0x3024; +public static final int EGL_DEPTH_SIZE = 0x3025; +public static final int EGL_STENCIL_SIZE = 0x3026; +public static final int EGL_CONFIG_CAVEAT = 0x3027; +public static final int EGL_CONFIG_ID = 0x3028; +public static final int EGL_LEVEL = 0x3029; +public static final int EGL_MAX_PBUFFER_HEIGHT = 0x302A; +public static final int EGL_MAX_PBUFFER_PIXELS = 0x302B; +public static final int EGL_MAX_PBUFFER_WIDTH = 0x302C; +public static final int EGL_NATIVE_RENDERABLE = 0x302D; +public static final int EGL_NATIVE_VISUAL_ID = 0x302E; +public static final int EGL_NATIVE_VISUAL_TYPE = 0x302F; +public static final int EGL_SAMPLES = 0x3031; +public static final int EGL_SAMPLE_BUFFERS = 0x3032; +public static final int EGL_SURFACE_TYPE = 0x3033; +public static final int EGL_TRANSPARENT_TYPE = 0x3034; +public static final int EGL_TRANSPARENT_BLUE_VALUE = 0x3035; +public static final int EGL_TRANSPARENT_GREEN_VALUE = 0x3036; +public static final int EGL_TRANSPARENT_RED_VALUE = 0x3037; +public static final int EGL_NONE = 0x3038; +public static final int EGL_BIND_TO_TEXTURE_RGB = 0x3039; +public static final int EGL_BIND_TO_TEXTURE_RGBA = 0x303A; +public static final int EGL_MIN_SWAP_INTERVAL = 0x303B; +public static final int EGL_MAX_SWAP_INTERVAL = 0x303C; +public static final int EGL_LUMINANCE_SIZE = 0x303D; +public static final int EGL_ALPHA_MASK_SIZE = 0x303E; +public static final int EGL_COLOR_BUFFER_TYPE = 0x303F; +public static final int EGL_RENDERABLE_TYPE = 0x3040; +public static final int EGL_MATCH_NATIVE_PIXMAP = 0x3041; +public static final int EGL_CONFORMANT = 0x3042; +public static final int EGL_SLOW_CONFIG = 0x3050; +public static final int EGL_NON_CONFORMANT_CONFIG = 0x3051; +public static final int EGL_TRANSPARENT_RGB = 0x3052; +public static final int EGL_RGB_BUFFER = 0x308E; +public static final int EGL_LUMINANCE_BUFFER = 0x308F; +public static final int EGL_NO_TEXTURE = 0x305C; +public static final int EGL_TEXTURE_RGB = 0x305D; +public static final int EGL_TEXTURE_RGBA = 0x305E; +public static final int EGL_TEXTURE_2D = 0x305F; +public static final int EGL_PBUFFER_BIT = 0x0001; +public static final int EGL_PIXMAP_BIT = 0x0002; +public static final int EGL_WINDOW_BIT = 0x0004; +public static final int EGL_VG_COLORSPACE_LINEAR_BIT = 0x0020; +public static final int EGL_VG_ALPHA_FORMAT_PRE_BIT = 0x0040; +public static final int EGL_MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200; +public static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400; +public static final int EGL_OPENGL_ES_BIT = 0x0001; +public static final int EGL_OPENVG_BIT = 0x0002; +public static final int EGL_OPENGL_ES2_BIT = 0x0004; +public static final int EGL_OPENGL_BIT = 0x0008; +public static final int EGL_VENDOR = 0x3053; +public static final int EGL_VERSION = 0x3054; +public static final int EGL_EXTENSIONS = 0x3055; +public static final int EGL_CLIENT_APIS = 0x308D; +public static final int EGL_HEIGHT = 0x3056; +public static final int EGL_WIDTH = 0x3057; +public static final int EGL_LARGEST_PBUFFER = 0x3058; +public static final int EGL_TEXTURE_FORMAT = 0x3080; +public static final int EGL_TEXTURE_TARGET = 0x3081; +public static final int EGL_MIPMAP_TEXTURE = 0x3082; +public static final int EGL_MIPMAP_LEVEL = 0x3083; +public static final int EGL_RENDER_BUFFER = 0x3086; +public static final int EGL_VG_COLORSPACE = 0x3087; +public static final int EGL_VG_ALPHA_FORMAT = 0x3088; +public static final int EGL_HORIZONTAL_RESOLUTION = 0x3090; +public static final int EGL_VERTICAL_RESOLUTION = 0x3091; +public static final int EGL_PIXEL_ASPECT_RATIO = 0x3092; +public static final int EGL_SWAP_BEHAVIOR = 0x3093; +public static final int EGL_MULTISAMPLE_RESOLVE = 0x3099; +public static final int EGL_BACK_BUFFER = 0x3084; +public static final int EGL_SINGLE_BUFFER = 0x3085; +public static final int EGL_VG_COLORSPACE_sRGB = 0x3089; +public static final int EGL_VG_COLORSPACE_LINEAR = 0x308A; +public static final int EGL_VG_ALPHA_FORMAT_NONPRE = 0x308B; +public static final int EGL_VG_ALPHA_FORMAT_PRE = 0x308C; +public static final int EGL_DISPLAY_SCALING = 10000; +public static final int EGL_BUFFER_PRESERVED = 0x3094; +public static final int EGL_BUFFER_DESTROYED = 0x3095; +public static final int EGL_OPENVG_IMAGE = 0x3096; +public static final int EGL_CONTEXT_CLIENT_TYPE = 0x3097; +public static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; +public static final int EGL_MULTISAMPLE_RESOLVE_DEFAULT = 0x309A; +public static final int EGL_MULTISAMPLE_RESOLVE_BOX = 0x309B; +public static final int EGL_OPENGL_ES_API = 0x30A0; +public static final int EGL_OPENVG_API = 0x30A1; +public static final int EGL_OPENGL_API = 0x30A2; +public static final int EGL_DRAW = 0x3059; +public static final int EGL_READ = 0x305A; +public static final int EGL_CORE_NATIVE_ENGINE = 0x305B; + + native private static void _nativeClassInit(); + static { + _nativeClassInit(); + } diff --git a/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp new file mode 100644 index 000000000..7904ac76f --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp @@ -0,0 +1,132 @@ +** +** 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. +*/ + +// This source file is automatically generated + +#include "jni.h" +#include "JNIHelp.h" +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +static int initialized = 0; + +static jclass egldisplayClass; +static jclass eglcontextClass; +static jclass eglsurfaceClass; +static jclass eglconfigClass; + +static jmethodID egldisplayGetHandleID; +static jmethodID eglcontextGetHandleID; +static jmethodID eglsurfaceGetHandleID; +static jmethodID eglconfigGetHandleID; + +static jmethodID egldisplayConstructor; +static jmethodID eglcontextConstructor; +static jmethodID eglsurfaceConstructor; +static jmethodID eglconfigConstructor; + +static jobject eglNoContextObject; +static jobject eglNoDisplayObject; +static jobject eglNoSurfaceObject; + + + +/* Cache method IDs each time the class is loaded. */ + +static void +nativeClassInit(JNIEnv *_env, jclass glImplClass) +{ + jclass egldisplayClassLocal = _env->FindClass("android/opengl/EGLDisplay"); + egldisplayClass = (jclass) _env->NewGlobalRef(egldisplayClassLocal); + jclass eglcontextClassLocal = _env->FindClass("android/opengl/EGLContext"); + eglcontextClass = (jclass) _env->NewGlobalRef(eglcontextClassLocal); + jclass eglsurfaceClassLocal = _env->FindClass("android/opengl/EGLSurface"); + eglsurfaceClass = (jclass) _env->NewGlobalRef(eglsurfaceClassLocal); + jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig"); + eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal); + + egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getHandle", "()I"); + eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getHandle", "()I"); + eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getHandle", "()I"); + eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getHandle", "()I"); + + + egldisplayConstructor = _env->GetMethodID(egldisplayClass, "", "(I)V"); + eglcontextConstructor = _env->GetMethodID(eglcontextClass, "", "(I)V"); + eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "", "(I)V"); + eglconfigConstructor = _env->GetMethodID(eglconfigClass, "", "(I)V"); + + jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, (jint)EGL_NO_CONTEXT); + eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject); + jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, (jint)EGL_NO_DISPLAY); + eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject); + jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, (jint)EGL_NO_SURFACE); + eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject); + + + jclass eglClass = _env->FindClass("android/opengl/EGL14"); + jfieldID noContextFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_CONTEXT", "Landroid/opengl/EGLContext;"); + _env->SetStaticObjectField(eglClass, noContextFieldID, eglNoContextObject); + + jfieldID noDisplayFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_DISPLAY", "Landroid/opengl/EGLDisplay;"); + _env->SetStaticObjectField(eglClass, noDisplayFieldID, eglNoDisplayObject); + + jfieldID noSurfaceFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_SURFACE", "Landroid/opengl/EGLSurface;"); + _env->SetStaticObjectField(eglClass, noSurfaceFieldID, eglNoSurfaceObject); +} + +static void * +fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) { + if (obj == NULL){ + jniThrowException(_env, "java/lang/IllegalArgumentException", + "Object is set to null."); + } + + return (void*) (_env->CallIntMethod(obj, mid)); +} + +static jobject +toEGLHandle(JNIEnv *_env, jclass cls, jmethodID con, void * handle) { + if (cls == eglcontextClass && + (EGLContext)handle == EGL_NO_CONTEXT) { + return eglNoContextObject; + } + + if (cls == egldisplayClass && + (EGLDisplay)handle == EGL_NO_DISPLAY) { + return eglNoDisplayObject; + } + + if (cls == eglsurfaceClass && + (EGLSurface)handle == EGL_NO_SURFACE) { + return eglNoSurfaceObject; + } + + return _env->NewObject(cls, con, (jint)handle); +} + +// -------------------------------------------------------------------------- diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp new file mode 100644 index 000000000..610cde52e --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp @@ -0,0 +1,154 @@ +/* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */ +static jobject +android_eglCreateWindowSurface + (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject win, jintArray attrib_list_ref, jint offset) { + jint _exception = 0; + const char * _exceptionType = ""; + const char * _exceptionMessage = ""; + EGLSurface _returnValue = (EGLSurface) 0; + EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy); + EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config); + int attrib_list_sentinel = 0; + EGLint *attrib_list_base = (EGLint *) 0; + jint _remaining; + EGLint *attrib_list = (EGLint *) 0; + android::sp window; + + if (!attrib_list_ref) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "attrib_list == null"; + goto exit; + } + if (offset < 0) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "offset < 0"; + goto exit; + } + if (win == NULL) { +not_valid_surface: + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface"; + goto exit; + } + + window = android::android_Surface_getNativeWindow(_env, win); + + if (window == NULL) + goto not_valid_surface; + + _remaining = _env->GetArrayLength(attrib_list_ref) - offset; + attrib_list_base = (EGLint *) + _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0); + attrib_list = attrib_list_base + offset; + attrib_list_sentinel = 0; + for (int i = _remaining - 1; i >= 0; i--) { + if (*((EGLint*)(attrib_list + i)) == EGL_NONE){ + attrib_list_sentinel = 1; + break; + } + } + if (attrib_list_sentinel == 0) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "attrib_list must contain EGL_NONE!"; + goto exit; + } + + _returnValue = eglCreateWindowSurface( + (EGLDisplay)dpy_native, + (EGLConfig)config_native, + (EGLNativeWindowType)window.get(), + (EGLint *)attrib_list + ); + +exit: + if (attrib_list_base) { + _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base, + JNI_ABORT); + } + if (_exception) { + jniThrowException(_env, _exceptionType, _exceptionMessage); + } + return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue); +} + +/* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */ +static jobject +android_eglCreateWindowSurfaceTexture + (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject win, jintArray attrib_list_ref, jint offset) { + jint _exception = 0; + const char * _exceptionType = ""; + const char * _exceptionMessage = ""; + EGLSurface _returnValue = (EGLSurface) 0; + EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy); + EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config); + int attrib_list_sentinel = 0; + EGLint *attrib_list_base = (EGLint *) 0; + jint _remaining; + EGLint *attrib_list = (EGLint *) 0; + android::sp window; + android::sp surfaceTexture; + + if (!attrib_list_ref) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "attrib_list == null"; + goto exit; + } + if (offset < 0) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "offset < 0"; + goto exit; + } + if (win == NULL) { +not_valid_surface: + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface"; + goto exit; + } + surfaceTexture = android::SurfaceTexture_getSurfaceTexture(_env, win); + window = new android::SurfaceTextureClient(surfaceTexture); + + if (window == NULL) + goto not_valid_surface; + + _remaining = _env->GetArrayLength(attrib_list_ref) - offset; + attrib_list_base = (EGLint *) + _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0); + attrib_list = attrib_list_base + offset; + attrib_list_sentinel = 0; + for (int i = _remaining - 1; i >= 0; i--) { + if (*((EGLint*)(attrib_list + i)) == EGL_NONE){ + attrib_list_sentinel = 1; + break; + } + } + if (attrib_list_sentinel == 0) { + _exception = 1; + _exceptionType = "java/lang/IllegalArgumentException"; + _exceptionMessage = "attrib_list must contain EGL_NONE!"; + goto exit; + } + + _returnValue = eglCreateWindowSurface( + (EGLDisplay)dpy_native, + (EGLConfig)config_native, + (EGLNativeWindowType)window.get(), + (EGLint *)attrib_list + ); + +exit: + if (attrib_list_base) { + _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base, + JNI_ABORT); + } + if (_exception) { + jniThrowException(_env, _exceptionType, _exceptionMessage); + } + return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue); +} diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.java b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.java new file mode 100644 index 000000000..e42334e18 --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.java @@ -0,0 +1,48 @@ + // C function EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) + + private static native EGLSurface _eglCreateWindowSurface( + EGLDisplay dpy, + EGLConfig config, + Object win, + int[] attrib_list, + int offset + ); + + private static native EGLSurface _eglCreateWindowSurfaceTexture( + EGLDisplay dpy, + EGLConfig config, + Object win, + int[] attrib_list, + int offset + ); + + public static EGLSurface eglCreateWindowSurface(EGLDisplay dpy, + EGLConfig config, + Object win, + int[] attrib_list, + int offset + ){ + Surface sur = null; + if (win instanceof SurfaceView) { + SurfaceView surfaceView = (SurfaceView)win; + sur = surfaceView.getHolder().getSurface(); + } else if (win instanceof SurfaceHolder) { + SurfaceHolder holder = (SurfaceHolder)win; + sur = holder.getSurface(); + } + + EGLSurface surface; + if (sur != null) { + surface = _eglCreateWindowSurface(dpy, config, sur, attrib_list, offset); + } else if (win instanceof SurfaceTexture) { + surface = _eglCreateWindowSurfaceTexture(dpy, config, + win, attrib_list, offset); + } else { + throw new java.lang.UnsupportedOperationException( + "eglCreateWindowSurface() can only be called with an instance of " + + "SurfaceView, SurfaceTexture or SurfaceHolder at the moment, " + + "this will be fixed later."); + } + + return surface; + } diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.nativeReg b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.nativeReg new file mode 100644 index 000000000..c37d05ba7 --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.nativeReg @@ -0,0 +1,2 @@ +{"_eglCreateWindowSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/lang/Object;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreateWindowSurface }, +{"_eglCreateWindowSurfaceTexture", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/lang/Object;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreateWindowSurfaceTexture }, diff --git a/opengl/tools/glgen/stubs/egl/eglQueryString.cpp b/opengl/tools/glgen/stubs/egl/eglQueryString.cpp new file mode 100644 index 000000000..625dad728 --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/eglQueryString.cpp @@ -0,0 +1,10 @@ +/* const char * eglQueryString ( EGLDisplay dpy, EGLint name ) */ +static jstring +android_eglQueryString__Landroind_opengl_EGLDisplay_2I + (JNIEnv *_env, jobject _this, jobject dpy, jint name) { + const char* chars = (const char*) eglQueryString( + (EGLDisplay)fromEGLHandle(_env, egldisplayGetHandleID, dpy), + (EGLint)name + ); + return _env->NewStringUTF(chars); +} diff --git a/opengl/tools/glgen/stubs/egl/eglQueryString.java b/opengl/tools/glgen/stubs/egl/eglQueryString.java new file mode 100644 index 000000000..f5d5a3866 --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/eglQueryString.java @@ -0,0 +1,6 @@ + // C function const char * eglQueryString ( EGLDisplay dpy, EGLint name ) + + public static native String eglQueryString( + EGLDisplay dpy, + int name + ); diff --git a/opengl/tools/glgen/stubs/egl/eglQueryString.nativeReg b/opengl/tools/glgen/stubs/egl/eglQueryString.nativeReg new file mode 100644 index 000000000..8276cdbba --- /dev/null +++ b/opengl/tools/glgen/stubs/egl/eglQueryString.nativeReg @@ -0,0 +1 @@ +{"eglQueryString", "(Landroid/opengl/EGLDisplay;I)Ljava/lang/String;", (void *) android_eglQueryString__Landroind_opengl_EGLDisplay_2I }, diff --git a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl index cd730aa95..e3aea76b0 100644 --- a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl +++ b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl @@ -22,6 +22,7 @@ import android.app.AppGlobals; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.os.Build; +import android.os.UserId; import android.util.Log; import java.nio.Buffer; @@ -66,7 +67,7 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack { int version = 0; IPackageManager pm = AppGlobals.getPackageManager(); try { - ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0); + ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0, UserId.myUserId()); if (applicationInfo != null) { version = applicationInfo.targetSdkVersion; }