diff options
author | kbr <[email protected]> | 2006-08-27 03:52:08 +0000 |
---|---|---|
committer | kbr <[email protected]> | 2006-08-27 03:52:08 +0000 |
commit | ab1d8906991beca3829f2a26ef1e12b0e3f5ee6b (patch) | |
tree | c8a70d2cd195a9db763e2a56860c85475459a152 | |
parent | bdf7b44a36265373606da7556d85dfb9c47dcfdd (diff) |
Changed NativeLibrary.open() to accept boolean argument indicating
whether to search the system path first; perhaps useful if
applications ship only a backup version of native libraries associated
with a particular Java binding. In the case of JOAL we plan to ship a
recent OpenAL implementation so we will not need to search the system
path first. Changed ForceProcAddressGen directive to force
call-through-function-pointer semantics for the targeted function.
Changed JOAL to not link directly against the OpenAL library at all,
but instead to look up all entry points using the GlueGen
NativeLibrary class (instead of the custom dlsym code, now removed) in
particular to solve DSO versioning problems on Linux. Updated EAX
binding to work with dynamically loading OpenAL. Tested on Windows so
far; more testing needed on Linux in Java Web Start scenarios.
git-svn-id: file:///home/mbien/NetBeansProjects/JOGAMP/joal-sync/git-svn/../svn-server-sync/joal/trunk@269 03bf7f67-59de-4072-a415-9a990d468a3f
-rwxr-xr-x | make/build.xml | 59 | ||||
-rwxr-xr-x | make/joal-CustomCCode.c | 44 | ||||
-rwxr-xr-x | make/joal-alc.cfg | 11 | ||||
-rwxr-xr-x | make/joal.cfg | 21 | ||||
-rwxr-xr-x | src/java/net/java/games/joal/NativeLibLoader.java | 14 | ||||
-rwxr-xr-x | src/java/net/java/games/joal/impl/ALProcAddressLookup.java | 30 | ||||
-rw-r--r-- | src/native/eaxfactory.c | 27 |
7 files changed, 67 insertions, 139 deletions
diff --git a/make/build.xml b/make/build.xml index 8ff3829..99d2802 100755 --- a/make/build.xml +++ b/make/build.xml @@ -207,31 +207,31 @@ <target name="declare.win32.vc6" if="isVC6"> <echo message="Win32.VC6" /> <property name="compiler.cfg.id" value="compiler.cfg.win32.msvc" /> - <property name="linker.cfg.id" value="linker.cfg.win32.msvc.joal" /> + <property name="linker.cfg.id" value="linker.cfg.win32.msvc" /> </target> <target name="declare.win32.vc7" if="isVC7"> <echo message="Win32.VC7" /> <property name="compiler.cfg.id" value="compiler.cfg.win32.msvc" /> - <property name="linker.cfg.id" value="linker.cfg.win32.msvc.joal" /> + <property name="linker.cfg.id" value="linker.cfg.win32.msvc" /> </target> <target name="declare.win32.vc8" if="isVC8"> <echo message="Win32.VC8" /> <property name="compiler.cfg.id" value="compiler.cfg.win32.msvc" /> - <property name="linker.cfg.id" value="linker.cfg.win32.msvc.joal" /> + <property name="linker.cfg.id" value="linker.cfg.win32.msvc" /> </target> <target name="declare.win32.vc8_x64" if="isVC8_X64"> <echo message="Win32.VC8_X64" /> <property name="compiler.cfg.id" value="compiler.cfg.win32.msvc" /> - <property name="linker.cfg.id" value="linker.cfg.win32.msvc.joal" /> + <property name="linker.cfg.id" value="linker.cfg.win32.msvc" /> </target> <target name="declare.win32.mingw" if="isMingw"> <echo message="Win32.MingW" /> <property name="compiler.cfg.id" value="compiler.cfg.win32.mingw" /> - <property name="linker.cfg.id" value="linker.cfg.win32.mingw.joal" /> + <property name="linker.cfg.id" value="linker.cfg.win32.mingw" /> </target> <target name="declare.win32" depends="declare.win32.vc6,declare.win32.vc7,declare.win32.vc8,declare.win32.vc8_x64,declare.win32.mingw" if="isWindows"> @@ -243,7 +243,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.linux}" /> <property name="compiler.cfg.id" value="compiler.cfg.linux" /> - <property name="linker.cfg.id" value="linker.cfg.linux.joal" /> + <property name="linker.cfg.id" value="linker.cfg.linux" /> </target> <target name="declare.linux.amd64" if="isLinuxAMD64"> @@ -251,7 +251,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.linux}" /> <property name="compiler.cfg.id" value="compiler.cfg.linux.amd64" /> - <property name="linker.cfg.id" value="linker.cfg.linux.amd64.joal" /> + <property name="linker.cfg.id" value="linker.cfg.linux.amd64" /> </target> <target name="declare.linux.ia64" if="isLinuxIA64"> @@ -259,7 +259,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.linux}" /> <property name="compiler.cfg.id" value="compiler.cfg.linux" /> - <property name="linker.cfg.id" value="linker.cfg.linux.joal" /> + <property name="linker.cfg.id" value="linker.cfg.linux" /> </target> <target name="declare.linux" depends="declare.linux.x86,declare.linux.amd64,declare.linux.ia64" if="isLinux" /> @@ -269,7 +269,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.solaris}" /> <property name="compiler.cfg.id" value="compiler.cfg.solaris" /> - <property name="linker.cfg.id" value="linker.cfg.solaris.joal" /> + <property name="linker.cfg.id" value="linker.cfg.solaris" /> </target> <target name="declare.solaris.sparcv9" if="isSolarisSparcv9"> @@ -277,7 +277,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.solaris}" /> <property name="compiler.cfg.id" value="compiler.cfg.solaris.sparcv9" /> - <property name="linker.cfg.id" value="linker.cfg.solaris.sparcv9.joal" /> + <property name="linker.cfg.id" value="linker.cfg.solaris.sparcv9" /> </target> @@ -286,7 +286,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.solaris}" /> <property name="compiler.cfg.id" value="compiler.cfg.solaris.amd64" /> - <property name="linker.cfg.id.core" value="linker.cfg.solaris.amd64.joal" /> + <property name="linker.cfg.id.core" value="linker.cfg.solaris.amd64" /> </target> <target name="declare.macosx" if="isOSX"> @@ -302,7 +302,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.freebsd}" /> <property name="compiler.cfg.id" value="compiler.cfg.freebsd" /> - <property name="linker.cfg.id" value="linker.cfg.linux.joal" /> + <property name="linker.cfg.id" value="linker.cfg.linux" /> </target> <target name="declare.hpux" if="isHPUX"> @@ -310,7 +310,7 @@ <property name="java.includes.dir.platform" value="${java.includes.dir.hpux}" /> <property name="compiler.cfg.id" value="compiler.cfg.hpux" /> - <property name="linker.cfg.id" value="linker.cfg.hpux.joal" /> + <property name="linker.cfg.id" value="linker.cfg.hpux" /> </target> <!-- ================================================================== --> @@ -447,44 +447,11 @@ <target name="c.configure" depends="gluegen.cpptasks.configure.compiler"> <!-- linker configuration --> - <linker id="linker.cfg.linux.joal" extends="linker.cfg.linux"> - <syslibset dir="${joal.lib.dir}" libs="openal"/> - </linker> - - <linker id="linker.cfg.linux.amd64.joal" extends="linker.cfg.linux.amd64"> - <syslibset dir="${joal.lib.dir}" libs="openal"/> - </linker> - - <linker id="linker.cfg.solaris.joal" extends="linker.cfg.solaris"> - <syslibset dir="${joal.lib.dir}" libs="openal"/> - </linker> - - <linker id="linker.cfg.solaris.sparcv9.joal" extends="linker.cfg.solaris.sparcv9"> - <syslibset dir="${joal.lib.dir}" libs="openal"/> - </linker> - - <linker id="linker.cfg.solaris.amd64.joal" extends="linker.cfg.solaris.amd64"> - <syslibset dir="${joal.lib.dir}" libs="openal"/> - </linker> - - <linker id="linker.cfg.win32.mingw.joal" extends="linker.cfg.win32.mingw"> - <syslibset dir="${joal.lib.dir}" libs="openal32, kernel32"/> - </linker> - - <linker id="linker.cfg.win32.msvc.joal" extends="linker.cfg.win32.msvc"> - <syslibset dir="${joal.lib.dir}" libs="openal32" /> - <syslibset libs="kernel32"/> - </linker> - <linker id="linker.cfg.macosx.joal" extends="linker.cfg.macosx"> <linkerarg value="-framework" /> <linkerarg value="OpenAL" /> </linker> - <linker id="linker.cfg.hpux.joal" extends="linker.cfg.hpux"> - <syslibset dir="${joal.lib.dir}" libs="openal"/> - </linker> - <patternset id="c.src.files.joal"> <include name="${rootrel.src.c}/*.c"/> <include name="${rootrel.generated.c.joal}/*.c"/> diff --git a/make/joal-CustomCCode.c b/make/joal-CustomCCode.c deleted file mode 100755 index 26c9b42..0000000 --- a/make/joal-CustomCCode.c +++ /dev/null @@ -1,44 +0,0 @@ -#if defined(_MSC_VER) /* Windows */ -#include <windows.h> -static HMODULE oalModule = NULL; -#else -/* Hack for Linux */ -#define __USE_GNU -#include <dlfcn.h> -#endif - -/* Java->C glue code: - * Java package: net.java.games.joal.impl.ALImpl - * Java method: long dynamicLookupFunction0(java.lang.String fname) - * C function: ALproc alGetProcAddress(const ALchar * fname); - */ -JNIEXPORT jlong JNICALL -Java_net_java_games_joal_impl_ALImpl_dynamicLookupFunction0__Ljava_lang_String_2(JNIEnv *env, jobject _unused, jstring fname) { - const char* _UTF8fname = NULL; - ALproc _res; - if (fname != NULL) { - if (fname != NULL) { - _UTF8fname = (*env)->GetStringUTFChars(env, fname, (jboolean*)NULL); - if (_UTF8fname == NULL) { - (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/OutOfMemoryError"), - "Failed to get UTF-8 chars for argument \"fname\" in native dispatcher for \"alGetProcAddress\""); - return 0; - } - } - } -#if defined(_MSC_VER) /* Windows */ - if (oalModule == NULL) { - oalModule = GetModuleHandle("OpenAL32"); - } - _res = (ALproc) GetProcAddress(oalModule, _UTF8fname); -/* Looks like we can use dlsym on OS X as well as other Unix flavors */ -/* #elif defined(__APPLE__) && defined(__MACH__) */ /* OS X */ -#else /* Assume vanilla Unix */ - _res = (ALproc) dlsym(RTLD_DEFAULT, _UTF8fname); -#endif - - if (fname != NULL) { - (*env)->ReleaseStringUTFChars(env, fname, _UTF8fname); - } - return (jlong) (intptr_t) _res; -} diff --git a/make/joal-alc.cfg b/make/joal-alc.cfg index 5425fec..8bb623c 100755 --- a/make/joal-alc.cfg +++ b/make/joal-alc.cfg @@ -56,14 +56,9 @@ ReturnValueCapacity alcGetCurrentContext 0 ReturnValueCapacity alcGetCurrentDevice 0 ReturnValueCapacity alcOpenDevice 0 -# These routines need to be statically linked for bootstrapping -SkipProcAddressGen alcOpenDevice -SkipProcAddressGen alcCreateContext -SkipProcAddressGen alcMakeContextCurrent - -# Need an epilogue on alcOpenDevice and alcMakeContextCurrent to set -# up the proc address tables the first time -JavaEpilogue alcOpenDevice ALProcAddressLookup.resetALCProcAddressTable(); +# Need a prologue on alcOpenDevice and epilogue on alcMakeContextCurrent +# to set up the proc address tables the first time +JavaPrologue alcOpenDevice ALProcAddressLookup.resetALCProcAddressTable(); JavaEpilogue alcMakeContextCurrent ALProcAddressLookup.resetALProcAddressTable(); # To be able to use alcGetString before a context is created we need diff --git a/make/joal.cfg b/make/joal.cfg index 7e2d594..3bc9350 100755 --- a/make/joal.cfg +++ b/make/joal.cfg @@ -7,8 +7,6 @@ ImplPackage net.java.games.joal.impl ImplJavaClass ALImpl Extends AL ALConstants -Implements ALImpl DynamicLookupHelper - EmitProcAddressTable true ProcAddressTableClassName ALProcAddressTable GetProcAddressTableExpr ALProcAddressLookup.getALProcAddressTable() @@ -26,17 +24,13 @@ Ignore ^AL_.+ # operation in order to populate the ALProcAddressTable and # ALCProcAddressTable. If / when it is fixed and we don't need # compatibility with preexisting OpenAL 1.0 and 1.1 installations we -# can enable the code below and delete the custom C code for -# dynamicLookupFunction0. +# can enable the code below, except presumably for the bootstrapping +# routines alcOpenDevice, alcCreateContext, alcMakeContextCurrent, and +# alGetProcAddress itself. Ignore alGetProcAddress # This routine is not exposed in the public API # AccessControl alGetProcAddress PACKAGE_PRIVATE -# And it's also statically linked for bootstrapping -# (could also consider looking it up via dlsym to more fully allow -# unloading of OpenAL, but that doesn't seem necessary and requires -# more native code to load/unload libraries) -# SkipProcAddressGen alGetProcAddress # We also have to hack its return type for now because we can't make # just that void* opaque # Opaque long ALproc @@ -60,12 +54,5 @@ CustomCCode #define __cdecl /* Trim non-standard keyword */ CustomCCode #endif CustomCCode #include "efx.h" -CustomJavaCode ALImpl /** Provides dlsym() capabilities because alGetProcAddress is -CustomJavaCode ALImpl broken for core OpenAL routines at least up through OpenAL 1.1. */ -CustomJavaCode ALImpl public long dynamicLookupFunction(String functionName) { -CustomJavaCode ALImpl return dynamicLookupFunction0(functionName); -CustomJavaCode ALImpl } -CustomJavaCode ALImpl private native long dynamicLookupFunction0(String functionName); - IncludeAs CustomCCode joal-common-CustomCCode.c -IncludeAs CustomCCode joal-CustomCCode.c + diff --git a/src/java/net/java/games/joal/NativeLibLoader.java b/src/java/net/java/games/joal/NativeLibLoader.java index 011b1dd..5aace19 100755 --- a/src/java/net/java/games/joal/NativeLibLoader.java +++ b/src/java/net/java/games/joal/NativeLibLoader.java @@ -44,20 +44,6 @@ class NativeLibLoader { static { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { - - boolean useGlueGen = - (System.getProperty("joal.use.gluegen") != null); - - if (useGlueGen) { - // Workaround for problems when OpenAL is not installed; - // want to be able to download the OpenAL shared library - // over e.g. Java Web Start and still link against it, so we - // have to use an alternate loading mechanism to work around - // the JDK's usage of RTLD_LOCAL on Unix platforms - NativeLibrary lib = NativeLibrary.open("OpenAL32", "openal", "openal", - NativeLibLoader.class.getClassLoader()); - } - // Workaround for problem in OpenAL32.dll, which is actually // the "wrapper" DLL which looks for real OpenAL // implementations like nvopenal.dll and "*oal.dll". diff --git a/src/java/net/java/games/joal/impl/ALProcAddressLookup.java b/src/java/net/java/games/joal/impl/ALProcAddressLookup.java index 5291587..687e03b 100755 --- a/src/java/net/java/games/joal/impl/ALProcAddressLookup.java +++ b/src/java/net/java/games/joal/impl/ALProcAddressLookup.java @@ -43,6 +43,30 @@ public class ALProcAddressLookup { private static volatile boolean alTableInitialized = false; private static final ALCProcAddressTable alcTable = new ALCProcAddressTable(); private static volatile boolean alcTableInitialized = false; + private static final DynamicLookup lookup = new DynamicLookup(); + private static volatile NativeLibrary openAL = null; + + static class DynamicLookup implements DynamicLookupHelper { + public long dynamicLookupFunction(String functionName) { + // At some point this may require an OpenAL context to be + // current as we will actually use alGetProcAddress. Since + // this routine is currently broken and there are no + // per-context function pointers anyway we could actually do + // this work anywhere. + if (openAL == null) { + // We choose not to search the system path first because we + // bundle a very recent version of OpenAL which we would like + // to override existing installations + openAL = NativeLibrary.open("OpenAL32", "openal", "openal", + false, + ALProcAddressLookup.class.getClassLoader()); + if (openAL == null) { + throw new RuntimeException("Unable to find and load OpenAL library"); + } + } + return openAL.lookupFunction(functionName); + } + } public static void resetALProcAddressTable() { if (!alTableInitialized) { @@ -55,8 +79,7 @@ public class ALProcAddressLookup { // this work anywhere. We should also in theory have // per-ALcontext ALProcAddressTables and per-ALCdevice // ALCProcAddressTables. - ALImpl impl = (ALImpl) ALFactory.getAL(); - ProcAddressHelper.resetProcAddressTable(alTable, impl); + ProcAddressHelper.resetProcAddressTable(alTable, lookup); alTableInitialized = true; } } @@ -74,8 +97,7 @@ public class ALProcAddressLookup { // this work anywhere. We should also in theory have // per-ALcontext ALProcAddressTables and per-ALCdevice // ALCProcAddressTables. - ALImpl impl = (ALImpl) ALFactory.getAL(); - ProcAddressHelper.resetProcAddressTable(alcTable, impl); + ProcAddressHelper.resetProcAddressTable(alcTable, lookup); alcTableInitialized = true; } } diff --git a/src/native/eaxfactory.c b/src/native/eaxfactory.c index d0e3e9d..6ad89ce 100644 --- a/src/native/eaxfactory.c +++ b/src/native/eaxfactory.c @@ -37,8 +37,12 @@ #include "eax.h" #ifdef _WIN32 -EAXSet eaxSet; // EAXSet function, ret$ -EAXGet eaxGet; // EAXGet function, ret$ +#include <windows.h> +static HMODULE oalModule = NULL; +static LPALISEXTENSIONPRESENT _ptr_alIsExtensionPresent = NULL; +static LPALGETPROCADDRESS _ptr_alGetProcAddress = NULL; +EAXSet eaxSet; // EAXSet function +EAXGet eaxGet; // EAXGet function #endif /* @@ -48,9 +52,20 @@ EAXGet eaxGet; // EAXGet function, ret$ JNIEXPORT void JNICALL Java_net_java_games_joal_eax_EAXFactory_init (JNIEnv *env, jclass clazz) { #ifdef _WIN32 - if(alIsExtensionPresent("EAX2.0")) { - eaxSet = alGetProcAddress((ALubyte*)"EAXSet"); - eaxGet = alGetProcAddress((ALubyte*)"EAXGet"); - } + if (_ptr_alIsExtensionPresent == NULL) { + if (oalModule == NULL) { + oalModule = GetModuleHandle("OpenAL32"); + } + _ptr_alIsExtensionPresent = (LPALISEXTENSIONPRESENT) GetProcAddress(oalModule, "alIsExtensionPresent"); + _ptr_alGetProcAddress = (LPALGETPROCADDRESS) GetProcAddress(oalModule, "alGetProcAddress"); + } + + if (_ptr_alIsExtensionPresent != NULL && + _ptr_alGetProcAddress != NULL) { + if ((*_ptr_alIsExtensionPresent)("EAX2.0")) { + eaxSet = (*_ptr_alGetProcAddress)((ALubyte*)"EAXSet"); + eaxGet = (*_ptr_alGetProcAddress)((ALubyte*)"EAXGet"); + } + } #endif } |