diff options
author | Sven Gothel <[email protected]> | 2010-06-10 09:35:06 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-06-10 09:35:06 +0200 |
commit | 1d333a771ce0bc7c8594e21d031703f698f06a46 (patch) | |
tree | 933d470582896320855fa1d98c1a917edc412c24 | |
parent | 4512900ddcb9ce9a498411d257b1b6d6010ec006 (diff) |
Fix: Locking/Threading; Common IntIntHashMap and Buffers; Fix: glMap*Buffer*; GLX/WGL/CgGL: All runtime dynamic; Misc ..
TODO: Compile and test on MacOSX ..
Fix:
=====
Multithreading/Locking:
See jogl/doc/Implementation/MultiThreading.txt
- Locking layer is not platform agnostic, ie GLContextImpl, GLDrawableImpl, ..
and NEWT: Window/Display
- No more use of JAWT global lock necessary, removed.
- No need for X11 Display lock, on the contrary,
this made the NV driver hang.
- Use common window/surface lock
- All NativeWindow surfaceLock's are recursive now
glMapBuffer: If size is 0, don't do cont with the native call.
glMapBufferRange: Fix capacity.
glNamedBufferDataEXT: Track the size.
glMapNamedBufferEXT: Manual impl. - use the tracked size
glXGetVisualFromFBConfig, glXChooseFBConfig, glXChooseVisual: Instead of
ignoring and implement a renamed version (*Copied), we just use ManualImplementation
for the proper copy-result code.
DesktopGLDynamicLookupHelper: Initialize _hasGLBinding* attributes
in the determing loadGLJNILibrary() method, which is called by super().
Otherwise static init will overwrite them after the super() call.
X11GLXDrawableFactory: Don't release anything at shutdown (removed sharedContext.destroy()),
since this caused a freeze/SEGV sometimes.
Fixed NEWT's reparentWindow() functionality incl NewtCanvasAWT usage.
- Native: if not visible, don't focus, etc
- NewtCanvasAWT: Use the container size to start with
- Run the command on the EDT
Using GlueGen's new DynamicLibraryBundle utility:
- X11, Windows and MacOSX OpenGL adapted to DynamicLibraryBundleInfo.
- X11GLXDynamicLookupHelper -> X11GLXDynamicLibraryBundleInfo
- Remove all path from lib names.
- GL order: libGL.so.1, libGL.so, GL
- shallLinkGlobal: true -> to server some 'old' DRI systems
-> http://dri.sourceforge.net/doc/DRIuserguide.html
- shallLookupGlobal: false
- Try both : glXGetProcAddressARB and glXGetProcAddress
- Using bootstrap: GLX.glXGetProcAddress(long glxGetProcAddressHandle, String glFuncName)
Found the issue with LIBGL_DRIVERS_PATH, ie if not set
no valid GL instance can be found (ie ATI fglrx/DRI).
This may happen if using a differen user than the desktop user
for whom the env var is set within some /etc/X11/Xsession.d/ script.
Enhancements:
=============
GLBufferSizeTracker: Use IntIntHashMap and add DirectState size tracking.
GLBufferStateTracker: Use IntIntHashMap.
GLStateTracker: Use IntIntHashMap.
GLDynamicLookupHelper: More generic (global loading/lookup and GetProcAddress function name list),
remove redundant code.
FIXME:
MacOSXCGLDynamicLookupHelper:
- Not tested
- Not using NSImage lookup anymore as recommended by OSX API Doc,
so dlsym is used always (to be tested)
WindowsWGLDynamicLookupHelper:
- Not tested
GLX/WGL/CgGL is all runtime-dynamic as now, ie loaded and looked-up at runtime,
no compile time dependencies to GL anymore, nor a need to specify CgGL.
Split up WGL in GDI and WGL, to allow proper dynamic runtime linkage of OpenGL32
while using static binding to GDI32
NEWT events generated by native code are enqueued and not send directly.
This should ease locking mechanisms .. if any are necessary.
NEWT: More platform specific code moved to *Impl method,
simplifying the generic code of the superclass and impl protocol.
Cleanup:
=========
Replace all InternalBufferUtil's with com.jogamp.common.nio.Buffers
Removed all InternalBufferUtil's from repository
Removed GLContextImpl notion of 'optimized' surface locking,
where the surface gets unlocked during makeCurrent/release.
This just makes no sense and would impact multithreading in a horrible way.
168 files changed, 3379 insertions, 4419 deletions
diff --git a/doc/Implementation/MultiThreading.txt b/doc/Implementation/MultiThreading.txt new file mode 100644 index 000000000..fb586e1ec --- /dev/null +++ b/doc/Implementation/MultiThreading.txt @@ -0,0 +1,94 @@ + +Locking +========= + +Interface AbstractGraphicsDevice: lock() / unlock() + + - Used to exclusively lock the device + - Current implementations: + - X11GraphicsDevice: XLockDisplay/XUnlockDisplay + + - Shall only be used, where race conditions may happen with + device toolkit calls in regards to windowing resources, + ie create/destroy .. etc + + - We call XInitThreads ASAP and a global X11 lock + is not necessary. + + - To ensure XInitThreads can be issued at first, + GLProfile.initSingleton() shall be called + in the static initializer block of the main class. + + TODO: + However, we have to investigate how to incooperate this + with Applet loading. + If such call ain't possible, a workaround could be to not + call XInitThreads() and utilize AWT locks. + +Interface NativeWindow: lockSurface() / unlockSurface() + + - Used to exclusively lock the surface + + - Implementations: + + - JAWTWindow: + - Recursive Lock + - JAWT SurfaceLock + + - NEWT Window: + - Recursive Lock + - May have platform specific surface lock, currently: None + + +GLContext/GLDrawable Locking: + + - MakeCurrent: NativeWindow:lockSurface() + - Release: NativeWindow:unlockSurface() + + - Create/Destroy/Realize/Swap: + - NativeWindow:lockSurface() + - CreateImpl/DestroyImpl/Realize/Swap + - NativeWindow:unlockSurface() + + - The Window impl. class shall lock the window recursive lock + for all modifying operations. + This should be the same lock as surfaceHandle! + + +Summary: + + Locking is implemented in the platform agnostic code layer. + + Locks and Order: + 1: - NativeWindow Surface/Window Lock + - Locked: + - [makeCurrent .. release] + - create/destroy + + GLContextImpl: + - makeCurrent + - Surface i - out only in error + + - release + - Surface o - makeCurrentImpl + + - create + - Surface i/o + + - destroy + - Surface i/o + + - copy + - Surface i/o + + - setSwapIntervalImpl + - Surface i/o + + + GLDrawableImpl + - setRealizedImpl + - Surface i/o + + - swapBuffersImpl + - [Surface i/o] - if not locked already + diff --git a/make/build-jogl.xml b/make/build-jogl.xml index 9203542a7..74b9da089 100644 --- a/make/build-jogl.xml +++ b/make/build-jogl.xml @@ -38,11 +38,6 @@ - Optional properties: - -Djogl.cg=1 when combined with the build or javadoc targets will cause - the experimental binding to NVidia's Cg language to be built. - - Then you need to define the location of your CG libraries: - - -Dwindows.cg.lib32=<PATH> for Windows x32 and - - -Dwindows.cg.lib64=<PATH> for Windows x64 and - - -Dx11.cg.lib32=<PATH> for X11/Unix x32 - - -Dx11.cg.lib64=<PATH> for X11/Unix x64 - - Thanks to Rob Grzywinski and Artur Biesiadowski for the bulk of the - ANT build, including the GlueGen and StaticGLInfo tasks, the building of @@ -299,7 +294,6 @@ <target name="setup.javacdc"> <copy file="../src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp" tofile="${src.generated.java-cdc}/com/jogamp/opengl/impl/SystemUtil.java" /> - <copy file="../src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp" tofile="${src.generated.java-cdc}/com/jogamp/opengl/impl/InternalBufferUtil.java" /> <copy file="../src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javame_cdc_fp" tofile="${src.generated.java-cdc}/com/jogamp/opengl/util/texture/TextureIO.java" /> <copy file="../src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javame_cdc_fp" tofile="${src.generated.java-cdc}/com/jogamp/opengl/util/texture/spi/DDSImage.java" /> <copy file="../src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javame_cdc_fp" tofile="${src.generated.java-cdc}/com/jogamp/opengl/util/texture/spi/TGAImage.java" /> @@ -307,7 +301,6 @@ <target name="setup.javase"> <copy file="../src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase" tofile="${src.generated.java}/com/jogamp/opengl/impl/SystemUtil.java" /> - <copy file="../src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase" tofile="${src.generated.java}/com/jogamp/opengl/impl/InternalBufferUtil.java" /> <copy file="../src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java.javase" tofile="${src.generated.java}/com/jogamp/opengl/util/texture/TextureIO.java" /> <copy file="../src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java.javase" tofile="${src.generated.java}/com/jogamp/opengl/util/texture/spi/DDSImage.java" /> <copy file="../src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java.javase" tofile="${src.generated.java}/com/jogamp/opengl/util/texture/spi/TGAImage.java" /> @@ -622,7 +615,7 @@ <echo message="Generating EGL implementation class" /> <antcall target="java.generate.copy2temp" inheritRefs="true" /> <dirset id="stub.includes.fileset.platform" dir="." includes="${stub.includes}/${window.es.system}/** ${stub.includes}/common/**" /> - <gluegen src="${stub.includes}/${window.es.system}/window-system.c" + <gluegen src="${stub.includes}/${window.es.system}/window-system1.c" outputRootDir="${build.jogl}" config="${window.es.cfg}" includeRefid="stub.includes.fileset.platform" @@ -644,12 +637,24 @@ </gluegen> </target> - <target name="java.generate.window.system.os" if="window.os.cfg"> + <target name="java.generate.window.system.os0" if="window.os0.cfg"> <echo message="Generating window system glue impl: ${window.os.system}" /> <antcall target="java.generate.copy2temp" inheritRefs="true" /> - <gluegen src="${stub.includes}/${window.os.system}/window-system.c" + <gluegen src="${stub.includes}/${window.os.system}/window-system0.c" outputRootDir="${build.jogl}" - config="${window.os.cfg}" + config="${window.os0.cfg}" + includeRefid="stub.includes.fileset.platform" + emitter="com.sun.gluegen.opengl.GLEmitter"> + <classpath refid="gluegen.classpath" /> + </gluegen> + </target> + + <target name="java.generate.window.system.os1" if="window.os1.cfg"> + <echo message="Generating window system glue impl: ${window.os.system}" /> + <antcall target="java.generate.copy2temp" inheritRefs="true" /> + <gluegen src="${stub.includes}/${window.os.system}/window-system1.c" + outputRootDir="${build.jogl}" + config="${window.os1.cfg}" includeRefid="stub.includes.fileset.platform" emitter="com.sun.gluegen.opengl.GLEmitter"> <classpath refid="gluegen.classpath" /> @@ -659,7 +664,8 @@ <target name="java.generate.gl.platforms" > <dirset id="stub.includes.fileset.platform" dir="." includes="${stub.includes}/${window.os.system}/** ${stub.includes}/${window.es.system}/** ${stub.includes}/common/** ${stub.includes}/opengl/**" /> - <antcall target="java.generate.window.system.os" inheritRefs="true" /> + <antcall target="java.generate.window.system.os0" inheritRefs="true" /> + <antcall target="java.generate.window.system.os1" inheritRefs="true" /> <antcall target="java.generate.platform.glext" inheritRefs="true" /> </target> @@ -688,21 +694,22 @@ <antcall target="java.generate.gl.platforms" inheritRefs="true"> <param name="window.os.system" value="x11"/> - <param name="window.os.cfg" value="${config.jogl}/glx-x11.cfg" /> + <param name="window.os1.cfg" value="${config.jogl}/glx-x11.cfg" /> <param name="glext.platform.cfg" value="${config.jogl}/glxext.cfg" /> <param name="glext.platform.header" value="${stub.includes}/x11/glxext.c" /> </antcall> <antcall target="java.generate.gl.platforms" inheritRefs="true"> <param name="window.os.system" value="win32"/> - <param name="window.os.cfg" value="${config.jogl}/wgl-win32.cfg" /> + <param name="window.os0.cfg" value="${config.jogl}/gdi-win32.cfg" /> + <param name="window.os1.cfg" value="${config.jogl}/wgl-win32.cfg" /> <param name="glext.platform.cfg" value="${config.jogl}/wglext.cfg" /> <param name="glext.platform.header" value="${stub.includes}/win32/wglext.c" /> </antcall> <antcall target="java.generate.gl.platforms" inheritRefs="true"> <param name="window.os.system" value="macosx"/> - <param name="window.os.cfg" value="${config.jogl}/cgl-macosx.cfg" /> + <param name="window.os1.cfg" value="${config.jogl}/cgl-macosx.cfg" /> <param name="glext.platform.cfg" value="${config.jogl}/cglext.cfg" /> <param name="glext.platform.header" value="${stub.includes}/macosx/cglext.c" /> </antcall> @@ -754,7 +761,7 @@ outputRootDir="${build.jogl}" config="${config.jogl}/cg-common.cfg" includeRefid="stub.includes.cg.fileset.all" - emitter="com.sun.gluegen.JavaEmitter"> + emitter="com.sun.gluegen.procaddress.ProcAddressEmitter"> <classpath refid="gluegen.classpath" /> </gluegen> </target> @@ -1108,10 +1115,6 @@ <syslibset libs="Xxf86vm" /> </linker> - <linker id="linker.cfg.linux.jogl.cg" extends="linker.cfg.linux.jogl.x11"> - <syslibset dir="${x11.cg.lib32}" libs="Cg, CgGL"/> - </linker> - <linker id="linker.cfg.linux.amd64.jogl.x11" extends="linker.cfg.linux.amd64"> <syslibset libs="X11"/> <syslibset libs="Xxf86vm" /> @@ -1288,6 +1291,7 @@ <include name="${rootrel.generated.c.jogl}/gl2/GLUgl2_JNI.c"/> <include name="${rootrel.generated.c.jogl}/X11/GLX*.c" if="isX11"/> <include name="${rootrel.generated.c.jogl}/MacOSX/CGL*.c" if="isOSX"/> + <include name="${rootrel.generated.c.jogl}/Windows/GDI*.c" if="isWindows"/> <include name="${rootrel.generated.c.jogl}/Windows/WGL*.c" if="isWindows"/> </patternset> diff --git a/make/config/jogl/cg-common-CustomJavaCode.java b/make/config/jogl/cg-common-CustomJavaCode.java index d1e4f8bf5..cdaa6f2b2 100755 --- a/make/config/jogl/cg-common-CustomJavaCode.java +++ b/make/config/jogl/cg-common-CustomJavaCode.java @@ -1,7 +1,26 @@ +private static DynamicLookupHelper cgDynamicLookupHelper; +private static CgProcAddressTable cgProcAddressTable; + static { - com.jogamp.opengl.impl.GLJNILibLoader.loadCgImpl(); + cgProcAddressTable = new CgProcAddressTable(); + if(null==cgProcAddressTable) { + throw new RuntimeException("Couldn't instantiate CgProcAddressTable"); + } + DynamicLibraryBundle cgDynamicLookupHelper = new DynamicLibraryBundle(new CgDynamicLibraryBundleInfo()); + if(null==cgDynamicLookupHelper) { + throw new RuntimeException("Null CgDynamicLookupHelper"); + } + if(!cgDynamicLookupHelper.isToolLibLoaded()) { + throw new RuntimeException("Couln't load native Cg or CgGL library"); + } + if(!cgDynamicLookupHelper.isGlueLibLoaded(CgDynamicLibraryBundleInfo.getCgGlueLibIndex())) { + throw new RuntimeException("Couln't load native GLue/JNI library"); + } + cgProcAddressTable.reset(cgDynamicLookupHelper); } +public static CgProcAddressTable getCgProcAddressTable() { return cgProcAddressTable; } + /** A convenience method which reads all available data from the InputStream and then calls cgCreateProgram. */ public static CGprogram cgCreateProgramFromStream(CGcontext ctx, int program_type, java.io.InputStream stream, int profile, java.lang.String entry, java.lang.String[] args) throws java.io.IOException { if (stream == null) { diff --git a/make/config/jogl/cg-common.cfg b/make/config/jogl/cg-common.cfg index 927d233a8..ae29d3f80 100644 --- a/make/config/jogl/cg-common.cfg +++ b/make/config/jogl/cg-common.cfg @@ -7,6 +7,14 @@ JavaOutputDir gensrc/classes NativeOutputDir gensrc/native/jogl_cg HierarchicalNativeOutput false +ForceProcAddressGen __ALL__ +LocalProcAddressCallingConvention __ALL__ APIENTRY + +EmitProcAddressTable true +ProcAddressTableClassName CgProcAddressTable +GetProcAddressTableExpr cgProcAddressTable +ProcAddressNameExpr PFN $UPPERCASE({0}) PROC + # # Map const char* return values to Java strings for these functions # @@ -94,6 +102,9 @@ Ignore cgGetProgramOptions # And NativeLibLoader for help loading the native libraries Import com.jogamp.opengl.impl.* +Import com.jogamp.common.os.DynamicLookupHelper; +Import com.jogamp.common.os.DynamicLibraryBundle; +Import com.jogamp.opengl.cg.CgDynamicLibraryBundleInfo; # # NIODirectOnly directives for routines requiring them for semantic reasons diff --git a/make/config/jogl/cgl-macosx.cfg b/make/config/jogl/cgl-macosx.cfg index f2af29e00..2b28d3c68 100644 --- a/make/config/jogl/cgl-macosx.cfg +++ b/make/config/jogl/cgl-macosx.cfg @@ -5,7 +5,7 @@ NativeOutputDir gensrc/native/jogl/MacOSX Package com.jogamp.opengl.impl.macosx.cgl JavaClass CGL -Style allstatic +Style AllStatic Include gl-common.cfg Include gl-common-extensions.cfg Include gl-desktop.cfg diff --git a/make/config/jogl/egl.cfg b/make/config/jogl/egl.cfg index 94984a305..c194de2d0 100755 --- a/make/config/jogl/egl.cfg +++ b/make/config/jogl/egl.cfg @@ -5,7 +5,7 @@ NativeOutputDir gensrc/native/jogl/egl Package com.jogamp.opengl.impl.egl JavaClass EGL -Style allstatic +Style AllStatic # Shouldn't matter which one of these we pick up Include egl-common.cfg diff --git a/make/config/jogl/wgl-CustomCCode.c b/make/config/jogl/gdi-CustomCCode.c index 0fe9ee628..0fe9ee628 100755 --- a/make/config/jogl/wgl-CustomCCode.c +++ b/make/config/jogl/gdi-CustomCCode.c diff --git a/make/config/jogl/gdi-win32.cfg b/make/config/jogl/gdi-win32.cfg new file mode 100644 index 000000000..7d831c7b9 --- /dev/null +++ b/make/config/jogl/gdi-win32.cfg @@ -0,0 +1,26 @@ +# This .cfg file is used to generate the interface to the wgl routines +# used internally by the WindowsGLContext implementation. +JavaOutputDir gensrc/classes +NativeOutputDir gensrc/native/jogl/Windows + +Package com.jogamp.opengl.impl.windows.wgl +JavaClass GDI +Style AllStatic +Include gl-common.cfg +Include gl-common-extensions.cfg +Include gl-desktop.cfg + +GLHeader wingdi.h + +AllowNonGLExtensions true + +CustomCCode #define WIN32_LEAN_AND_MEAN +CustomCCode #include <windows.h> +CustomCCode #undef WIN32_LEAN_AND_MEAN + +CustomCCode #include <wingdi.h> +CustomCCode #include <stddef.h> + +Include ../intptr.cfg + +IncludeAs CustomCCode gdi-CustomCCode.c diff --git a/make/config/jogl/gl-common.cfg b/make/config/jogl/gl-common.cfg index 8d726c4bf..2c8e79e75 100644 --- a/make/config/jogl/gl-common.cfg +++ b/make/config/jogl/gl-common.cfg @@ -39,6 +39,7 @@ Ignore glTracePointerRangeMESA # Manually implement glMapBuffer as the size of the returned buffer # can only be computed by calling another routine ManuallyImplement glMapBuffer +ForceProcAddressGen glMapBuffer # Ignore the ATI_map_object_buffer extension for now unless someone # claims they need it, as it will undoubtedly require a similar @@ -347,6 +348,8 @@ NIODirectOnly glXFreeMemoryNV ReturnValueCapacity wglAllocateMemoryNV {0} ReturnValueCapacity glXAllocateMemoryNV {0} +ReturnValueCapacity glMapBufferRange {2} + # Pass arguments to ARB_vertex_program, ARB_fragment_program, # ARB_shader_objects, NV_vertex_program, NV_fragment_program, and # ARB_vertex_shader as Strings diff --git a/make/config/jogl/gl-desktop.cfg b/make/config/jogl/gl-desktop.cfg index f35ed254b..ce2fefe2f 100755 --- a/make/config/jogl/gl-desktop.cfg +++ b/make/config/jogl/gl-desktop.cfg @@ -51,19 +51,11 @@ Opaque long Visual * # traversed) Ignore Display Ignore Visual -# Implement the first argument to glXGetProcAddress as String instead -# of byte[] ArgumentIsString glXGetProcAddress 0 ArgumentIsString glXGetProcAddressARB 0 ReturnsString glXQueryExtensionsString ReturnsString glXQueryServerString ReturnsString glXGetClientString -TemporaryCVariableDeclaration glXChooseFBConfig int count; -TemporaryCVariableAssignment glXChooseFBConfig count = _ptr3[0]; -ReturnValueCapacity glXChooseFBConfig count * sizeof(GLXFBConfig) -TemporaryCVariableDeclaration glXChooseFBConfigSGIX int count; -TemporaryCVariableAssignment glXChooseFBConfigSGIX count = _ptr3[0]; -ReturnValueCapacity glXChooseFBConfigSGIX count * sizeof(GLXFBConfig) TemporaryCVariableDeclaration glXGetFBConfigs int count; TemporaryCVariableAssignment glXGetFBConfigs count = _nelements_ptr[0]; ReturnValueCapacity glXGetFBConfigs count * sizeof(GLXFBConfig) diff --git a/make/config/jogl/gl-es1.cfg b/make/config/jogl/gl-es1.cfg index da2267186..63905dfff 100755 --- a/make/config/jogl/gl-es1.cfg +++ b/make/config/jogl/gl-es1.cfg @@ -97,4 +97,4 @@ IncludeAs CustomCCode gl-impl-CustomCCode-gles1.c Import javax.media.opengl.GLES1 Import javax.media.opengl.GLES2 Import javax.media.opengl.GL2 -Import com.jogamp.opengl.impl.InternalBufferUtil +Import com.jogamp.common.nio.Buffers; diff --git a/make/config/jogl/gl-es2.cfg b/make/config/jogl/gl-es2.cfg index fd11ffcf0..cdfd7fef8 100755 --- a/make/config/jogl/gl-es2.cfg +++ b/make/config/jogl/gl-es2.cfg @@ -79,6 +79,6 @@ Import javax.media.opengl.GLES2 Import javax.media.opengl.GL2 Import javax.media.opengl.GLArrayData Import javax.media.opengl.GLUniformData -Import com.jogamp.opengl.impl.InternalBufferUtil +Import com.jogamp.common.nio.Buffers; Import java.io.PrintStream diff --git a/make/config/jogl/gl-gl2es12.cfg b/make/config/jogl/gl-gl2es12.cfg index 3942b1419..ec121d777 100644 --- a/make/config/jogl/gl-gl2es12.cfg +++ b/make/config/jogl/gl-gl2es12.cfg @@ -22,11 +22,6 @@ Include gl-common.cfg Include gl-common-extensions.cfg Include gl-desktop.cfg -# Because we're manually implementing glMapBuffer but only producing -# the implementing class, GlueGen doesn't notice that it has to emit a -# proc address table entry for it. Force it to here. -ForceProcAddressGen glMapBuffer - # Force all of the methods to be emitted using dynamic linking so we # don't need to link against any emulation library on the desktop or # depend on the presence of an import library for a particular device @@ -86,5 +81,5 @@ IncludeAs CustomCCode gl-impl-CustomCCode-gl2es12.c Import javax.media.opengl.GLES1 Import javax.media.opengl.GLES2 -Import com.jogamp.opengl.impl.InternalBufferUtil +Import com.jogamp.common.nio.Buffers; Import java.io.PrintStream diff --git a/make/config/jogl/gl-gl4bc.cfg b/make/config/jogl/gl-gl4bc.cfg index 3a3e02041..ccd9723e6 100644 --- a/make/config/jogl/gl-gl4bc.cfg +++ b/make/config/jogl/gl-gl4bc.cfg @@ -46,10 +46,11 @@ Include gl3-common.cfg Include gl4-common.cfg Include gl3-desktop.cfg -# Because we're manually implementing glMapBuffer but only producing -# the implementing class, GlueGen doesn't notice that it has to emit a -# proc address table entry for it. Force it to here. -ForceProcAddressGen glMapBuffer +# Manually implement glMapNamedBufferEXT as the size of the returned buffer +# can only be computed by calling another routine +ManuallyImplement glMapNamedBufferEXT +ForceProcAddressGen glMapNamedBufferEXT +JavaEpilogue glNamedBufferDataEXT bufferSizeTracker.setDirectStateBufferSize({0}, this, {1}); # Force all of the methods to be emitted using dynamic linking so we # don't need to link against any emulation library on the desktop or @@ -106,5 +107,5 @@ Import javax.media.opengl.GL2 Import javax.media.opengl.GL3 Import javax.media.opengl.GL3bc Import javax.media.opengl.GL4 -Import com.jogamp.opengl.impl.InternalBufferUtil +Import com.jogamp.common.nio.Buffers; Import java.io.PrintStream diff --git a/make/config/jogl/gl-impl-CustomCCode-gl4bc.c b/make/config/jogl/gl-impl-CustomCCode-gl4bc.c index bcda20fa4..0bd8b68da 100644 --- a/make/config/jogl/gl-impl-CustomCCode-gl4bc.c +++ b/make/config/jogl/gl-impl-CustomCCode-gl4bc.c @@ -15,6 +15,21 @@ Java_com_jogamp_opengl_impl_gl4_GL4bcImpl_dispatch_1glMapBuffer(JNIEnv *env, job /* Java->C glue code: * Java package: com.jogamp.opengl.impl.gl4.GL4bcImpl + * Java method: long dispatch_glMapNamedBufferEXT(int target, int access) + * C function: void * glMapNamedBufferEXT(GLenum target, GLenum access); + */ +JNIEXPORT jlong JNICALL +Java_com_jogamp_opengl_impl_gl4_GL4bcImpl_dispatch_1glMapNamedBufferEXT(JNIEnv *env, jobject _unused, jint target, jint access, jlong glProcAddress) { + PFNGLMAPNAMEDBUFFEREXTPROC ptr_glMapNamedBufferEXT; + void * _res; + ptr_glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC) (intptr_t) glProcAddress; + assert(ptr_glMapNamedBufferEXT != NULL); + _res = (* ptr_glMapNamedBufferEXT) ((GLenum) target, (GLenum) access); + return (jlong) (intptr_t) _res; +} + +/* Java->C glue code: + * Java package: com.jogamp.opengl.impl.gl4.GL4bcImpl * Java method: ByteBuffer newDirectByteBuffer(long addr, int capacity); * C function: jobject newDirectByteBuffer(jlong addr, jint capacity); */ diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java b/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java index 4bc39b076..cb0d01312 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java @@ -339,16 +339,19 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) { int sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this); + if (0 == sz) { + return null; + } long addr; addr = dispatch_glMapBuffer(target, access, __addr_); - if (addr == 0 || sz == 0) { + if (0 == addr) { return null; } ARBVBOKey key = new ARBVBOKey(addr, sz); ByteBuffer _res = (ByteBuffer) arbVBOCache.get(key); if (_res == null) { _res = newDirectByteBuffer(addr, sz); - InternalBufferUtil.nativeOrder(_res); + Buffers.nativeOrder(_res); arbVBOCache.put(key, _res); } _res.position(0); diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4.java deleted file mode 100644 index a2c70eeee..000000000 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl4.java +++ /dev/null @@ -1,339 +0,0 @@ -// Tracks glBegin/glEnd calls to determine whether it is legal to -// query Vertex Buffer Object state -private boolean inBeginEndPair; - -/* FIXME: refactor dependence on Java 2D / JOGL bridge - -// Tracks creation and destruction of server-side OpenGL objects when -// the Java2D/OpenGL pipeline is enabled and it is using frame buffer -// objects (FBOs) to do its rendering -private GLObjectTracker tracker; - -public void setObjectTracker(GLObjectTracker tracker) { - this.tracker = tracker; -} - -*/ - -public GL3Impl(GLProfile glp, GLContextImpl context) { - this._context = context; - this.bufferSizeTracker = context.getBufferSizeTracker(); - this.bufferStateTracker = context.getBufferStateTracker(); - this.glStateTracker = context.getGLStateTracker(); - this.glProfile = glp; -} - -/** - * Provides platform-independent access to the wglAllocateMemoryNV / - * glXAllocateMemoryNV extension. - */ -public java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { - return _context.glAllocateMemoryNV(arg0, arg1, arg2, arg3); -} - -// -// Helpers for ensuring the correct amount of texture data -// - -/** Returns the number of bytes required to fill in the appropriate - texture. This is computed as closely as possible based on the - pixel pack or unpack parameters. The logic in this routine is - based on code in the SGI OpenGL sample implementation. */ - -private int imageSizeInBytes(int format, int type, int w, int h, int d, - boolean pack) { - int elements = 0; - int esize = 0; - - if (w < 0) return 0; - if (h < 0) return 0; - if (d < 0) return 0; - switch (format) { - case GL_STENCIL_INDEX: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - elements = 4; - break; - /* FIXME ?? - case GL_HILO_NV: - elements = 2; - break; */ - default: - return 0; - } - switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return 0; - } - return imageSizeInBytes(elements * esize, w, h, d, pack); -} - -private GLBufferSizeTracker bufferSizeTracker; -private GLBufferStateTracker bufferStateTracker; -private GLStateTracker glStateTracker; - -private boolean bufferObjectExtensionsInitialized = false; -private boolean haveARBPixelBufferObject; -private boolean haveEXTPixelBufferObject; -private boolean haveGL15; -private boolean haveGL21; -private boolean haveARBVertexBufferObject; - -private void initBufferObjectExtensionChecks() { - if (bufferObjectExtensionsInitialized) - return; - bufferObjectExtensionsInitialized = true; - haveARBPixelBufferObject = isExtensionAvailable("GL_ARB_pixel_buffer_object"); - haveEXTPixelBufferObject = isExtensionAvailable("GL_EXT_pixel_buffer_object"); - haveGL15 = isExtensionAvailable("GL_VERSION_1_5"); - haveGL21 = isExtensionAvailable("GL_VERSION_2_1"); - haveARBVertexBufferObject = isExtensionAvailable("GL_ARB_vertex_buffer_object"); -} - -private boolean checkBufferObject(boolean extension1, - boolean extension2, - boolean extension3, - boolean enabled, - int state, - String kind, boolean throwException) { - if (inBeginEndPair) { - throw new GLException("May not call this between glBegin and glEnd"); - } - boolean avail = (extension1 || extension2 || extension3); - if (!avail) { - if (!enabled) - return true; - if(throwException) { - throw new GLException("Required extensions not available to call this function"); - } - return false; - } - int buffer = bufferStateTracker.getBoundBufferObject(state, this); - if (enabled) { - if (buffer == 0) { - if(throwException) { - throw new GLException(kind + " must be enabled to call this method"); - } - return false; - } - } else { - if (buffer != 0) { - if(throwException) { - throw new GLException(kind + " must be disabled to call this method"); - } - return false; - } - } - return true; -} - -private boolean checkArrayVBODisabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveGL15, - haveARBVertexBufferObject, - false, - false, - GL.GL_ARRAY_BUFFER, - "array vertex_buffer_object", throwException); -} - -private boolean checkArrayVBOEnabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveGL15, - haveARBVertexBufferObject, - false, - true, - GL.GL_ARRAY_BUFFER, - "array vertex_buffer_object", throwException); -} - -private boolean checkElementVBODisabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveGL15, - haveARBVertexBufferObject, - false, - false, - GL.GL_ELEMENT_ARRAY_BUFFER, - "element vertex_buffer_object", throwException); -} - -private boolean checkElementVBOEnabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveGL15, - haveARBVertexBufferObject, - false, - true, - GL.GL_ELEMENT_ARRAY_BUFFER, - "element vertex_buffer_object", throwException); -} - -private boolean checkUnpackPBODisabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveARBPixelBufferObject, - haveEXTPixelBufferObject, - haveGL21, - false, - GL2.GL_PIXEL_UNPACK_BUFFER, - "unpack pixel_buffer_object", throwException); -} - -private boolean checkUnpackPBOEnabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveARBPixelBufferObject, - haveEXTPixelBufferObject, - haveGL21, - true, - GL2.GL_PIXEL_UNPACK_BUFFER, - "unpack pixel_buffer_object", throwException); -} - -private boolean checkPackPBODisabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveARBPixelBufferObject, - haveEXTPixelBufferObject, - haveGL21, - false, - GL2.GL_PIXEL_PACK_BUFFER, - "pack pixel_buffer_object", throwException); -} - -private boolean checkPackPBOEnabled(boolean throwException) { - initBufferObjectExtensionChecks(); - return checkBufferObject(haveARBPixelBufferObject, - haveEXTPixelBufferObject, - haveGL21, - true, - GL2.GL_PIXEL_PACK_BUFFER, - "pack pixel_buffer_object", throwException); -} - -public boolean glIsPBOPackEnabled() { - return checkPackPBOEnabled(false); -} - -public boolean glIsPBOUnpackEnabled() { - return checkUnpackPBOEnabled(false); -} - -// Attempt to return the same ByteBuffer object from glMapBuffer if -// the vertex buffer object's base address and size haven't changed -private static class ARBVBOKey { - private long addr; - private int capacity; - - ARBVBOKey(long addr, int capacity) { - this.addr = addr; - this.capacity = capacity; - } - - public int hashCode() { - return (int) addr; - } - - public boolean equals(Object o) { - if ((o == null) || (!(o instanceof ARBVBOKey))) { - return false; - } - - ARBVBOKey other = (ARBVBOKey) o; - return ((addr == other.addr) && (capacity == other.capacity)); - } -} - -private Map/*<ARBVBOKey, ByteBuffer>*/ arbVBOCache = new HashMap(); - -/** Entry point to C language function: <br> <code> LPVOID glMapBuffer(GLenum target, GLenum access); </code> */ -public java.nio.ByteBuffer glMapBuffer(int target, int access) { - final long __addr_ = ((GL3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer; - if (__addr_ == 0) { - throw new GLException("Method \"glMapBuffer\" not available"); - } - int sz = bufferSizeTracker.getBufferSize(bufferStateTracker, - target, - this); - long addr; - addr = dispatch_glMapBuffer(target, access, __addr_); - if (addr == 0 || sz == 0) { - return null; - } - ARBVBOKey key = new ARBVBOKey(addr, sz); - ByteBuffer _res = (ByteBuffer) arbVBOCache.get(key); - if (_res == null) { - _res = newDirectByteBuffer(addr, sz); - InternalBufferUtil.nativeOrder(_res); - arbVBOCache.put(key, _res); - } - _res.position(0); - return _res; -} - -/** Encapsulates function pointer for OpenGL function <br>: <code> LPVOID glMapBuffer(GLenum target, GLenum access); </code> */ -native private long dispatch_glMapBuffer(int target, int access, long glProcAddress); - -native private ByteBuffer newDirectByteBuffer(long addr, int capacity); - - /** Dummy implementation for the ES 2.0 function: <br> <code> void {@native glShaderBinary}(GLint n, const GLuint * shaders, GLenum binaryformat, const void * binary, GLint length); </code> <br> Always throws a GLException! */ - public void glShaderBinary(int n, java.nio.IntBuffer shaders, int binaryformat, java.nio.Buffer binary, int length) { - throw new GLException("Method \"glShaderBinary\" not available"); - } - - /** Dummy implementation for the ES 2.0 function: <br> <code> void {@native glShaderBinary}(GLint n, const GLuint * shaders, GLenum binaryformat, const void * binary, GLint length); </code> <br> Always throws a GLException! */ - public void glShaderBinary(int n, int[] shaders, int shaders_offset, int binaryformat, java.nio.Buffer binary, int length) { - throw new GLException("Method \"glShaderBinary\" not available"); - } - - public void glReleaseShaderCompiler() { - // nothing to do - } - diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java index bceb12fe5..aa176738a 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java @@ -308,19 +308,20 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) { if (__addr_ == 0) { throw new GLException("Method \"glMapBuffer\" not available"); } - int sz = bufferSizeTracker.getBufferSize(bufferStateTracker, - target, - this); + int sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this); + if (0 == sz) { + return null; + } long addr; addr = dispatch_glMapBuffer(target, access, __addr_); - if (addr == 0 || sz == 0) { + if (0 == addr) { return null; } ARBVBOKey key = new ARBVBOKey(addr, sz); ByteBuffer _res = (ByteBuffer) arbVBOCache.get(key); if (_res == null) { _res = newDirectByteBuffer(addr, sz); - InternalBufferUtil.nativeOrder(_res); + Buffers.nativeOrder(_res); arbVBOCache.put(key, _res); } _res.position(0); @@ -330,6 +331,29 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) { /** Encapsulates function pointer for OpenGL function <br>: <code> LPVOID glMapBuffer(GLenum target, GLenum access); </code> */ native private long dispatch_glMapBuffer(int target, int access, long glProcAddress); +/** Entry point to C language function: <code> GLvoid * {@native glMapNamedBufferEXT}(GLuint buffer, GLenum access); </code> <br>Part of <code>GL_EXT_direct_state_access</code> */ +public java.nio.ByteBuffer glMapNamedBufferEXT(int buffer, int access) { + final long __addr_ = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapNamedBufferEXT; + if (__addr_ == 0) { + throw new GLException("Method \"glMapNamedBufferEXT\" not available"); + } + int sz = bufferSizeTracker.getDirectStateBufferSize(buffer, this); + if (0 == sz) { + return null; + } + long addr; + addr = dispatch_glMapNamedBufferEXT(buffer, access, __addr_); + if (0 == addr) { + return null; + } + ByteBuffer _res = newDirectByteBuffer(addr, sz); + Buffers.nativeOrder(_res); + _res.position(0); + return _res; +} + +private native long dispatch_glMapNamedBufferEXT(int buffer, int access, long procAddress); + native private ByteBuffer newDirectByteBuffer(long addr, int capacity); /** Dummy implementation for the ES 2.0 function: <br> <code> void {@native glShaderBinary}(GLint n, const GLuint * shaders, GLenum binaryformat, const void * binary, GLint length); </code> <br> Always throws a GLException! */ diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java index b4efac8a1..d29fe1645 100755 --- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java @@ -285,16 +285,19 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) { int sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this); + if (0 == sz) { + return null; + } long addr; addr = dispatch_glMapBuffer(target, access, __addr_); - if (addr == 0 || sz == 0) { + if (0 == addr) { return null; } ARBVBOKey key = new ARBVBOKey(addr, sz); java.nio.ByteBuffer _res = (java.nio.ByteBuffer) arbVBOCache.get(key); if (_res == null) { _res = newDirectByteBuffer(addr, sz); - InternalBufferUtil.nativeOrder(_res); + Buffers.nativeOrder(_res); arbVBOCache.put(key, _res); } _res.position(0); diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java index bb8ddb7ef..e65c491a2 100755 --- a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java @@ -295,16 +295,19 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) { int sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this); + if (0 == sz) { + return null; + } long addr; addr = dispatch_glMapBuffer(target, access, __addr_); - if (addr == 0 || sz == 0) { + if (0 == addr) { return null; } ARBVBOKey key = new ARBVBOKey(addr, sz); java.nio.ByteBuffer _res = (java.nio.ByteBuffer) arbVBOCache.get(key); if (_res == null) { _res = newDirectByteBuffer(addr, sz); - InternalBufferUtil.nativeOrder(_res); + Buffers.nativeOrder(_res); arbVBOCache.put(key, _res); } _res.position(0); diff --git a/make/config/jogl/gl3-desktop.cfg b/make/config/jogl/gl3-desktop.cfg index ee741089e..19eef4270 100755 --- a/make/config/jogl/gl3-desktop.cfg +++ b/make/config/jogl/gl3-desktop.cfg @@ -47,19 +47,11 @@ Opaque long Visual * # traversed) Ignore Display Ignore Visual -# Implement the first argument to glXGetProcAddress as String instead -# of byte[] ArgumentIsString glXGetProcAddress 0 ArgumentIsString glXGetProcAddressARB 0 ReturnsString glXQueryExtensionsString ReturnsString glXQueryServerString ReturnsString glXGetClientString -TemporaryCVariableDeclaration glXChooseFBConfig int count; -TemporaryCVariableAssignment glXChooseFBConfig count = _ptr3[0]; -ReturnValueCapacity glXChooseFBConfig count * sizeof(GLXFBConfig) -TemporaryCVariableDeclaration glXChooseFBConfigSGIX int count; -TemporaryCVariableAssignment glXChooseFBConfigSGIX count = _ptr3[0]; -ReturnValueCapacity glXChooseFBConfigSGIX count * sizeof(GLXFBConfig) TemporaryCVariableDeclaration glXGetFBConfigs int count; TemporaryCVariableAssignment glXGetFBConfigs count = _nelements_ptr[0]; ReturnValueCapacity glXGetFBConfigs count * sizeof(GLXFBConfig) diff --git a/make/config/jogl/glu-CustomJavaCode-base.java b/make/config/jogl/glu-CustomJavaCode-base.java index 480f5d117..7aee33ae1 100755 --- a/make/config/jogl/glu-CustomJavaCode-base.java +++ b/make/config/jogl/glu-CustomJavaCode-base.java @@ -1382,21 +1382,21 @@ public void gluLookAt(double eyeX, double eyeY, double eyeZ, double centerX, dou * <P> Accepts the outgoing window coordinates as a single array. */ public boolean gluProject(double objX, double objY, double objZ, double[] model, int model_offset, double[] proj, int proj_offset, int[] view, int view_offset, double[] winPos, int winPos_offset) { - return project.gluProject((float)objX, (float)objY, (float)objZ, InternalBufferUtil.getFloatArray(model), model_offset, InternalBufferUtil.getFloatArray(proj), proj_offset, view, view_offset, InternalBufferUtil.getFloatArray(winPos), winPos_offset); + return project.gluProject((float)objX, (float)objY, (float)objZ, Buffers.getFloatArray(model), model_offset, Buffers.getFloatArray(proj), proj_offset, view, view_offset, Buffers.getFloatArray(winPos), winPos_offset); } /** Interface to C language function: <br> <code> GLint gluUnProject(GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble * model, const GLdouble * proj, const GLint * view, GLdouble * objX, GLdouble * objY, GLdouble * objZ); </code> * <P> Accepts the outgoing object coordinates (a 3-vector) as a single array. */ public boolean gluUnProject(double winX, double winY, double winZ, double[] model, int model_offset, double[] proj, int proj_offset, int[] view, int view_offset, double[] objPos, int objPos_offset) { - return project.gluUnProject((float)winX, (float)winY, (float)winZ, InternalBufferUtil.getFloatArray(model), model_offset, InternalBufferUtil.getFloatArray(proj), proj_offset, view, view_offset, InternalBufferUtil.getFloatArray(objPos), objPos_offset); + return project.gluUnProject((float)winX, (float)winY, (float)winZ, Buffers.getFloatArray(model), model_offset, Buffers.getFloatArray(proj), proj_offset, view, view_offset, Buffers.getFloatArray(objPos), objPos_offset); } /** Interface to C language function: <br> <code> GLint gluUnProject4(GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble * model, const GLdouble * proj, const GLint * view, GLdouble nearVal, GLdouble farVal, GLdouble * objX, GLdouble * objY, GLdouble * objZ, GLdouble * objW); </code> * <P> Accepts the outgoing object coordinates (a 4-vector) as a single array. */ public boolean gluUnProject4(double winX, double winY, double winZ, double clipW, double[] model, int model_offset, double[] proj, int proj_offset, int[] view, int view_offset, double nearVal, double farVal, double[] objPos, int objPos_offset) { - return project.gluUnProject4((float)winX, (float)winY, (float)winZ, (float)clipW, InternalBufferUtil.getFloatArray(model), model_offset, InternalBufferUtil.getFloatArray(proj), proj_offset, view, view_offset, (float)nearVal, (float)farVal, InternalBufferUtil.getFloatArray(objPos), objPos_offset); + return project.gluUnProject4((float)winX, (float)winY, (float)winZ, (float)clipW, Buffers.getFloatArray(model), model_offset, Buffers.getFloatArray(proj), proj_offset, view, view_offset, (float)nearVal, (float)farVal, Buffers.getFloatArray(objPos), objPos_offset); } public void gluPickMatrix(double x, double y, double delX, double delY, int[] viewport, int viewport_offset) { diff --git a/make/config/jogl/glu-CustomJavaCode-gl2.java b/make/config/jogl/glu-CustomJavaCode-gl2.java index 3367b2f69..4dcb5691e 100644 --- a/make/config/jogl/glu-CustomJavaCode-gl2.java +++ b/make/config/jogl/glu-CustomJavaCode-gl2.java @@ -218,13 +218,13 @@ private final ByteBuffer copyToByteBuffer(Buffer buf) { if (buf.position() == 0) { return (ByteBuffer) buf; } - return InternalBufferUtil.copyByteBuffer((ByteBuffer) buf); + return Buffers.copyByteBuffer((ByteBuffer) buf); } else if (buf instanceof ShortBuffer) { - return InternalBufferUtil.copyShortBufferAsByteBuffer((ShortBuffer) buf); + return Buffers.copyShortBufferAsByteBuffer((ShortBuffer) buf); } else if (buf instanceof IntBuffer) { - return InternalBufferUtil.copyIntBufferAsByteBuffer((IntBuffer) buf); + return Buffers.copyIntBufferAsByteBuffer((IntBuffer) buf); } else if (buf instanceof FloatBuffer) { - return InternalBufferUtil.copyFloatBufferAsByteBuffer((FloatBuffer) buf); + return Buffers.copyFloatBufferAsByteBuffer((FloatBuffer) buf); } else { throw new IllegalArgumentException("Unsupported buffer type (must be one of byte, short, int, or float)"); } @@ -239,11 +239,11 @@ private final int gluScaleImageJava( int format, int widthin, int heightin, if( dataout instanceof ByteBuffer ) { out = (ByteBuffer)dataout; } else if( dataout instanceof ShortBuffer ) { - out = InternalBufferUtil.newByteBuffer(dataout.remaining() * InternalBufferUtil.SIZEOF_SHORT); + out = Buffers.newDirectByteBuffer(dataout.remaining() * Buffers.SIZEOF_SHORT); } else if ( dataout instanceof IntBuffer ) { - out = InternalBufferUtil.newByteBuffer(dataout.remaining() * InternalBufferUtil.SIZEOF_INT); + out = Buffers.newDirectByteBuffer(dataout.remaining() * Buffers.SIZEOF_INT); } else if ( dataout instanceof FloatBuffer ) { - out = InternalBufferUtil.newByteBuffer(dataout.remaining() * InternalBufferUtil.SIZEOF_FLOAT); + out = Buffers.newDirectByteBuffer(dataout.remaining() * Buffers.SIZEOF_FLOAT); } else { throw new IllegalArgumentException("Unsupported destination buffer type (must be byte, short, int, or float)"); } diff --git a/make/config/jogl/glu-CustomJavaCode-gl2es1.java b/make/config/jogl/glu-CustomJavaCode-gl2es1.java index d3c8ab3d1..742f7c240 100755 --- a/make/config/jogl/glu-CustomJavaCode-gl2es1.java +++ b/make/config/jogl/glu-CustomJavaCode-gl2es1.java @@ -99,13 +99,13 @@ private final java.nio.ByteBuffer copyToByteBuffer(java.nio.Buffer buf) { if (buf.position() == 0) { return (java.nio.ByteBuffer) buf; } - return InternalBufferUtil.copyByteBuffer((java.nio.ByteBuffer) buf); + return Buffers.copyByteBuffer((java.nio.ByteBuffer) buf); } else if (buf instanceof java.nio.ShortBuffer) { - return InternalBufferUtil.copyShortBufferAsByteBuffer((java.nio.ShortBuffer) buf); + return Buffers.copyShortBufferAsByteBuffer((java.nio.ShortBuffer) buf); } else if (buf instanceof java.nio.IntBuffer) { - return InternalBufferUtil.copyIntBufferAsByteBuffer((java.nio.IntBuffer) buf); + return Buffers.copyIntBufferAsByteBuffer((java.nio.IntBuffer) buf); } else if (buf instanceof java.nio.FloatBuffer) { - return InternalBufferUtil.copyFloatBufferAsByteBuffer((java.nio.FloatBuffer) buf); + return Buffers.copyFloatBufferAsByteBuffer((java.nio.FloatBuffer) buf); } else { throw new IllegalArgumentException("Unsupported buffer type (must be one of byte, short, int, or float)"); } @@ -124,11 +124,11 @@ public final int gluScaleImage( int format, int widthin, int heightin, if( dataout instanceof java.nio.ByteBuffer ) { out = (java.nio.ByteBuffer)dataout; } else if( dataout instanceof java.nio.ShortBuffer ) { - out = InternalBufferUtil.newByteBuffer(dataout.remaining() * InternalBufferUtil.SIZEOF_SHORT); + out = Buffers.newDirectByteBuffer(dataout.remaining() * Buffers.SIZEOF_SHORT); } else if ( dataout instanceof java.nio.IntBuffer ) { - out = InternalBufferUtil.newByteBuffer(dataout.remaining() * InternalBufferUtil.SIZEOF_INT); + out = Buffers.newDirectByteBuffer(dataout.remaining() * Buffers.SIZEOF_INT); } else if ( dataout instanceof java.nio.FloatBuffer ) { - out = InternalBufferUtil.newByteBuffer(dataout.remaining() * InternalBufferUtil.SIZEOF_FLOAT); + out = Buffers.newDirectByteBuffer(dataout.remaining() * Buffers.SIZEOF_FLOAT); } else { throw new IllegalArgumentException("Unsupported destination buffer type (must be byte, short, int, or float)"); } diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c index 1b30a7da6..dec3f4583 100755 --- a/make/config/jogl/glx-CustomCCode.c +++ b/make/config/jogl/glx-CustomCCode.c @@ -15,28 +15,28 @@ /* We expect glXGetProcAddressARB to be defined */ extern void (*glXGetProcAddressARB(const GLubyte *procname))(); -static const char * clazzNameInternalBufferUtil = "com/jogamp/opengl/impl/InternalBufferUtil"; -static const char * clazzNameInternalBufferUtilStaticCstrName = "copyByteBuffer"; -static const char * clazzNameInternalBufferUtilStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; +static const char * clazzNameBuffers = "com/jogamp/common/nio/Buffers"; +static const char * clazzNameBuffersStaticCstrName = "copyByteBuffer"; +static const char * clazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; static const char * clazzNameByteBuffer = "java/nio/ByteBuffer"; -static jclass clazzInternalBufferUtil = NULL; -static jmethodID cstrInternalBufferUtil = NULL; +static jclass clazzBuffers = NULL; +static jmethodID cstrBuffers = NULL; static jclass clazzByteBuffer = NULL; static void _initClazzAccess(JNIEnv *env) { jclass c; - if(NULL!=cstrInternalBufferUtil) return ; + if(NULL!=cstrBuffers) return ; - c = (*env)->FindClass(env, clazzNameInternalBufferUtil); + c = (*env)->FindClass(env, clazzNameBuffers); if(NULL==c) { - fprintf(stderr, "FatalError: Java_com_jogamp_opengl_impl_x11_glx_GLX: can't find %s\n", clazzNameInternalBufferUtil); - (*env)->FatalError(env, clazzNameInternalBufferUtil); + fprintf(stderr, "FatalError: Java_com_jogamp_opengl_impl_x11_glx_GLX: can't find %s\n", clazzNameBuffers); + (*env)->FatalError(env, clazzNameBuffers); } - clazzInternalBufferUtil = (jclass)(*env)->NewGlobalRef(env, c); - if(NULL==clazzInternalBufferUtil) { - fprintf(stderr, "FatalError: Java_com_jogamp_opengl_impl_x11_glx_GLX: can't use %s\n", clazzNameInternalBufferUtil); - (*env)->FatalError(env, clazzNameInternalBufferUtil); + clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); + if(NULL==clazzBuffers) { + fprintf(stderr, "FatalError: Java_com_jogamp_opengl_impl_x11_glx_GLX: can't use %s\n", clazzNameBuffers); + (*env)->FatalError(env, clazzNameBuffers); } c = (*env)->FindClass(env, clazzNameByteBuffer); if(NULL==c) { @@ -49,13 +49,13 @@ static void _initClazzAccess(JNIEnv *env) { (*env)->FatalError(env, clazzNameByteBuffer); } - cstrInternalBufferUtil = (*env)->GetStaticMethodID(env, clazzInternalBufferUtil, - clazzNameInternalBufferUtilStaticCstrName, clazzNameInternalBufferUtilStaticCstrSignature); - if(NULL==cstrInternalBufferUtil) { + cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, + clazzNameBuffersStaticCstrName, clazzNameBuffersStaticCstrSignature); + if(NULL==cstrBuffers) { fprintf(stderr, "FatalError: Java_com_jogamp_opengl_impl_x11_glx_GLX:: can't create %s.%s %s\n", - clazzNameInternalBufferUtil, - clazzNameInternalBufferUtilStaticCstrName, clazzNameInternalBufferUtilStaticCstrSignature); - (*env)->FatalError(env, clazzNameInternalBufferUtilStaticCstrName); + clazzNameBuffers, + clazzNameBuffersStaticCstrName, clazzNameBuffersStaticCstrSignature); + (*env)->FatalError(env, clazzNameBuffersStaticCstrName); } } @@ -65,18 +65,21 @@ static void _initClazzAccess(JNIEnv *env) { * C function: XVisualInfo * glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config); */ JNIEXPORT jobject JNICALL -Java_com_jogamp_opengl_impl_x11_glx_GLX_glXGetVisualFromFBConfigCopied0__JJ(JNIEnv *env, jclass _unused, jlong dpy, jlong config) { +Java_com_jogamp_opengl_impl_x11_glx_GLX_dispatch_1glXGetVisualFromFBConfig(JNIEnv *env, jclass _unused, jlong dpy, jlong config, jlong procAddress) { + typedef XVisualInfo* (APIENTRY*_local_PFNGLXGETVISUALFROMFBCONFIG)(Display * dpy, GLXFBConfig config); + _local_PFNGLXGETVISUALFROMFBCONFIG ptr_glXGetVisualFromFBConfig; XVisualInfo * _res; jobject jbyteSource; jobject jbyteCopy; - _res = glXGetVisualFromFBConfig((Display *) (intptr_t) dpy, (GLXFBConfig) (intptr_t) config); + ptr_glXGetVisualFromFBConfig = (_local_PFNGLXGETVISUALFROMFBCONFIG) (intptr_t) procAddress; + assert(ptr_glXGetVisualFromFBConfig != NULL); + _res = (* ptr_glXGetVisualFromFBConfig) ((Display *) (intptr_t) dpy, (GLXFBConfig) (intptr_t) config); if (_res == NULL) return NULL; _initClazzAccess(env); jbyteSource = (*env)->NewDirectByteBuffer(env, _res, sizeof(XVisualInfo)); - jbyteCopy = (*env)->CallStaticObjectMethod(env, - clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource); + jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); (*env)->DeleteLocalRef(env, jbyteSource); XFree(_res); @@ -90,20 +93,24 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXGetVisualFromFBConfigCopied0__JJ(JNIE * C function: GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); */ JNIEXPORT jobject JNICALL -Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseFBConfigCopied1__JILjava_lang_Object_2ILjava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset, jobject nitems, jint nitems_byte_offset) { +Java_com_jogamp_opengl_impl_x11_glx_GLX_dispatch_1glXChooseFBConfig(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset, jobject nitems, jint nitems_byte_offset, jlong procAddress) { + typedef GLXFBConfig* (APIENTRY*_local_PFNGLXCHOOSEFBCONFIG)(Display * dpy, int screen, const int * attribList, int * nitems); + _local_PFNGLXCHOOSEFBCONFIG ptr_glXChooseFBConfig; int * _ptr2 = NULL; int * _ptr3 = NULL; GLXFBConfig * _res; int count; jobject jbyteSource; jobject jbyteCopy; + ptr_glXChooseFBConfig = (_local_PFNGLXCHOOSEFBCONFIG) (intptr_t) procAddress; + assert(ptr_glXChooseFBConfig != NULL); if (attribList != NULL) { _ptr2 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, attribList, NULL)) + attribList_byte_offset); } if (nitems != NULL) { _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, nitems, NULL)) + nitems_byte_offset); } - _res = glXChooseFBConfig((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2, (int *) _ptr3); + _res = (*ptr_glXChooseFBConfig)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2, (int *) _ptr3); count = _ptr3[0]; if (attribList != NULL) { (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0); @@ -116,8 +123,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseFBConfigCopied1__JILjava_lang_O _initClazzAccess(env); jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(GLXFBConfig)); - jbyteCopy = (*env)->CallStaticObjectMethod(env, - clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource); + jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); (*env)->DeleteLocalRef(env, jbyteSource); XFree(_res); @@ -130,15 +136,19 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseFBConfigCopied1__JILjava_lang_O * C function: XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); */ JNIEXPORT jobject JNICALL -Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseVisualCopied1__JILjava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset) { +Java_com_jogamp_opengl_impl_x11_glx_GLX_dispatch_1glXChooseVisual(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset, jlong procAddress) { + typedef XVisualInfo* (APIENTRY*_local_PFNGLXCHOOSEVISUAL)(Display * dpy, int screen, int * attribList); + _local_PFNGLXCHOOSEVISUAL ptr_glXChooseVisual; int * _ptr2 = NULL; XVisualInfo * _res; jobject jbyteSource; jobject jbyteCopy; + ptr_glXChooseVisual = (_local_PFNGLXCHOOSEVISUAL) (intptr_t) procAddress; + assert(ptr_glXChooseVisual != NULL); if (attribList != NULL) { _ptr2 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, attribList, NULL)) + attribList_byte_offset); } - _res = glXChooseVisual((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2); + _res = (*ptr_glXChooseVisual)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2); if (attribList != NULL) { (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0); } @@ -147,8 +157,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseVisualCopied1__JILjava_lang_Obj _initClazzAccess(env); jbyteSource = (*env)->NewDirectByteBuffer(env, _res, sizeof(XVisualInfo)); - jbyteCopy = (*env)->CallStaticObjectMethod(env, - clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource); + jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); (*env)->DeleteLocalRef(env, jbyteSource); XFree(_res); diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java index fe81cd64a..0c3693b8b 100644 --- a/make/config/jogl/glx-CustomJavaCode.java +++ b/make/config/jogl/glx-CustomJavaCode.java @@ -1,46 +1,58 @@ /** Interface to C language function: <br> - Alias for: <br> <code> XVisualInfo * glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config); </code> */ - public static XVisualInfo glXGetVisualFromFBConfigCopied(long dpy, long config) + public static XVisualInfo glXGetVisualFromFBConfig(long dpy, long config) { + final long __addr_ = glxProcAddressTable._addressof_glXGetVisualFromFBConfig; + if (__addr_ == 0) { + throw new GLException("Method \"glXGetVisualFromFBConfig\" not available"); + } java.nio.ByteBuffer _res; - _res = glXGetVisualFromFBConfigCopied0(dpy, config); + _res = dispatch_glXGetVisualFromFBConfig(dpy, config, __addr_); if (_res == null) return null; return XVisualInfo.create(_res); } /** Entry point to C language function: - Alias for: <br> <code> XVisualInfo * glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config); </code> */ - private static native java.nio.ByteBuffer glXGetVisualFromFBConfigCopied0(long dpy, long config); + private static native java.nio.ByteBuffer dispatch_glXGetVisualFromFBConfig(long dpy, long config, long procAddr); /** Interface to C language function: <br> - Alias for: <br> <code> GLXFBConfig * glXChooseFBConfigSGIX, glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); </code> */ - public static com.jogamp.common.nio.PointerBuffer glXChooseFBConfigCopied(long dpy, int screen, int[] attribList, int attribList_offset, int[] nitems, int nitems_offset) + public static com.jogamp.common.nio.PointerBuffer glXChooseFBConfig(long dpy, int screen, int[] attribList, int attribList_offset, int[] nitems, int nitems_offset) { + final long __addr_ = glxProcAddressTable._addressof_glXChooseFBConfig; + if (__addr_ == 0) { + throw new GLException("Method \"glXGetVisualFromFBConfig\" not available"); + } if(attribList != null && attribList.length <= attribList_offset) throw new GLException("array offset argument \"attribList_offset\" (" + attribList_offset + ") equals or exceeds array length (" + attribList.length + ")"); if(nitems != null && nitems.length <= nitems_offset) throw new GLException("array offset argument \"nitems_offset\" (" + nitems_offset + ") equals or exceeds array length (" + nitems.length + ")"); java.nio.ByteBuffer _res; - _res = glXChooseFBConfigCopied1(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, nitems, Buffers.SIZEOF_INT * nitems_offset); + _res = dispatch_glXChooseFBConfig(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, nitems, Buffers.SIZEOF_INT * nitems_offset, __addr_); if (_res == null) return null; return PointerBuffer.wrap(_res); } /** Entry point to C language function: - Alias for: <br> <code> GLXFBConfig * glXChooseFBConfigSGIX, glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); </code> */ - private static native java.nio.ByteBuffer glXChooseFBConfigCopied1(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset); + private static native java.nio.ByteBuffer dispatch_glXChooseFBConfig(long dpy, int screen, Object attribList, int attribList_byte_offset, Object nitems, int nitems_byte_offset, long procAddr); /** Interface to C language function: <br> - Alias for: <br> <code> XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); </code> */ - public static XVisualInfo glXChooseVisualCopied(long dpy, int screen, int[] attribList, int attribList_offset) + public static XVisualInfo glXChooseVisual(long dpy, int screen, int[] attribList, int attribList_offset) { + final long __addr_ = glxProcAddressTable._addressof_glXChooseVisual; + if (__addr_ == 0) { + throw new GLException("Method \"glXChooseVisual\" not available"); + } if(attribList != null && attribList.length <= attribList_offset) throw new GLException("array offset argument \"attribList_offset\" (" + attribList_offset + ") equals or exceeds array length (" + attribList.length + ")"); java.nio.ByteBuffer _res; - _res = glXChooseVisualCopied1(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset); + _res = dispatch_glXChooseVisual(dpy, screen, attribList, Buffers.SIZEOF_INT * attribList_offset, __addr_); if (_res == null) return null; return XVisualInfo.create(_res); } /** Entry point to C language function: - Alias for: <br> <code> XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); </code> */ - private static native java.nio.ByteBuffer glXChooseVisualCopied1(long dpy, int screen, Object attribList, int attribList_byte_offset); + private static native java.nio.ByteBuffer dispatch_glXChooseVisual(long dpy, int screen, Object attribList, int attribList_byte_offset, long procAddr); diff --git a/make/config/jogl/glx-x11.cfg b/make/config/jogl/glx-x11.cfg index f451fa7f3..dee1d015f 100644 --- a/make/config/jogl/glx-x11.cfg +++ b/make/config/jogl/glx-x11.cfg @@ -5,7 +5,7 @@ NativeOutputDir gensrc/native/jogl/X11 Package com.jogamp.opengl.impl.x11.glx JavaClass GLX -Style allstatic +Style AllStatic Include gl-common.cfg Include gl-common-extensions.cfg Include gl-desktop.cfg @@ -13,16 +13,17 @@ Include gl-desktop.cfg GLHeader GL/glx.h GLHeader GL/glxext.h +ForceProcAddressGen __ALL__ +LocalProcAddressCallingConvention __ALL__ APIENTRY + +AllowNonGLExtensions true EmitProcAddressTable true ProcAddressTableClassName GLXProcAddressTable GetProcAddressTableExpr glxProcAddressTable -# This must be present for bootstrapping -SkipProcAddressGen glXGetProcAddressARB Import com.jogamp.nativewindow.impl.x11.* Import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver - CustomJavaCode GLX private static GLXProcAddressTable glxProcAddressTable = new GLXProcAddressTable(new GLProcAddressResolver()); CustomJavaCode GLX public static GLXProcAddressTable getGLXProcAddressTable() { return glxProcAddressTable; } @@ -36,13 +37,16 @@ Opaque long GLXFBConfig Ignore glXCreateContextAttribsARB # -# We have Custom code for the following -Ignore glXGetVisualFromFBConfig +# We have manual code for the following (copying the return values) Ignore glXGetVisualFromFBConfigSGIX -Ignore glXChooseFBConfig -Ignore glXChooseVisual - -# Ignore everything not in the GLX core (up through GLX 1.4) aside from glXGetProcAddress +ManuallyImplement glXGetVisualFromFBConfig +ManuallyImplement glXChooseFBConfig +ManuallyImplement glXChooseVisual +ForceProcAddressGen glXGetVisualFromFBConfig +ForceProcAddressGen glXChooseFBConfig +ForceProcAddressGen glXChooseVisual + +# Ignore everything not in the GLX core (up through GLX 1.4) # FIXME: this needs to be kept in sync with the stub headers more than usual Ignore glXFreeContextEXT Ignore glXGetContextIDEXT @@ -86,3 +90,11 @@ Ignore GLXHyperpipeConfigSGIX Ignore GLXPipeRect Ignore GLXPipeRectLimits +CustomJavaCode GLX protected static long glXGetProcAddress(long glXGetProcAddressHandle, java.lang.String procname) +CustomJavaCode GLX { +CustomJavaCode GLX if (glXGetProcAddressHandle == 0) { +CustomJavaCode GLX throw new GLException("Passed null pointer for method \"glXGetProcAddress\""); +CustomJavaCode GLX } +CustomJavaCode GLX return dispatch_glXGetProcAddress1(procname, glXGetProcAddressHandle); +CustomJavaCode GLX } + diff --git a/make/config/jogl/glxext.cfg b/make/config/jogl/glxext.cfg index 1dfc8fccd..aeed3af4e 100755 --- a/make/config/jogl/glxext.cfg +++ b/make/config/jogl/glxext.cfg @@ -95,7 +95,6 @@ Ignore glXGetCurrentReadDrawable Ignore glXQueryContext Ignore glXSelectEvent Ignore glXGetSelectedEvent -Ignore glXGetProcAddress # Ignore a few extensions that bring in data types we don't want to # expose in the public API (and that are useless anyway without diff --git a/make/config/jogl/wgl-win32.cfg b/make/config/jogl/wgl-win32.cfg index 69f8c75fa..97938a853 100644 --- a/make/config/jogl/wgl-win32.cfg +++ b/make/config/jogl/wgl-win32.cfg @@ -5,16 +5,27 @@ NativeOutputDir gensrc/native/jogl/Windows Package com.jogamp.opengl.impl.windows.wgl JavaClass WGL -Style allstatic +Style AllStatic Include gl-common.cfg Include gl-common-extensions.cfg Include gl-desktop.cfg -AllowNonGLExtensions true - GLHeader wingdi.h GLHeader GL/wglext.h +ForceProcAddressGen __ALL__ +LocalProcAddressCallingConvention __ALL__ APIENTRY + +AllowNonGLExtensions true +EmitProcAddressTable true +ProcAddressTableClassName WGLProcAddressTable +GetProcAddressTableExpr wglProcAddressTable + +Import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver + +CustomJavaCode WGL private static WGLProcAddressTable wglProcAddressTable = new WGLProcAddressTable(new GLProcAddressResolver()); +CustomJavaCode WGL public static WGLProcAddressTable getWGLProcAddressTable() { return wglProcAddressTable; } + # Implement the first argument to wglGetProcAddress as String instead # of byte[] ArgumentIsString wglGetProcAddress 0 @@ -28,8 +39,6 @@ CustomCCode #include <stddef.h> Include ../intptr.cfg -IncludeAs CustomCCode wgl-CustomCCode.c - DropUniqVendorExtensions AMD # We need GL_APPLE_float_pixels for our pbuffer implementation # DropUniqVendorExtensions APPLE @@ -45,3 +54,11 @@ DropUniqVendorExtensions SGIX DropUniqVendorExtensions SUN DropUniqVendorExtensions WIN +CustomJavaCode WGL protected static long wglGetProcAddress(long wglGetProcAddressHandle, java.lang.String procname) +CustomJavaCode WGL { +CustomJavaCode WGL if (wglGetProcAddressHandle == 0) { +CustomJavaCode WGL throw new GLException("Passed null pointer for method \"wglGetProcAddress\""); +CustomJavaCode WGL } +CustomJavaCode WGL return dispatch_wglGetProcAddress1(procname, wglGetProcAddressHandle); +CustomJavaCode WGL } + diff --git a/make/config/jogl/wglext.cfg b/make/config/jogl/wglext.cfg index 35c43cb86..aca757b1c 100644 --- a/make/config/jogl/wglext.cfg +++ b/make/config/jogl/wglext.cfg @@ -36,6 +36,9 @@ GLHeader GL/wglext.h IgnoreExtension WGL_OML_sync_control IgnoreExtension WGL_NV_gpu_affinity +IgnoreExtension WGL_EXT_make_current_read +RenameExtensionIntoCore WGL_ARB_make_current_read + CustomJavaCode WGLExt public boolean isFunctionAvailable(String glFunctionName); CustomJavaCode WGLExt public boolean isExtensionAvailable(String glExtensionName); diff --git a/make/config/nativewindow/jawt-CustomJavaCode.java b/make/config/nativewindow/jawt-CustomJavaCode.java index 87d08241b..3223a74b1 100755 --- a/make/config/nativewindow/jawt-CustomJavaCode.java +++ b/make/config/nativewindow/jawt-CustomJavaCode.java @@ -5,7 +5,7 @@ public static JAWT getJAWT() { if (jawt == null) { synchronized (JAWT.class) { if (jawt == null) { - JAWTUtil.init(); + JAWTUtil.initSingleton(); // Workaround for 4845371. // Make sure the first reference to the JNI GetDirectBufferAddress is done // from a privileged context so the VM's internal class lookups will succeed. diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java index 5919ddc40..41f726916 100644 --- a/make/config/nativewindow/x11-CustomJavaCode.java +++ b/make/config/nativewindow/x11-CustomJavaCode.java @@ -3,12 +3,12 @@ } /** Interface to C language function: <br> <code> XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); </code> */ - public static XVisualInfo[] XGetVisualInfoCopied(long arg0, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) + public static XVisualInfo[] XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) { if(arg3 != null && arg3.length <= arg3_offset) throw new RuntimeException("array offset argument \"arg3_offset\" (" + arg3_offset + ") equals or exceeds array length (" + arg3.length + ")"); java.nio.ByteBuffer _res; - _res = XGetVisualInfoCopied1(arg0, arg1, ((arg2 == null) ? null : arg2.getBuffer()), arg3, Buffers.SIZEOF_INT * arg3_offset); + _res = XGetVisualInfo1(arg0, arg1, ((arg2 == null) ? null : arg2.getBuffer()), arg3, Buffers.SIZEOF_INT * arg3_offset); if (_res == null) return null; Buffers.nativeOrder(_res); @@ -25,7 +25,7 @@ } /** Entry point to C language function: <code> XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); </code> */ - private static native java.nio.ByteBuffer XGetVisualInfoCopied1(long arg0, long arg1, java.nio.ByteBuffer arg2, Object arg3, int arg3_byte_offset); + private static native java.nio.ByteBuffer XGetVisualInfo1(long arg0, long arg1, java.nio.ByteBuffer arg2, Object arg3, int arg3_byte_offset); public static native long DefaultVisualID(long display, int screen); diff --git a/make/jogl.compiler.xml b/make/jogl.compiler.xml index 1033a2851..413920e97 100644 --- a/make/jogl.compiler.xml +++ b/make/jogl.compiler.xml @@ -8,7 +8,6 @@ <linker id="linker.cfg.linux.jogl.gl2" extends="linker.cfg.linux.jogl.x11"> <syslibset dir="/devtools/i686-unknown-linux-gnu/xfree86-4.3.0-linux-ix86-glibc23/lib" libs="GL"/> - <syslibset dir="${x11.cg.lib}" libs="Cg, CgGL" if="c.compiler.use-cglib"/> </linker> </target> </project> diff --git a/make/jogl.properties b/make/jogl.properties index 1a123d7dc..7945cecc5 100644 --- a/make/jogl.properties +++ b/make/jogl.properties @@ -9,14 +9,3 @@ # home directory alongside this file and that copy also modified appropriately. # See that file for additional properties required by the build. # - -# -# If you are building the Cg binding (by specifying -Djogl.cg=1 to the -# Ant build) and have installed the Cg SDK in somewhere other than the -# default location, modify the appropriate variable to point to the -# absolute path of the lib directory -# -windows.cg.lib32=C:/Cg-2.2/bin -windows.cg.lib64=C:/Cg-2.2/bin.x64 -x11.cg.lib32=/usr/lib32 -x11.cg.lib64=/usr/lib64 diff --git a/make/nativewindow.compiler.xml b/make/nativewindow.compiler.xml index b60f9c707..21fd52eac 100644 --- a/make/nativewindow.compiler.xml +++ b/make/nativewindow.compiler.xml @@ -8,7 +8,6 @@ <linker id="linker.cfg.linux.nwi.gl2" extends="linker.cfg.linux.nwi.x11"> <syslibset dir="/devtools/i686-unknown-linux-gnu/xfree86-4.3.0-linux-ix86-glibc23/lib" libs="GL"/> - <syslibset dir="${x11.cg.lib}" libs="Cg, CgGL" if="c.compiler.use-cglib"/> </linker> </target> </project> diff --git a/make/newt.compiler.xml b/make/newt.compiler.xml index 973ef9654..ab405153b 100644 --- a/make/newt.compiler.xml +++ b/make/newt.compiler.xml @@ -8,7 +8,6 @@ <linker id="linker.cfg.linux.newt.gl2" extends="linker.cfg.linux.newt.x11"> <syslibset dir="/devtools/i686-unknown-linux-gnu/xfree86-4.3.0-linux-ix86-glibc23/lib" libs="GL"/> - <syslibset dir="${x11.cg.lib}" libs="Cg, CgGL" if="c.compiler.use-cglib"/> </linker> </target> </project> diff --git a/make/scripts/java-run-all.sh b/make/scripts/java-run-all.sh index 622ed1bae..0188ae5d2 100755 --- a/make/scripts/java-run-all.sh +++ b/make/scripts/java-run-all.sh @@ -17,6 +17,11 @@ if [ "$1" = "-libdir" ] ; then shift LD_LIBRARY_PATH=$PRELIB:$LD_LIBRARY_PATH export LD_LIBRARY_PATH + # Mesa/Gallium EGL driver + EGL_DRIVER=$PRELIB/egl_glx.so + export EGL_DRIVER + # unset DRI/ATI .. + unset LIBGL_DRIVERS_PATH fi if [ -z "$1" ] ; then @@ -31,19 +36,27 @@ shift MOSX=0 uname -a | grep -i Darwin && MOSX=1 -D_ARGS="-Dgluegen.debug.ProcAddressHelper=true -Dgluegen.debug.NativeLibrary=true -Djogl.debug=all" -# D_ARGS="-Dgluegen.debug.ProcAddressHelper=true -Dgluegen.debug.NativeLibrary=true -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all" +# D_ARGS="-Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogl.debug=all" +# D_ARGS="-Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all" # D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all -Djogl.debug.GLSLState" # D_ARGS="-Dnativewindow.debug.X11Util=true -Djogl.debug.GLDrawableFactory=true" # D_ARGS="-Dnativewindow.debug.X11Util=true" # D_ARGS="-Dnewt.debug=all -Dnativewindow.debug=all" +# D_ARGS="-Djogl.debug=all -Dnewt.debug=all -Dnativewindow.debug=all" # D_ARGS="-Dnewt.debug=all" # D_ARGS="-Dnewt.debug.Window" # D_ARGS="-Dnewt.debug.Display" +# D_ARGS="-Djogl.debug=all -Djogl.debug.DynamicLookup=true -Djogamp.debug.NativeLibrary=true" # D_ARGS="-Djogl.debug=all" +# D_ARGS="-Djogamp.debug.JNILibLoader=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true -Djogl.debug.GLProfile=true" rm -f java-run.log +# export LIBGL_DRIVERS_PATH=/usr/lib/fglrx/dri:/usr/lib32/fglrx/dri +# export LIBGL_DEBUG=verbose echo LIBXCB_ALLOW_SLOPPY_LOCK: $LIBXCB_ALLOW_SLOPPY_LOCK 2>&1 | tee -a java-run.log +echo LIBGL_DRIVERS_PATH: $LIBGL_DRIVERS_PATH 2>&1 | tee -a java-run.log +echo LIBGL_DEBUG: $LIBGL_DEBUG 2>&1 | tee -a java-run.log echo java $X_ARGS $D_ARGS $* 2>&1 | tee -a java-run.log java $X_ARGS $D_ARGS $* 2>&1 | tee -a java-run.log + diff --git a/make/scripts/java-run-newt.sh b/make/scripts/java-run-newt.sh index 796e22da4..9fbe4e583 100755 --- a/make/scripts/java-run-newt.sh +++ b/make/scripts/java-run-newt.sh @@ -38,7 +38,8 @@ fi # D_ARGS="-Dgluegen.debug.ProcAddressHelper=true -Dgluegen.debug.NativeLibrary=true -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all" # D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all -Djogl.debug.GLSLState" # D_ARGS="-Dnativewindow.debug.X11Util=true -Djogl.debug.GLDrawableFactory=true" -# D_ARGS="-Dnativewindow.debug.X11Util=true" +# D_ARGS="-Dnativewindow.debug.X11Util=true -Dnewt.debug.Display=true" # D_ARGS="-Dnewt.debug=all" +# D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all" java $X_ARGS -Djava.awt.headless=true $D_ARGS com.jogamp.newt.util.MainThread $* 2>&1 | tee java-run-newt.log diff --git a/make/scripts/make.jogl.all.linux-x86.sh b/make/scripts/make.jogl.all.linux-x86.sh index 5033f5f3a..76b46a03b 100644 --- a/make/scripts/make.jogl.all.linux-x86.sh +++ b/make/scripts/make.jogl.all.linux-x86.sh @@ -28,7 +28,7 @@ if [ "$1" = "-libdir" ] ; then fi -# -Djogl.cg=1 -Dx11.cg.lib=../../lib-linux-x86_64 +# -Djogl.cg=1 # -Dc.compiler.debug=true # -DuseOpenMAX=true \ # -Dbuild.noarchives=true @@ -37,19 +37,29 @@ fi # -DisLinux=true \ # -DisLinuxX86=true \ # -DisX11=true \ -# -Djogl.cg=1 -Dx11.cg.lib=../../lib-linux-x86 \ +# -Djogl.cg=1 \ #LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64 #export LD_LIBRARY_PATH +LOGF=make.jogl.all.linux-x86.log +rm -f $LOGF + +# export LIBGL_DRIVERS_PATH=/usr/lib/fglrx/dri:/usr/lib32/fglrx/dri +# export LIBGL_DEBUG=verbose +echo LIBXCB_ALLOW_SLOPPY_LOCK: $LIBXCB_ALLOW_SLOPPY_LOCK 2>&1 | tee -a $LOGF +echo LIBGL_DRIVERS_PATH: $LIBGL_DRIVERS_PATH 2>&1 | tee -a $LOGF +echo LIBGL_DEBUG: $LIBGL_DEBUG 2>&1 | tee -a $LOGF + ant \ $CUSTOMLIBDIR \ -Dbuild.noarchives=true \ -Dgluegen-cpptasks.file=`pwd`/../../gluegen/make/lib/gluegen-cpptasks-linux-32bit.xml \ -Dbuild.noarchives=true \ - -Djogl.cg=1 -Dx11.cg.lib=../../lib-linux-x86 \ + -Djogl.cg=1 \ -Drootrel.build=build-x86 \ -Dos.arch=x86 \ -DuseKD=true \ -DuseOpenMAX=true \ - $* 2>&1 | tee make.jogl.all.linux-x86.log + $* 2>&1 | tee -a $LOGF + diff --git a/make/scripts/make.jogl.all.linux-x86_64.sh b/make/scripts/make.jogl.all.linux-x86_64.sh index b17cd2f15..220848693 100644 --- a/make/scripts/make.jogl.all.linux-x86_64.sh +++ b/make/scripts/make.jogl.all.linux-x86_64.sh @@ -27,7 +27,7 @@ if [ "$1" = "-libdir" ] ; then shift fi -# -Djogl.cg=1 -Dx11.cg.lib=../../lib-linux-x86_64 +# -Djogl.cg=1 # -Dc.compiler.debug=true \ # -Dbuild.noarchives=true \ @@ -41,11 +41,21 @@ fi #LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64 #export LD_LIBRARY_PATH +LOGF=make.jogl.all.linux-x86_64.log +rm -f $LOGF + +# export LIBGL_DRIVERS_PATH=/usr/lib/fglrx/dri:/usr/lib32/fglrx/dri +# export LIBGL_DEBUG=verbose +echo LIBXCB_ALLOW_SLOPPY_LOCK: $LIBXCB_ALLOW_SLOPPY_LOCK 2>&1 | tee -a $LOGF +echo LIBGL_DRIVERS_PATH: $LIBGL_DRIVERS_PATH 2>&1 | tee -a $LOGF +echo LIBGL_DEBUG: $LIBGL_DEBUG 2>&1 | tee -a $LOGF + ant \ $CUSTOMLIBDIR \ -Dbuild.noarchives=true \ - -Djogl.cg=1 -Dx11.cg.lib=../../lib-linux-x86_64 \ + -Djogl.cg=1 \ -Drootrel.build=build-x86_64 \ -DuseKD=true \ -DuseOpenMAX=true \ - $* 2>&1 | tee make.jogl.all.linux-x86_64.log + $* 2>&1 | tee -a $LOGF + diff --git a/make/scripts/make.jogl.all.win32.bat b/make/scripts/make.jogl.all.win32.bat index cea1317a5..528e153aa 100644 --- a/make/scripts/make.jogl.all.win32.bat +++ b/make/scripts/make.jogl.all.win32.bat @@ -11,7 +11,7 @@ set CLASSPATH=.;%THISDIR%\build-win32\classes REM -Dc.compiler.debug=true
REM -DuseOpenMAX=true
REM -DuseKD=true
-REM -Djogl.cg=1 -D-Dwindows.cg.lib=C:\Cg-2.2
+REM -Djogl.cg=1
REM -Dbuild.noarchives=true
-ant -Dbuild.noarchives=true -Drootrel.build=build-win32 -Djogl.cg=1 -Dwindows.cg.lib=C:\Cg-2.2\bin %1 %2 %3 %4 %5 %6 %7 %8 %9 > make.jogl.all.win32.log 2>&1
+ant -Dbuild.noarchives=true -Drootrel.build=build-win32 -Djogl.cg=1 %1 %2 %3 %4 %5 %6 %7 %8 %9 > make.jogl.all.win32.log 2>&1
diff --git a/make/scripts/make.jogl.all.win64.bat b/make/scripts/make.jogl.all.win64.bat index 5ce53e4a1..b8d8cc662 100644 --- a/make/scripts/make.jogl.all.win64.bat +++ b/make/scripts/make.jogl.all.win64.bat @@ -11,7 +11,7 @@ set CLASSPATH=.;%THISDIR%\build-win64\classes REM -Dc.compiler.debug=true
REM -DuseOpenMAX=true
REM -DuseKD=true
-REM -Djogl.cg=1 -D-Dwindows.cg.lib=C:\Cg-2.2
+REM -Djogl.cg=1
REM -Dbuild.noarchives=true
-ant -Dbuild.noarchives=true -Drootrel.build=build-win64 -Djogl.cg=1 -Dwindows.cg.lib=C:\Cg-2.2\bin.x64 %1 %2 %3 %4 %5 %6 %7 %8 %9 > make.jogl.all.win64.log 2>&1
+ant -Dbuild.noarchives=true -Drootrel.build=build-win64 -Djogl.cg=1 %1 %2 %3 %4 %5 %6 %7 %8 %9 > make.jogl.all.win64.log 2>&1
diff --git a/make/stub_includes/egl/window-system.c b/make/stub_includes/egl/window-system1.c index fbd0f0cde..fbd0f0cde 100755 --- a/make/stub_includes/egl/window-system.c +++ b/make/stub_includes/egl/window-system1.c diff --git a/make/stub_includes/macosx/window-system.c b/make/stub_includes/macosx/window-system1.c index 787d265ed..787d265ed 100644 --- a/make/stub_includes/macosx/window-system.c +++ b/make/stub_includes/macosx/window-system1.c diff --git a/make/stub_includes/win32/window-system.c b/make/stub_includes/win32/window-system0.c index c5c5d37b9..c5c5d37b9 100644 --- a/make/stub_includes/win32/window-system.c +++ b/make/stub_includes/win32/window-system0.c diff --git a/make/stub_includes/win32/window-system1.c b/make/stub_includes/win32/window-system1.c new file mode 100644 index 000000000..f74488c63 --- /dev/null +++ b/make/stub_includes/win32/window-system1.c @@ -0,0 +1,2 @@ +#include <windows.h> +#include <winwgl.h> diff --git a/make/stub_includes/win32/windows.h b/make/stub_includes/win32/windows.h index 647a5733d..20d424a79 100644 --- a/make/stub_includes/win32/windows.h +++ b/make/stub_includes/win32/windows.h @@ -34,14 +34,6 @@ typedef unsigned int UINT; typedef unsigned short USHORT; typedef unsigned short WORD; -typedef struct tagRECT - { - LONG left; - LONG top; - LONG right; - LONG bottom; - } RECT; - /* Necessary handle typedefs for parsing wglext.h */ typedef HANDLE HPBUFFERARB; diff --git a/make/stub_includes/win32/wingdi.h b/make/stub_includes/win32/wingdi.h index a0a4194b5..4a034e81c 100644 --- a/make/stub_includes/win32/wingdi.h +++ b/make/stub_includes/win32/wingdi.h @@ -8,6 +8,15 @@ #ifndef WGL_GDI_VERSION_1_X +/** +typedef struct tagRECT + { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECT; */ + typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; @@ -85,37 +94,6 @@ typedef struct tagPIXELFORMATDESCRIPTOR #define PFD_MAIN_PLANE 0 #define PFD_OVERLAY_PLANE 1 #define PFD_UNDERLAY_PLANE (-1) -#define WGL_SWAP_MAIN_PLANE 1 -#define WGL_SWAP_OVERLAY1 2 -#define WGL_SWAP_OVERLAY2 4 -#define WGL_SWAP_OVERLAY3 8 -#define WGL_SWAP_OVERLAY4 16 -#define WGL_SWAP_OVERLAY5 32 -#define WGL_SWAP_OVERLAY6 64 -#define WGL_SWAP_OVERLAY7 128 -#define WGL_SWAP_OVERLAY8 256 -#define WGL_SWAP_OVERLAY9 512 -#define WGL_SWAP_OVERLAY10 1024 -#define WGL_SWAP_OVERLAY11 2048 -#define WGL_SWAP_OVERLAY12 4096 -#define WGL_SWAP_OVERLAY13 8192 -#define WGL_SWAP_OVERLAY14 16384 -#define WGL_SWAP_OVERLAY15 32768 -#define WGL_SWAP_UNDERLAY1 65536 -#define WGL_SWAP_UNDERLAY2 0x20000 -#define WGL_SWAP_UNDERLAY3 0x40000 -#define WGL_SWAP_UNDERLAY4 0x80000 -#define WGL_SWAP_UNDERLAY5 0x100000 -#define WGL_SWAP_UNDERLAY6 0x200000 -#define WGL_SWAP_UNDERLAY7 0x400000 -#define WGL_SWAP_UNDERLAY8 0x800000 -#define WGL_SWAP_UNDERLAY9 0x1000000 -#define WGL_SWAP_UNDERLAY10 0x2000000 -#define WGL_SWAP_UNDERLAY11 0x4000000 -#define WGL_SWAP_UNDERLAY12 0x8000000 -#define WGL_SWAP_UNDERLAY13 0x10000000 -#define WGL_SWAP_UNDERLAY14 0x20000000 -#define WGL_SWAP_UNDERLAY15 0x40000000 /* PIXELFORMATDESCRIPTOR flags */ #define PFD_DOUBLEBUFFER 0x00000001 @@ -178,16 +156,7 @@ WINGDIAPI int WINAPI ChoosePixelFormat(HDC, CONST PIXELFORMATDESCRIPTOR *); WINGDIAPI int WINAPI DescribePixelFormat(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); WINGDIAPI int WINAPI GetPixelFormat(HDC); WINGDIAPI BOOL WINAPI SetPixelFormat(HDC, int, CONST PIXELFORMATDESCRIPTOR *); -WINGDIAPI BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT); -WINGDIAPI HGLRC WINAPI wglCreateContext(HDC); -WINGDIAPI BOOL WINAPI wglDeleteContext(HGLRC); -WINGDIAPI HGLRC WINAPI wglGetCurrentContext(VOID); -WINGDIAPI HDC WINAPI wglGetCurrentDC(VOID); -WINGDIAPI BOOL WINAPI wglMakeCurrent(HDC, HGLRC); -WINGDIAPI BOOL WINAPI wglShareLists(HGLRC, HGLRC); WINGDIAPI BOOL WINAPI SwapBuffers(HDC); -WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR); -WINGDIAPI BOOL WINAPI wglSwapLayerBuffers(HDC,UINT); /* --- FIXME: need to handle these entry points! WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC, int); @@ -221,3 +190,4 @@ WINGDIAPI BOOL WINAPI GetDeviceGammaRamp(HDC,LPVOID); WINGDIAPI BOOL WINAPI SetDeviceGammaRamp(HDC,LPVOID); #endif /* WGL_GDI_VERSION_1_X */ + diff --git a/make/stub_includes/win32/winwgl.h b/make/stub_includes/win32/winwgl.h new file mode 100644 index 000000000..27b43f915 --- /dev/null +++ b/make/stub_includes/win32/winwgl.h @@ -0,0 +1,72 @@ +/* + * Essential wgl and supporting routines and data structures extracted + * from WINGDI.H. + * + * Copyright (c) 1985-1997, Microsoft Corp. All rights reserved. + * + */ + +#ifndef WGL_GDI_VERSION_1_X + +/* layer types */ +#define WGL_SWAP_MAIN_PLANE 1 +#define WGL_SWAP_OVERLAY1 2 +#define WGL_SWAP_OVERLAY2 4 +#define WGL_SWAP_OVERLAY3 8 +#define WGL_SWAP_OVERLAY4 16 +#define WGL_SWAP_OVERLAY5 32 +#define WGL_SWAP_OVERLAY6 64 +#define WGL_SWAP_OVERLAY7 128 +#define WGL_SWAP_OVERLAY8 256 +#define WGL_SWAP_OVERLAY9 512 +#define WGL_SWAP_OVERLAY10 1024 +#define WGL_SWAP_OVERLAY11 2048 +#define WGL_SWAP_OVERLAY12 4096 +#define WGL_SWAP_OVERLAY13 8192 +#define WGL_SWAP_OVERLAY14 16384 +#define WGL_SWAP_OVERLAY15 32768 +#define WGL_SWAP_UNDERLAY1 65536 +#define WGL_SWAP_UNDERLAY2 0x20000 +#define WGL_SWAP_UNDERLAY3 0x40000 +#define WGL_SWAP_UNDERLAY4 0x80000 +#define WGL_SWAP_UNDERLAY5 0x100000 +#define WGL_SWAP_UNDERLAY6 0x200000 +#define WGL_SWAP_UNDERLAY7 0x400000 +#define WGL_SWAP_UNDERLAY8 0x800000 +#define WGL_SWAP_UNDERLAY9 0x1000000 +#define WGL_SWAP_UNDERLAY10 0x2000000 +#define WGL_SWAP_UNDERLAY11 0x4000000 +#define WGL_SWAP_UNDERLAY12 0x8000000 +#define WGL_SWAP_UNDERLAY13 0x10000000 +#define WGL_SWAP_UNDERLAY14 0x20000000 +#define WGL_SWAP_UNDERLAY15 0x40000000 + +#endif /* WGL_GDI_VERSION_1_X */ + +#ifndef WGL_GDI_VERSION_1_X +#define WGL_GDI_VERSION_1_X + +// OpenGL-related routines +WINGDIAPI BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT); +WINGDIAPI HGLRC WINAPI wglCreateContext(HDC); +WINGDIAPI BOOL WINAPI wglDeleteContext(HGLRC); +WINGDIAPI HGLRC WINAPI wglGetCurrentContext(VOID); +WINGDIAPI HDC WINAPI wglGetCurrentDC(VOID); +WINGDIAPI BOOL WINAPI wglMakeCurrent(HDC, HGLRC); +WINGDIAPI BOOL WINAPI wglShareLists(HGLRC, HGLRC); +WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR); +WINGDIAPI BOOL WINAPI wglSwapLayerBuffers(HDC,UINT); + +/* --- FIXME: need to handle these entry points! +WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC, int); +WINGDIAPI BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD); +WINGDIAPI BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD); +#ifdef UNICODE +#define wglUseFontBitmaps wglUseFontBitmapsW +#else +#define wglUseFontBitmaps wglUseFontBitmapsA +#endif // !UNICODE +*/ + +#endif /* WGL_GDI_VERSION_1_X */ + diff --git a/make/stub_includes/x11/window-system.c b/make/stub_includes/x11/window-system1.c index e718aee97..e718aee97 100644 --- a/make/stub_includes/x11/window-system.c +++ b/make/stub_includes/x11/window-system1.c diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java new file mode 100644 index 000000000..c28e52d07 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2010, Sven Gothel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sven Gothel nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jogamp.opengl.cg; + +import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.common.os.DynamicLibraryBundleInfo; +import com.jogamp.common.os.NativeLibrary; +import com.jogamp.common.os.Platform; +import java.util.*; +import java.security.*; +import javax.media.opengl.GLException; + +public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { + private static List/*<String>*/ glueLibNames; + static { + glueLibNames = new ArrayList(); + // glueLibNames.addAll(getGlueLibNamesPreload()); + glueLibNames.add("jogl_cg"); + } + + public static final int getCgGlueLibIndex() { + return glueLibNames.size()-1; + } + + protected CgDynamicLibraryBundleInfo() { + super(); + } + + /** Make Cg symbols available to CgGL */ + public boolean shallLinkGlobal() { return true; } + + /** default **/ + public boolean shallLookupGlobal() { return false; } + + /** Tool has none **/ + public final List getToolGetProcAddressFuncNameList() { + return null; + } + + /** Tool has none **/ + public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) { + return 0; + } + + public List/*<List<String>>*/ getToolLibNames() { + List/*<List>*/ libNamesList = new ArrayList(); + + libNamesList.add("Cg"); + libNamesList.add("CgGL"); + + return libNamesList; + } + + public final List/*<String>*/ getGlueLibNames() { + return glueLibNames; + } +} + + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLibraryBundleInfo.java new file mode 100755 index 000000000..57a69af4c --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLibraryBundleInfo.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010, Sven Gothel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sven Gothel nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jogamp.opengl.impl; + +import com.jogamp.common.os.DynamicLibraryBundleInfo; +import java.util.List; +import java.util.ArrayList; + +public abstract class DesktopGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo { + private static int posGlueLibGL2ES12; + private static int posGlueLibGLDESKTOP; + private static List/*<String>*/ glueLibNames; + static { + glueLibNames = new ArrayList(); + + glueLibNames.addAll(getGlueLibNamesPreload()); + + posGlueLibGL2ES12 = glueLibNames.size(); + glueLibNames.add("jogl_gl2es12"); + + posGlueLibGLDESKTOP = glueLibNames.size(); + glueLibNames.add("jogl_desktop"); + } + + public static final int getGlueLibPosGL2ES12() { + return posGlueLibGL2ES12; + } + + public static final int getGlueLibPosGLDESKTOP() { + return posGlueLibGLDESKTOP; + } + + public DesktopGLDynamicLibraryBundleInfo() { + super(); + } + + public final List/*<String>*/ getGlueLibNames() { + return glueLibNames; + } +} + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java index f9858df62..4aeea9d42 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java @@ -27,55 +27,45 @@ package com.jogamp.opengl.impl; -/** - * Abstract implementation of the DynamicLookupHelper for GL, - * which decouples it's dependencies to EGLDrawableFactory. - * - * Currently two implementations exist, one for ES1 and one for ES2. - */ -public abstract class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper { - private boolean hasGLBinding = false; - private boolean hasGLES12Binding = false; +import com.jogamp.common.os.DynamicLibraryBundle; +import com.jogamp.common.os.DynamicLibraryBundleInfo; +import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.common.os.NativeLibrary; +import java.util.*; +import java.security.*; +import javax.media.opengl.GLException; - public boolean hasGLBinding() { return hasGLBinding; } - public boolean hasGLES12Binding() { return hasGLES12Binding; } +public class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper { - protected void loadGLJNILibrary() { - Throwable t=null; + public DesktopGLDynamicLookupHelper(DesktopGLDynamicLibraryBundleInfo info) { + super(info); + } - try { - GLJNILibLoader.loadGLDesktop(); - hasGLBinding = true; - } catch (UnsatisfiedLinkError ule) { - t=ule; - } catch (SecurityException se) { - t=se; - } catch (NullPointerException npe) { - t=npe; - } catch (RuntimeException re) { - t=re; - } - if(DEBUG && null!=t) { - System.err.println("DesktopGLDynamicLookupHelper: Desktop GL Binding Library not available"); - t.printStackTrace(); - } + public DesktopGLDynamicLibraryBundleInfo getDesktopGLBundleInfo() { return (DesktopGLDynamicLibraryBundleInfo) getBundleInfo(); } - try { - GLJNILibLoader.loadGLDesktopES12(); - hasGLES12Binding = true; - } catch (UnsatisfiedLinkError ule) { - t=ule; - } catch (SecurityException se) { - t=se; - } catch (NullPointerException npe) { - t=npe; - } catch (RuntimeException re) { - t=re; - } - if(DEBUG && null!=t) { - System.err.println("DesktopGLDynamicLookupHelper: Desktop GLES12 Binding Library not available"); - t.printStackTrace(); + public boolean hasGLBinding() { + return isToolLibLoaded() && isGlueLibLoaded(DesktopGLDynamicLibraryBundleInfo.getGlueLibPosGLDESKTOP()); + } + + public boolean hasGLES12Binding() { + return isToolLibLoaded() && isGlueLibLoaded(DesktopGLDynamicLibraryBundleInfo.getGlueLibPosGL2ES12()); + } + + public synchronized boolean loadGLULibrary() { + /** hacky code .. where all platform GLU libs are tried ..*/ + if(null==gluLib) { + List/*<String>*/ gluLibNames = new ArrayList(); + gluLibNames.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"); // osx + gluLibNames.add("libGLU.so"); // unix + gluLibNames.add("GLU32"); // windows + gluLibNames.add("GLU"); // generic + gluLib = loadFirstAvailable(gluLibNames, null, true); + if(null != gluLib) { + nativeLibraries.add(gluLib); + } } + return null != gluLib ; } + NativeLibrary gluLib = null; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java index 48affa534..b4237501e 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java @@ -39,8 +39,8 @@ package com.jogamp.opengl.impl; -import java.util.*; import javax.media.opengl.*; +import com.jogamp.common.util.IntIntHashMap; /** * Tracks as closely as possible the sizes of allocated OpenGL buffer @@ -93,18 +93,17 @@ public class GLBufferSizeTracker { // objects, which is probably sub-optimal. The expected usage // pattern of buffer objects indicates that the fact that this map // never shrinks is probably not that bad. - private Map/*<Integer,Integer>*/ bufferSizeMap = - Collections.synchronizedMap(new HashMap/*<Integer,Integer>*/()); + private IntIntHashMap bufferSizeMap; private static final boolean DEBUG = Debug.debug("GLBufferSizeTracker"); public GLBufferSizeTracker() { + bufferSizeMap = new IntIntHashMap(); + bufferSizeMap.setKeyNotFoundValue(-1); } public void setBufferSize(GLBufferStateTracker bufferStateTracker, - int target, - GL caller, - int size) { + int target, GL caller, int size) { // Need to do some similar queries to getBufferSize below int buffer = bufferStateTracker.getBoundBufferObject(target, caller); boolean valid = bufferStateTracker.isBoundBufferObjectKnown(target); @@ -118,7 +117,7 @@ public class GLBufferSizeTracker { throw new GLException("Error: no OpenGL buffer object appears to be bound to target 0x" + Integer.toHexString(target)); } - bufferSizeMap.put(new Integer(buffer), new Integer(size)); + setDirectStateBufferSize(buffer, caller, size); } // We don't know the current buffer state. Note that the buffer // state tracker will have made the appropriate OpenGL query if it @@ -126,6 +125,10 @@ public class GLBufferSizeTracker { // left to do except drop this piece of information on the floor. } + public void setDirectStateBufferSize(int buffer, GL caller, int size) { + bufferSizeMap.put(buffer, size); + } + public int getBufferSize(GLBufferStateTracker bufferStateTracker, int target, GL caller) { @@ -134,7 +137,7 @@ public class GLBufferSizeTracker { int buffer = bufferStateTracker.getBoundBufferObject(target, caller); boolean valid = bufferStateTracker.isBoundBufferObjectKnown(target); if (valid) { - if (buffer == 0) { + if (0 == buffer) { // FIXME: this really should not happen if we know what's // going on. Very likely there is an OpenGL error in the // application if we get here. Could silently return 0, but it @@ -143,38 +146,56 @@ public class GLBufferSizeTracker { throw new GLException("Error: no OpenGL buffer object appears to be bound to target 0x" + Integer.toHexString(target)); } + return getBufferSizeImpl(target, buffer, caller); + } + // We don't know what's going on in this case; query the GL for an answer + int[] tmp = new int[1]; + caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0); + if (DEBUG) { + System.err.println("GLBufferSizeTracker.getBufferSize(): no cached buffer information"); + } + return tmp[0]; + } + + public int getDirectStateBufferSize(int buffer, GL caller) { + return getBufferSizeImpl(0, buffer, caller); + } + + private int getBufferSizeImpl(int target, int buffer, GL caller) { // See whether we know the size of this buffer object; at this // point we almost certainly should if the application is // written correctly - Integer key = new Integer(buffer); - Integer sz = (Integer) bufferSizeMap.get(key); - if (sz == null) { + int sz = bufferSizeMap.get(buffer); + if (0 > sz) { // For robustness, try to query this value from the GL as we used to int[] tmp = new int[1]; - caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0); + if(0==target) { + // DirectState .. + if(caller.isFunctionAvailable("glGetNamedBufferParameterivEXT")) { + caller.getGL2().glGetNamedBufferParameterivEXT(buffer, GL.GL_BUFFER_SIZE, tmp, 0); + } else { + throw new GLException("Error: getDirectStateBufferSize called with unknown state and GL function 'glGetNamedBufferParameterivEXT' n/a to query size"); + } + } else { + caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0); + } if (tmp[0] == 0) { // Assume something is wrong rather than silently going along - throw new GLException("Error: buffer size returned by glGetBufferParameteriv was zero; probably application error"); + throw new GLException("Error: buffer size returned by "+ + ((0==target)?"glGetNamedBufferParameterivEXT":"glGetBufferParameteriv")+ + " was zero; probably application error"); } // Assume we just don't know what's happening - sz = new Integer(tmp[0]); - bufferSizeMap.put(key, sz); + sz = tmp[0]; + bufferSizeMap.put(buffer, sz); if (DEBUG) { System.err.println("GLBufferSizeTracker.getBufferSize(): made slow query to cache size " + - tmp[0] + + sz + " for buffer " + buffer); } } - return sz.intValue(); - } - // We don't know what's going on in this case; query the GL for an answer - int[] tmp = new int[1]; - caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0); - if (DEBUG) { - System.err.println("GLBufferSizeTracker.getBufferSize(): no cached buffer information"); - } - return tmp[0]; + return sz; } // This should be called on any major event where we might start diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java index df8d673a1..05b2a2fa9 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java @@ -39,8 +39,8 @@ package com.jogamp.opengl.impl; -import java.util.*; import javax.media.opengl.*; +import com.jogamp.common.util.IntIntHashMap; /** * Tracks as closely as possible which OpenGL buffer object is bound @@ -77,29 +77,28 @@ import javax.media.opengl.*; public class GLBufferStateTracker { private static final boolean DEBUG = Debug.debug("GLBufferStateTracker"); - private static final Integer arrayBufferEnum = new Integer(GL.GL_ARRAY_BUFFER); - private static final Integer elementArrayBufferEnum = new Integer(GL.GL_ELEMENT_ARRAY_BUFFER); - private static final Integer pixelPackBufferEnum = new Integer(GL2.GL_PIXEL_PACK_BUFFER); - private static final Integer pixelUnpackBufferEnum = new Integer(GL2.GL_PIXEL_UNPACK_BUFFER); - private static final Integer zero = new Integer(0); - // Maps binding targets to buffer objects. A null value indicates // that the binding is unknown. A zero value indicates that it is - // known that no buffer is bound to the target. - private Map/*<Integer,Integer>*/ bindingMap = new HashMap/*<Integer,Integer>*/(); + // known that no buffer is bound to the target, according to the + // OpenGL specifications. + // http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml + private IntIntHashMap bindingMap; private int[] bufTmp = new int[1]; public GLBufferStateTracker() { + bindingMap = new IntIntHashMap(); + bindingMap.setKeyNotFoundValue(-1); + // Start with known unbound targets for known keys - bindingMap.put(arrayBufferEnum, zero); - bindingMap.put(elementArrayBufferEnum, zero); - bindingMap.put(pixelPackBufferEnum, zero); - bindingMap.put(pixelUnpackBufferEnum, zero); + bindingMap.put(GL.GL_ARRAY_BUFFER, 0); + bindingMap.put(GL.GL_ELEMENT_ARRAY_BUFFER, 0); + bindingMap.put(GL2.GL_PIXEL_PACK_BUFFER, 0); + bindingMap.put(GL2.GL_PIXEL_UNPACK_BUFFER, 0); } public void setBoundBufferObject(int target, int buffer) { - bindingMap.put(box(target), box(buffer)); + bindingMap.put(target, buffer); } /** Note: returns an unspecified value if the binding for the @@ -107,8 +106,8 @@ public class GLBufferStateTracker { You must use isBoundBufferObjectKnown() to see whether the return value is valid. */ public int getBoundBufferObject(int target, GL caller) { - Integer value = (Integer) bindingMap.get(box(target)); - if (value == null) { + int value = bindingMap.get(target); + if (0 > value) { // User probably either called glPushClientAttrib / // glPopClientAttrib or is querying an unknown target. See // whether we know how to fetch this state. @@ -129,19 +128,19 @@ public class GLBufferStateTracker { " for query target 0x" + Integer.toHexString(queryTarget)); } setBoundBufferObject(target, bufTmp[0]); - // Try once more - return getBoundBufferObject(target, caller); + return bufTmp[0]; } return 0; } - return value.intValue(); + return value; } /** Indicates whether the binding state for the specified target is - currently known. Should be called after getBoundBufferObject() + currently known, ie it could be bound or not but it must be tracked.<br> + Should be called after getBoundBufferObject() because that method may change the answer for a given target. */ public boolean isBoundBufferObjectKnown(int target) { - return (bindingMap.get(box(target)) != null); + return 0 < bindingMap.get(target) ; } /** Clears out the known/unknown state of the various buffer object @@ -154,16 +153,4 @@ public class GLBufferStateTracker { public void clearBufferObjectState() { bindingMap.clear(); } - - // FIXME: could largely remove this and use Integer.valueOf() in JDK 5 - private static Integer box(int key) { - switch (key) { - case 0: return zero; - case GL.GL_ARRAY_BUFFER: return arrayBufferEnum; - case GL.GL_ELEMENT_ARRAY_BUFFER: return elementArrayBufferEnum; - case GL2.GL_PIXEL_PACK_BUFFER: return pixelPackBufferEnum; - case GL2.GL_PIXEL_UNPACK_BUFFER: return pixelUnpackBufferEnum; - default: return new Integer(key); - } - } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index 0742587dd..dc98b5514 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -53,16 +53,6 @@ public abstract class GLContextImpl extends GLContext { protected GLContextLock lock = new GLContextLock(); protected static final boolean DEBUG = Debug.debug("GLContext"); protected static final boolean VERBOSE = Debug.verbose(); - // NOTE: default sense of GLContext optimization disabled in JSR-231 - // 1.0 beta 5 due to problems on X11 platforms (both Linux and - // Solaris) when moving and resizing windows. Apparently GLX tokens - // get sent to the X server under the hood (and out from under the - // cover of the AWT lock) in these situations. Users requiring - // multi-screen X11 applications can manually enable this flag. It - // basically had no tangible effect on the Windows or Mac OS X - // platforms anyway in particular with the disabling of the - // GLWorkerThread which we found to be necessary in 1.0 beta 4. - protected boolean optimizationEnabled = Debug.isPropertyDefined("jogl.GLContext.optimize", true); // Cache of the functions that are available to be called at the current // moment in time @@ -151,21 +141,24 @@ public abstract class GLContextImpl extends GLContext { public abstract Object getPlatformGLExtensions(); + // Note: the surface is locked within [makeCurrent .. swap .. release] public void release() throws GLException { if (!lock.isHeld()) { throw new GLException("Context not current on current thread"); } setCurrent(null); try { - releaseImpl(); + releaseImpl(); } finally { + if (drawable.isSurfaceLocked()) { + drawable.unlockSurface(); + } lock.unlock(); } } - protected abstract void releaseImpl() throws GLException; - public void destroy() { + public final void destroy() { if (lock.isHeld()) { // release current context release(); @@ -209,14 +202,47 @@ public abstract class GLContextImpl extends GLContext { glStateTracker.clearStates(false); } - destroyImpl(); + if (contextHandle != 0) { + int lockRes = drawable.lockSurface(); + if (NativeWindow.LOCK_SURFACE_NOT_READY == lockRes) { + // this would be odd .. + throw new GLException("Surface not ready to lock: "+drawable); + } + try { + destroyImpl(); + contextHandle = 0; + GLContextShareSet.contextDestroyed(this); + } finally { + drawable.unlockSurface(); + } + } } finally { lock.unlock(); } } - protected abstract void destroyImpl() throws GLException; + public final void copy(GLContext source, int mask) throws GLException { + if (source.getHandle() == 0) { + throw new GLException("Source OpenGL context has not been created"); + } + if (getHandle() == 0) { + throw new GLException("Destination OpenGL context has not been created"); + } + + int lockRes = drawable.lockSurface(); + if (NativeWindow.LOCK_SURFACE_NOT_READY == lockRes) { + // this would be odd .. + throw new GLException("Surface not ready to lock"); + } + try { + copyImpl(source, mask); + } finally { + drawable.unlockSurface(); + } + } + protected abstract void copyImpl(GLContext source, int mask) throws GLException; + //---------------------------------------------------------------------- // @@ -285,7 +311,7 @@ public abstract class GLContextImpl extends GLContext { lock.lock(); int res = 0; try { - res = makeCurrentImpl(); + res = makeCurrentLocking(); /* FIXME: refactor dependence on Java 2D / JOGL bridge if ((tracker != null) && @@ -320,15 +346,50 @@ public abstract class GLContextImpl extends GLContext { return res; } - /** - * @see #makeCurrent - */ - protected abstract int makeCurrentImpl() throws GLException; - - /** - * @see #makeCurrent - */ - protected abstract void create() throws GLException ; + // Note: the surface is locked within [makeCurrent .. swap .. release] + protected final int makeCurrentLocking() throws GLException { + boolean exceptionOccurred = false; + int lockRes = drawable.lockSurface(); + try { + if (NativeWindow.LOCK_SURFACE_NOT_READY == lockRes) { + return CONTEXT_NOT_CURRENT; + } + try { + if (NativeWindow.LOCK_SURFACE_CHANGED == lockRes) { + drawable.updateHandle(); + } + if (0 == drawable.getHandle()) { + throw new GLException("drawable has invalid handle: "+drawable); + } + boolean newCreated = false; + if (!isCreated()) { + newCreated = createImpl(); // may throws exception if fails! + if (DEBUG) { + if(newCreated) { + System.err.println(getThreadName() + ": !!! Create GL context OK: " + toHexString(contextHandle) + " for " + getClass().getName()); + } else { + System.err.println(getThreadName() + ": !!! Create GL context FAILED for " + getClass().getName()); + } + } + if(!newCreated) { + return CONTEXT_NOT_CURRENT; + } + GLContextShareSet.contextCreated(this); + } + makeCurrentImpl(newCreated); + return newCreated ? CONTEXT_CURRENT_NEW : CONTEXT_CURRENT ; + } catch (RuntimeException e) { + exceptionOccurred = true; + throw e; + } + } finally { + if (exceptionOccurred) { + drawable.unlockSurface(); + } + } + } + protected abstract void makeCurrentImpl(boolean newCreatedContext) throws GLException; + protected abstract boolean createImpl() throws GLException ; /** * Platform dependent but harmonized implementation of the <code>ARB_create_context</code> @@ -388,8 +449,8 @@ public abstract class GLContextImpl extends GLContext { * @see #createContextARBImpl * @see #destroyContextARBImpl */ - protected long createContextARB(long share, boolean direct, - int major[], int minor[], int ctp[]) + protected final long createContextARB(long share, boolean direct, + int major[], int minor[], int ctp[]) { AbstractGraphicsConfiguration config = drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); @@ -441,7 +502,7 @@ public abstract class GLContextImpl extends GLContext { return _ctx; } - private void createContextARBMapVersionsAvailable(int reqMajor, boolean compat) + private final void createContextARBMapVersionsAvailable(int reqMajor, boolean compat) { long _context; int reqProfile = compat ? CTX_PROFILE_COMPAT : CTX_PROFILE_CORE ; @@ -509,10 +570,10 @@ public abstract class GLContextImpl extends GLContext { } } - private long createContextARBVersions(long share, boolean direct, int ctxOptionFlags, - int majorMax, int minorMax, - int majorMin, int minorMin, - int major[], int minor[]) { + private final long createContextARBVersions(long share, boolean direct, int ctxOptionFlags, + int majorMax, int minorMax, + int majorMin, int minorMin, + int major[], int minor[]) { major[0]=majorMax; minor[0]=minorMax; long _context=0; @@ -540,7 +601,7 @@ public abstract class GLContextImpl extends GLContext { * If major==0 && minor == 0 : Use GL_VERSION * Otherwise .. don't touch .. */ - protected void setContextVersion(int major, int minor, int ctp) { + protected final void setContextVersion(int major, int minor, int ctp) { if (0==ctp) { throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp)); } @@ -619,7 +680,7 @@ public abstract class GLContextImpl extends GLContext { public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3); - public void setSwapInterval(final int interval) { + public final void setSwapInterval(final int interval) { GLContext current = getCurrent(); if (current != this) { throw new GLException("This context is not current. Current context: "+current+ @@ -627,17 +688,12 @@ public abstract class GLContextImpl extends GLContext { } setSwapIntervalImpl(interval); } - + protected void setSwapIntervalImpl(final int interval) { /** nop per default .. **/ } protected int currentSwapInterval = -1; // default: not set yet .. - public int getSwapInterval() { return currentSwapInterval; } - protected void setSwapIntervalImpl(final int interval) { - // nop per default .. - } - /** Maps the given "platform-independent" function name to a real function name. Currently this is only used to map "glAllocateMemoryNV" and associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */ @@ -838,10 +894,6 @@ public abstract class GLContextImpl extends GLContext { // current on the OpenGL worker thread // - public boolean isOptimizable() { - return optimizationEnabled; - } - public boolean hasWaiters() { return lock.hasWaiters(); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java index 6cbed48cd..b13cb44ee 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java @@ -56,7 +56,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { protected static final boolean DEBUG = Debug.debug("GLDrawableFactory"); /** - * Returns the DynamicLookupHelper + * Returns the GLDynamicLookupHelper * @param profile if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2, * otherwise the profile is ignored. */ @@ -226,18 +226,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { return (GLDrawableFactoryImpl) getFactory(glp); } - //---------------------------------------------------------------------- - // Support for locking and unlocking the toolkit -- needed only on X11 platforms - // - - public void lockToolkit() { - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - } - - public void unlockToolkit() { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } - //--------------------------------------------------------------------------- // Support for Java2D/JOGL bridge on Mac OS X; the external // GLDrawable mechanism in the public API is sufficient to diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java index fca0a7d93..8cc12ca89 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java @@ -157,7 +157,7 @@ public class GLDrawableHelper { System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running runnable"); } runnable.run(); - if (autoSwapBufferMode) { + if (autoSwapBufferMode && null != initAction) { if (drawable != null) { drawable.swapBuffers(); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java index b846b379d..1270a4545 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java @@ -69,11 +69,23 @@ public abstract class GLDrawableImpl implements GLDrawable { throw new GLException("Should not call this (should only be called for offscreen GLDrawables)"); } - public void swapBuffers() throws GLException { + public final void swapBuffers() throws GLException { GLCapabilities caps = (GLCapabilities)component.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); if ( caps.getDoubleBuffered() ) { if(!component.surfaceSwap()) { - swapBuffersImpl(); + int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release] + if (NativeWindow.LOCK_SURFACE_NOT_READY == lockRes) { + return; + } + try { + AbstractGraphicsDevice aDevice = getNativeWindow().getGraphicsConfiguration().getScreen().getDevice(); + if (NativeWindow.LOCK_SURFACE_CHANGED == lockRes) { + updateHandle(); + } + swapBuffersImpl(); + } finally { + unlockSurface(); + } } } else { GLContext ctx = GLContext.getCurrent(); @@ -83,7 +95,6 @@ public abstract class GLDrawableImpl implements GLDrawable { } component.surfaceUpdated(this, component, System.currentTimeMillis()); } - protected abstract void swapBuffersImpl(); public static String toHexString(long hex) { @@ -106,23 +117,45 @@ public abstract class GLDrawableImpl implements GLDrawable { return component; } + protected void destroyHandle() {} + protected void updateHandle() {} + + public long getHandle() { + return component.getSurfaceHandle(); + } + public GLDrawableFactory getFactory() { return factory; } - public void setRealized(boolean realized) { + public final void setRealized(boolean realized) { if ( this.realized != realized ) { if(DEBUG) { System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" -> "+realized); } this.realized = realized; - setRealizedImpl(); + if(realized && NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) { + throw new GLException("X11GLXDrawable.setRealized(true): lockSurface - surface not ready"); + } + try { + AbstractGraphicsDevice aDevice = getNativeWindow().getGraphicsConfiguration().getScreen().getDevice(); + if(!realized) { + destroyHandle(); + } + setRealizedImpl(); + if(realized) { + updateHandle(); + } + } finally { + if(realized) { + unlockSurface(); + } + } } else if(DEBUG) { System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" == "+realized); } } protected abstract void setRealizedImpl(); - public boolean isRealized() { return realized; } @@ -137,9 +170,6 @@ public abstract class GLDrawableImpl implements GLDrawable { } public int lockSurface() throws GLException { - if (!realized) { - return NativeWindow.LOCK_SURFACE_NOT_READY; - } return component.lockSurface(); } @@ -154,6 +184,7 @@ public abstract class GLDrawableImpl implements GLDrawable { public String toString() { return getClass().getName()+"[Realized "+isRealized()+ ",\n\tFactory "+getFactory()+ + ",\n\thandle "+toHexString(getHandle())+ ",\n\tWindow "+getNativeWindow()+"]"; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLibraryBundleInfo.java new file mode 100755 index 000000000..dd196c4a1 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLibraryBundleInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, Sven Gothel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sven Gothel nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jogamp.opengl.impl; + +import com.jogamp.common.os.DynamicLibraryBundleInfo; +import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.common.os.NativeLibrary; +import java.util.*; +import java.security.*; +import javax.media.opengl.GLException; + +public abstract class GLDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { + static List/*<String>*/ glueLibNamesPreload; + static { + glueLibNamesPreload = new ArrayList(); + glueLibNamesPreload.add("nativewindow_x11"); + } + + protected GLDynamicLibraryBundleInfo() { + } + + /** default **/ + public boolean shallLinkGlobal() { return false; } + + /** default **/ + public boolean shallLookupGlobal() { return false; } + + public static List/*<String>*/ getGlueLibNamesPreload() { + return glueLibNamesPreload; + } +} + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java index ce0649997..89dbb4a78 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java @@ -27,158 +27,23 @@ package com.jogamp.opengl.impl; +import com.jogamp.common.os.DynamicLibraryBundle; +import com.jogamp.common.os.DynamicLibraryBundleInfo; import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.os.NativeLibrary; import java.util.*; import java.security.*; import javax.media.opengl.GLException; -/** - * Abstract implementation of the DynamicLookupHelper for GL, - * which decouples it's dependencies to EGLDrawableFactory. - * - * Currently two implementations exist, one for ES1 and one for ES2. - */ -public abstract class GLDynamicLookupHelper implements DynamicLookupHelper { - protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GL"); - protected static final boolean DEBUG_LOOKUP; - - static { - AccessControlContext localACC=AccessController.getContext(); - DEBUG_LOOKUP = com.jogamp.opengl.impl.Debug.isPropertyDefined("jogl.debug.DynamicLookup", true, localACC); - } - - protected List/*<NativeLibrary>*/ glLibraries; - private long glxGetProcAddressHandle; - private String glxGetProcAddressFuncName; - - protected GLDynamicLookupHelper() { - glLibraries = new ArrayList(); - loadGLLibrary(); - glxGetProcAddressFuncName = getGLXGetProcAddressFuncName(); - glxGetProcAddressHandle = getGLXGetProcAddressHandle(); - } - - /** Must return at least one OpenGL library name, eg GL, OpenGL32, .. */ - protected abstract List/*<String>*/ getGLLibNames(); +public class GLDynamicLookupHelper extends DynamicLibraryBundle { - /** May return OpenGL Platform library name(s), eg EGL, GLX, .. */ - protected abstract List/*<String>*/ getGLXLibNames(); - - protected boolean shallGLLibLoadedGlobal() { return false; } - - protected boolean shallGLXLibLoadedGlobal() { return false; } - - /** Shall return the OpenGL Platform function name to lookup function pointer, eg eglGetProcAddress */ - protected abstract String getGLXGetProcAddressFuncName() ; - - protected abstract long dynamicLookupFunctionOnGLX(long glxGetProcAddressHandle, String glFuncName); - - /** Shall load the JNI binding */ - protected abstract void loadGLJNILibrary(); - - /** May load the native GLU library, default: None **/ - public void loadGLULibrary() { } - - protected long getGLXGetProcAddressHandle() { - long aptr = dynamicLookupFunctionOnLibs(glxGetProcAddressFuncName); - if(0==aptr) { - GLException e = new GLException("Couldn't find "+glxGetProcAddressFuncName+" function entry"); - if(DEBUG) { - e.printStackTrace(); - } - throw e; - } - return aptr; + public GLDynamicLookupHelper(GLDynamicLibraryBundleInfo info) { + super(info); } - protected NativeLibrary loadFirstAvailable(List/*<String>*/ libNames, ClassLoader loader, boolean global) { - for (Iterator iter = libNames.iterator(); iter.hasNext(); ) { - NativeLibrary lib = NativeLibrary.open((String) iter.next(), loader, global); - if (lib != null) { - return lib; - } - } - return null; - } + public GLDynamicLibraryBundleInfo getGLBundleInfo() { return (GLDynamicLibraryBundleInfo) getBundleInfo(); } - private boolean loadGLXLibrary(ClassLoader loader, List/*<String>*/ osLibNames) { - if(null!=osLibNames && osLibNames.size()>0) { - NativeLibrary lib = loadFirstAvailable(osLibNames, loader, shallGLXLibLoadedGlobal()); - if ( null != lib ) { - glLibraries.add(lib); - } - return null!=lib; - } - return true; // none is ok - } - - private void loadGLLibrary() { - List/*<String>*/ glLibNames = getGLLibNames(); - List/*<String>*/ osLibNames = getGLXLibNames(); - - ClassLoader loader = getClass().getClassLoader(); - NativeLibrary lib = null; - - // GL libraries .. - lib = loadFirstAvailable(glLibNames, loader, shallGLLibLoadedGlobal()); - if ( null == lib ) { - throw new GLException("Unable to dynamically load OpenGL library: "+getClass().getName()); - } - glLibraries.add(lib); - - // GL Platform libraries .. - if ( !loadGLXLibrary(loader, osLibNames) ) { - throw new GLException("Unable to dynamically load GL Platform library: " + getClass().getName()); - } - - loadGLJNILibrary(); - } - - private long dynamicLookupFunctionOnLibs(String glFuncName) { - String funcName=glFuncName; - long addr = dynamicLookupFunctionOnLibsImpl(funcName); - if(DEBUG_LOOKUP) { - if(0!=addr) { - System.err.println("Lookup-Native: "+glFuncName+" / "+funcName+" 0x"+Long.toHexString(addr)); - } else { - System.err.println("Lookup-Native: "+glFuncName+" / "+funcName+" ** FAILED ** "); - } - } - return addr; - } - - private long dynamicLookupFunctionOnLibsImpl(String glFuncName) { - // Look up this function name in all known libraries - for (Iterator iter = glLibraries.iterator(); iter.hasNext(); ) { - NativeLibrary lib = (NativeLibrary) iter.next(); - long addr = lib.dynamicLookupFunction(glFuncName); - if (addr != 0) { - return addr; - } - } - return 0; - } - - public long dynamicLookupFunction(String glFuncName) { - if(null==glFuncName) { - return 0; - } - - if(glFuncName.equals(glxGetProcAddressFuncName)) { - return glxGetProcAddressHandle; - } - - long addr = dynamicLookupFunctionOnGLX(glxGetProcAddressHandle, glFuncName); - if(DEBUG_LOOKUP) { - if(0!=addr) { - System.err.println("Lookup: <"+glFuncName+"> 0x"+Long.toHexString(addr)); - } - } - if(0==addr) { - addr = dynamicLookupFunctionOnLibs(glFuncName); - } - return addr; - } + /** NOP per default */ + public boolean loadGLULibrary() { return false; } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java b/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java index c3958eedf..1daf3358b 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java @@ -58,52 +58,6 @@ public class GLJNILibLoader extends JNILibLoaderBase { }); } - public static void loadGLDesktop() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - loadLibrary("jogl_desktop", nativeOSPreload, true); - return null; - } - }); - } - - public static void loadGLDesktopES12() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - loadLibrary("jogl_gl2es12", nativeOSPreload, true); - return null; - } - }); - } - - public static void loadES2() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - loadLibrary("jogl_es2", nativeOSPreload, true); - return null; - } - }); - } - - public static void loadES1() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - loadLibrary("jogl_es1", nativeOSPreload, true); - return null; - } - }); - } - - public static void loadCgImpl() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - String[] preload = { "nativewindow", "cg", "cgGL" }; - loadLibrary("jogl_cg", preload, true); - return null; - } - }); - } - private static final String[] nativeOSPreload = { "nativewindow_x11" }; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java index 1da19663a..eb5e09d2f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java @@ -48,6 +48,7 @@ import java.beans.PropertyChangeListener; import javax.media.nativewindow.*; import javax.media.opengl.*; +import com.jogamp.nativewindow.impl.RecursiveToolkitLock; /** Platform-independent class exposing pbuffer functionality to applications. This class is not exposed in the public API as it @@ -99,6 +100,10 @@ public class GLPbufferImpl implements GLPbuffer { return pbufferDrawable.getNativeWindow(); } + public long getHandle() { + return pbufferDrawable.getHandle(); + } + public GLDrawableFactory getFactory() { return pbufferDrawable.getFactory(); } @@ -194,19 +199,23 @@ public class GLPbufferImpl implements GLPbuffer { return pbufferDrawable.getGLProfile(); } - private boolean surfaceLocked = false; + private RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); public int lockSurface() throws GLException { - surfaceLocked=true; + recurLock.lock(); return NativeWindow.LOCK_SUCCESS; } public void unlockSurface() { - surfaceLocked=false; + recurLock.unlock(); } public boolean isSurfaceLocked() { - return surfaceLocked; + return recurLock.isLocked(); + } + + public Exception getLockedStack() { + return recurLock.getLockedStack(); } //---------------------------------------------------------------------- diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java index 744e7b924..9d896b7f8 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java @@ -39,8 +39,10 @@ package com.jogamp.opengl.impl; -import java.util.*; +import java.util.List; +import java.util.ArrayList; import javax.media.opengl.*; +import com.jogamp.common.util.IntIntHashMap; /** * Tracks as closely as possible OpenGL states. @@ -54,24 +56,27 @@ public class GLStateTracker { private volatile boolean enabled = true; - private Map/*<Integer,Integer>*/ pixelStateMap = new HashMap/*<Integer,Integer>*/(); + private IntIntHashMap pixelStateMap; static class SavedState { SavedState() { this.pixelStateMap = null; } - void putPixelStateMap(Map pixelStateMap) { - this.pixelStateMap = new HashMap(); + void putPixelStateMap(IntIntHashMap pixelStateMap) { + this.pixelStateMap = new IntIntHashMap(); + this.pixelStateMap.setKeyNotFoundValue(-1); this.pixelStateMap.putAll(pixelStateMap); } - Map getPixelStateMap() { return pixelStateMap; } + IntIntHashMap getPixelStateMap() { return pixelStateMap; } - private Map pixelStateMap; + private IntIntHashMap pixelStateMap; // private Map otherStateMap; } private List/*<SavedState>*/ stack = new ArrayList(); public GLStateTracker() { + pixelStateMap = new IntIntHashMap(); + pixelStateMap.setKeyNotFoundValue(-1); resetStates(); } @@ -88,34 +93,26 @@ public class GLStateTracker { return enabled; } + /** @return true if found in our map, otherwise false, + * which forces the caller to query GL. */ public boolean getInt(int pname, int[] params, int params_offset) { if(enabled) { - Integer key = boxKey(pname); - if(null!=key) { - Integer value = (Integer) pixelStateMap.get(key); - if(null!=value) { - params[params_offset] = value.intValue(); - } else { - GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped"); - throw re; - } + int value = pixelStateMap.get(pname); + if(0 <= value) { + params[params_offset] = value; return true; } } return false; } + /** @return true if found in our map, otherwise false, + * which forces the caller to query GL. */ public boolean getInt(int pname, java.nio.IntBuffer params, int dummy) { if(enabled) { - Integer key = boxKey(pname); - if(null!=key) { - Integer value = (Integer) pixelStateMap.get(key); - if(null!=value) { - params.put(params.position(), value.intValue()); - } else { - GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped"); - throw re; - } + int value = pixelStateMap.get(pname); + if(0 <= value) { + params.put(params.position(), value); return true; } } @@ -124,10 +121,7 @@ public class GLStateTracker { public void setInt(int pname, int param) { if(enabled) { - Integer key = boxKey(pname); - if(null!=key) { - pixelStateMap.put(key, boxInt(param)); - } + pixelStateMap.put(pname, param); } } @@ -151,7 +145,8 @@ public class GLStateTracker { throw new GLException("null stack element (remaining stack size "+stack.size()+")"); } - Map/*<Integer,Integer>*/ pixelStateMapNew = new HashMap/*<Integer,Integer>*/(); + IntIntHashMap pixelStateMapNew = new IntIntHashMap(); + pixelStateMapNew.setKeyNotFoundValue(-1); if ( null != state.getPixelStateMap() ) { pixelStateMapNew.putAll(state.getPixelStateMap()); } @@ -159,80 +154,26 @@ public class GLStateTracker { } } - private static final Integer GL_PACK_SWAP_BYTES = new Integer(GL2GL3.GL_PACK_SWAP_BYTES); - private static final Integer GL_PACK_LSB_FIRST = new Integer(GL2GL3.GL_PACK_LSB_FIRST); - private static final Integer GL_PACK_ROW_LENGTH = new Integer(GL2GL3.GL_PACK_ROW_LENGTH); - private static final Integer GL_PACK_SKIP_ROWS = new Integer(GL2GL3.GL_PACK_SKIP_ROWS); - private static final Integer GL_PACK_SKIP_PIXELS = new Integer(GL2GL3.GL_PACK_SKIP_PIXELS); - private static final Integer GL_PACK_ALIGNMENT = new Integer(GL.GL_PACK_ALIGNMENT); - private static final Integer GL_PACK_IMAGE_HEIGHT = new Integer(GL2GL3.GL_PACK_IMAGE_HEIGHT); - private static final Integer GL_PACK_SKIP_IMAGES = new Integer(GL2GL3.GL_PACK_SKIP_IMAGES); - - private static final Integer GL_UNPACK_SWAP_BYTES = new Integer(GL2GL3.GL_UNPACK_SWAP_BYTES); - private static final Integer GL_UNPACK_LSB_FIRST = new Integer(GL2GL3.GL_UNPACK_LSB_FIRST); - private static final Integer GL_UNPACK_ROW_LENGTH = new Integer(GL2GL3.GL_UNPACK_ROW_LENGTH); - private static final Integer GL_UNPACK_SKIP_ROWS = new Integer(GL2GL3.GL_UNPACK_SKIP_ROWS); - private static final Integer GL_UNPACK_SKIP_PIXELS = new Integer(GL2GL3.GL_UNPACK_SKIP_PIXELS); - private static final Integer GL_UNPACK_ALIGNMENT = new Integer(GL.GL_UNPACK_ALIGNMENT); - private static final Integer GL_UNPACK_IMAGE_HEIGHT = new Integer(GL2GL3.GL_UNPACK_IMAGE_HEIGHT); - private static final Integer GL_UNPACK_SKIP_IMAGES = new Integer(GL2GL3.GL_UNPACK_SKIP_IMAGES); - - private static final Integer zero = new Integer(0); - private static final Integer one = new Integer(1); - - private static Integer boxKey(int key) { - switch (key) { - case 0: return zero; - case GL2GL3.GL_PACK_SWAP_BYTES: return GL_PACK_SWAP_BYTES; - case GL2GL3.GL_PACK_LSB_FIRST: return GL_PACK_LSB_FIRST; - case GL2GL3.GL_PACK_ROW_LENGTH: return GL_PACK_ROW_LENGTH; - case GL2GL3.GL_PACK_SKIP_ROWS: return GL_PACK_SKIP_ROWS; - case GL2GL3.GL_PACK_SKIP_PIXELS: return GL_PACK_SKIP_PIXELS; - case GL.GL_PACK_ALIGNMENT: return GL_PACK_ALIGNMENT; - case GL2GL3.GL_PACK_IMAGE_HEIGHT: return GL_PACK_IMAGE_HEIGHT; - case GL2GL3.GL_PACK_SKIP_IMAGES: return GL_PACK_SKIP_IMAGES; - - case GL2GL3.GL_UNPACK_SWAP_BYTES: return GL_UNPACK_SWAP_BYTES; - case GL2GL3.GL_UNPACK_LSB_FIRST: return GL_UNPACK_LSB_FIRST; - case GL2GL3.GL_UNPACK_ROW_LENGTH: return GL_UNPACK_ROW_LENGTH; - case GL2GL3.GL_UNPACK_SKIP_ROWS: return GL_UNPACK_SKIP_ROWS; - case GL2GL3.GL_UNPACK_SKIP_PIXELS: return GL_UNPACK_SKIP_PIXELS; - case GL.GL_UNPACK_ALIGNMENT: return GL_UNPACK_ALIGNMENT; - case GL2GL3.GL_UNPACK_IMAGE_HEIGHT: return GL_UNPACK_IMAGE_HEIGHT; - case GL2GL3.GL_UNPACK_SKIP_IMAGES: return GL_UNPACK_SKIP_IMAGES; - - default: return null; - } - } - public void resetStates() { pixelStateMap.clear(); - pixelStateMap.put(GL_PACK_SWAP_BYTES, zero /* GL_FALSE */); - pixelStateMap.put(GL_PACK_LSB_FIRST, zero /* GL_FALSE */); - pixelStateMap.put(GL_PACK_ROW_LENGTH, zero); - pixelStateMap.put(GL_PACK_SKIP_ROWS, zero); - pixelStateMap.put(GL_PACK_SKIP_PIXELS, zero); - pixelStateMap.put(GL_PACK_ALIGNMENT, new Integer(4)); - pixelStateMap.put(GL_PACK_IMAGE_HEIGHT, zero); - pixelStateMap.put(GL_PACK_SKIP_IMAGES, zero); - - pixelStateMap.put(GL_UNPACK_SWAP_BYTES, zero /* GL_FALSE */); - pixelStateMap.put(GL_UNPACK_LSB_FIRST, zero /* GL_FALSE */); - pixelStateMap.put(GL_UNPACK_ROW_LENGTH, zero); - pixelStateMap.put(GL_UNPACK_SKIP_ROWS, zero); - pixelStateMap.put(GL_UNPACK_SKIP_PIXELS, zero); - pixelStateMap.put(GL_UNPACK_ALIGNMENT, new Integer(4)); - pixelStateMap.put(GL_UNPACK_IMAGE_HEIGHT, zero); - pixelStateMap.put(GL_UNPACK_SKIP_IMAGES, zero); - } - - private static Integer boxInt(int value) { - switch (value) { - case 0: return zero; - case 1: return one; - - default: return new Integer(value); - } + pixelStateMap.put(GL.GL_PACK_ALIGNMENT, 4); + pixelStateMap.put(GL2GL3.GL_PACK_SWAP_BYTES, 0 /* GL_FALSE */); + pixelStateMap.put(GL2GL3.GL_PACK_LSB_FIRST, 0 /* GL_FALSE */); + pixelStateMap.put(GL2GL3.GL_PACK_ROW_LENGTH, 0); + pixelStateMap.put(GL2GL3.GL_PACK_SKIP_ROWS, 0); + pixelStateMap.put(GL2GL3.GL_PACK_SKIP_PIXELS, 0); + pixelStateMap.put(GL2GL3.GL_PACK_IMAGE_HEIGHT, 0); + pixelStateMap.put(GL2GL3.GL_PACK_SKIP_IMAGES, 0); + + pixelStateMap.put(GL.GL_UNPACK_ALIGNMENT, 4); + pixelStateMap.put(GL2GL3.GL_UNPACK_SWAP_BYTES, 0 /* GL_FALSE */); + pixelStateMap.put(GL2GL3.GL_UNPACK_LSB_FIRST, 0 /* GL_FALSE */); + pixelStateMap.put(GL2GL3.GL_UNPACK_ROW_LENGTH, 0); + pixelStateMap.put(GL2GL3.GL_UNPACK_SKIP_ROWS, 0); + pixelStateMap.put(GL2GL3.GL_UNPACK_SKIP_PIXELS, 0); + pixelStateMap.put(GL2GL3.GL_UNPACK_IMAGE_HEIGHT, 0); + pixelStateMap.put(GL2GL3.GL_UNPACK_SKIP_IMAGES, 0); } } + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp deleted file mode 100644 index 4a0eaa22b..000000000 --- a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package com.jogamp.opengl.impl; - -import java.lang.reflect.*; -import java.nio.*; - -/** Internal copy of selected routines from BufferUtil to avoid - outward dependencies on com.jogamp.opengl.util package. */ -public class InternalBufferUtil { - public static final int SIZEOF_BYTE = 1; - public static final int SIZEOF_SHORT = 2; - public static final int SIZEOF_INT = 4; - public static final int SIZEOF_FLOAT = 4; - - //---------------------------------------------------------------------- - // Allocation routines - // - - /** Allocates a new direct ByteBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static ByteBuffer newByteBuffer(int numElements) { - ByteBuffer bb = ByteBuffer.allocateDirect(numElements); - nativeOrder(bb); - return bb; - } - - /** Allocates a new direct IntBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static IntBuffer newIntBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT); - return bb.asIntBuffer(); - } - - /** Allocates a new direct ShortBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static ShortBuffer newShortBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT); - return bb.asShortBuffer(); - } - - /** Allocates a new direct FloatBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static FloatBuffer newFloatBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT); - return bb.asFloatBuffer(); - } - - //---------------------------------------------------------------------- - // Copy routines (type-to-type) - // - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed FloatBuffer - into a newly-allocated direct ByteBuffer. The returned buffer - will have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT); - dest.asFloatBuffer().put(orig); - dest.rewind(); - return dest; - } - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed IntBuffer into - a newly-allocated direct ByteBuffer. The returned buffer will - have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT); - dest.asIntBuffer().put(orig); - dest.rewind(); - return dest; - } - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed ShortBuffer - into a newly-allocated direct ByteBuffer. The returned buffer - will have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT); - dest.asShortBuffer().put(orig); - dest.rewind(); - return dest; - } - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed ByteBuffer into - a newly-allocated direct ByteBuffer. The returned buffer will - have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyByteBuffer(ByteBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining()); - dest.put(orig); - dest.rewind(); - return dest; - } - - //---------------------------------------------------------------------- - // Conversion routines - // - - public static float[] getFloatArray(double[] source) { - int i=source.length; - float[] dest = new float[i--]; - while(i>=0) { dest[i]=(float)source[i]; i--; } - return dest; - } - - public static ByteBuffer nativeOrder(ByteBuffer buf) { - if (!isCDCFP) { - try { - if (byteOrderClass == null) { - byteOrderClass = Class.forName("java.nio.ByteOrder"); - orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass }); - Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null); - nativeOrderObject = nativeOrderMethod.invoke(null, null); - } - } catch (Throwable t) { - // Must be running on CDC / FP - isCDCFP = true; - } - - if (!isCDCFP) { - try { - orderMethod.invoke(buf, new Object[] { nativeOrderObject }); - } catch (Throwable t) { - } - } - } - return buf; - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - // NOTE that this work must be done reflectively at the present time - // because this code must compile and run correctly on both CDC/FP and J2SE - private static boolean isCDCFP; - private static Class byteOrderClass; - private static Object nativeOrderObject; - private static Method orderMethod; -} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase deleted file mode 100644 index 655fa95de..000000000 --- a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package com.jogamp.opengl.impl; - -import java.lang.reflect.*; -import java.nio.*; - -/** Internal copy of selected routines from BufferUtil to avoid - outward dependencies on com.jogamp.opengl.util package. */ -public class InternalBufferUtil { - public static final int SIZEOF_BYTE = 1; - public static final int SIZEOF_SHORT = 2; - public static final int SIZEOF_INT = 4; - public static final int SIZEOF_FLOAT = 4; - public static final int SIZEOF_LONG = 8; - public static final int SIZEOF_DOUBLE = 8; - - //---------------------------------------------------------------------- - // Allocation routines - // - - /** Allocates a new direct ByteBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static ByteBuffer newByteBuffer(int numElements) { - ByteBuffer bb = ByteBuffer.allocateDirect(numElements); - nativeOrder(bb); - return bb; - } - - /** Allocates a new direct DoubleBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static DoubleBuffer newDoubleBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_DOUBLE); - return bb.asDoubleBuffer(); - } - - /** Allocates a new direct IntBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static IntBuffer newIntBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT); - return bb.asIntBuffer(); - } - - /** Allocates a new direct ShortBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static ShortBuffer newShortBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT); - return bb.asShortBuffer(); - } - - /** Allocates a new direct FloatBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static FloatBuffer newFloatBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT); - return bb.asFloatBuffer(); - } - - //---------------------------------------------------------------------- - // Copy routines (type-to-ByteBuffer) - // - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed FloatBuffer - into a newly-allocated direct ByteBuffer. The returned buffer - will have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT); - dest.asFloatBuffer().put(orig); - dest.rewind(); - return dest; - } - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed IntBuffer into - a newly-allocated direct ByteBuffer. The returned buffer will - have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT); - dest.asIntBuffer().put(orig); - dest.rewind(); - return dest; - } - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed ShortBuffer - into a newly-allocated direct ByteBuffer. The returned buffer - will have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT); - dest.asShortBuffer().put(orig); - dest.rewind(); - return dest; - } - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed ByteBuffer into - a newly-allocated direct ByteBuffer. The returned buffer will - have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyByteBuffer(ByteBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining()); - dest.put(orig); - dest.rewind(); - return dest; - } - - //---------------------------------------------------------------------- - // Conversion routines - // - - public static float[] getFloatArray(double[] source) { - int i=source.length; - float[] dest = new float[i--]; - while(i>=0) { dest[i]=(float)source[i]; i--; } - return dest; - } - - public static ByteBuffer nativeOrder(ByteBuffer buf) { - if (!isCDCFP) { - try { - if (byteOrderClass == null) { - byteOrderClass = Class.forName("java.nio.ByteOrder"); - orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass }); - Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null); - nativeOrderObject = nativeOrderMethod.invoke(null, null); - } - } catch (Throwable t) { - // Must be running on CDC / FP - isCDCFP = true; - } - - if (!isCDCFP) { - try { - orderMethod.invoke(buf, new Object[] { nativeOrderObject }); - } catch (Throwable t) { - } - } - } - return buf; - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - // NOTE that this work must be done reflectively at the present time - // because this code must compile and run correctly on both CDC/FP and J2SE - private static boolean isCDCFP; - private static Class byteOrderClass; - private static Object nativeOrderObject; - private static Method orderMethod; -} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java b/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java index dbd84c9de..ab277e704 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java @@ -118,6 +118,7 @@ import java.nio.*; import javax.media.opengl.*; import javax.media.opengl.fixedfunc.GLMatrixFunc; +import com.jogamp.common.nio.Buffers; /** * ProjectFloat.java @@ -180,7 +181,7 @@ public class ProjectFloat { // Slice up one big buffer because some NIO implementations // allocate a huge amount of memory to back even the smallest of // buffers. - locbuf = InternalBufferUtil.newFloatBuffer(2*16+2*4+3*3); + locbuf = Buffers.newDirectFloatBuffer(2*16+2*4+3*3); int pos = 0; int sz = 16; matrixBuf = slice(locbuf, pos, sz); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java index 56ae649be..5671b033d 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java @@ -84,66 +84,35 @@ public abstract class EGLContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return null; } - protected int makeCurrentImpl() throws GLException { + protected void makeCurrentImpl(boolean newCreated) throws GLException { if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) { throw new GLException("drawable not properly initialized, NO DISPLAY: "+drawable); } - if (0 == drawable.getNativeWindow().getSurfaceHandle()) { - throw new GLException("drawable has invalid surface handle: "+drawable); - } - boolean newCreated = false; - if (!isCreated()) { - create(); // throws exception if fails! - newCreated = true; - if (DEBUG) { - System.err.println(getThreadName() + ": !!! Created GL context " + toHexString(contextHandle) + " for " + getClass().getName()); - } - } if (EGL.eglGetCurrentContext() != contextHandle) { if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), - ((EGLDrawable)drawable).getSurface(), - ((EGLDrawable)drawableRead).getSurface(), + drawable.getHandle(), + drawableRead.getHandle(), contextHandle)) { throw new GLException("Error making context 0x" + Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError()); } } - - if(newCreated) { - setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_ES|CTX_OPTION_ANY); - return CONTEXT_CURRENT_NEW; - } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { - getDrawableImpl().getFactoryImpl().lockToolkit(); - try { - if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), - EGL.EGL_NO_SURFACE, - EGL.EGL_NO_SURFACE, - EGL.EGL_NO_CONTEXT)) { - throw new GLException("Error freeing OpenGL context 0x" + - Long.toHexString(contextHandle) + ": error code " + EGL.eglGetError()); - } - } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); + if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), + EGL.EGL_NO_SURFACE, + EGL.EGL_NO_SURFACE, + EGL.EGL_NO_CONTEXT)) { + throw new GLException("Error freeing OpenGL context 0x" + + Long.toHexString(contextHandle) + ": error code " + EGL.eglGetError()); } } protected void destroyImpl() throws GLException { - getDrawableImpl().getFactoryImpl().lockToolkit(); - try { - if (contextHandle != 0) { - if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), contextHandle)) { - throw new GLException("Error destroying OpenGL context 0x" + - Long.toHexString(contextHandle) + ": error code " + EGL.eglGetError()); - } - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); - } - } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); + if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), contextHandle)) { + throw new GLException("Error destroying OpenGL context 0x" + + Long.toHexString(contextHandle) + ": error code " + EGL.eglGetError()); } } @@ -155,7 +124,7 @@ public abstract class EGLContext extends GLContextImpl { // FIXME } - protected void create() throws GLException { + protected boolean createImpl() throws GLException { long eglDisplay = ((EGLDrawable)drawable).getDisplay(); EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration(); GLProfile glProfile = drawable.getGLProfile(); @@ -208,19 +177,20 @@ public abstract class EGLContext extends GLContextImpl { if (DEBUG) { System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" + Long.toHexString(contextHandle) + - ",\n\twrite surface 0x" + Long.toHexString(((EGLDrawable)drawable).getSurface()) + - ",\n\tread surface 0x" + Long.toHexString(((EGLDrawable)drawableRead).getSurface())+ + ",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) + + ",\n\tread surface 0x" + Long.toHexString(drawableRead.getHandle())+ ",\n\t"+this+ ",\n\tsharing with 0x" + Long.toHexString(shareWith)); } if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), - ((EGLDrawable)drawable).getSurface(), - ((EGLDrawable)drawableRead).getSurface(), + drawable.getHandle(), + drawableRead.getHandle(), contextHandle)) { throw new GLException("Error making context 0x" + Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError()); } setGLFunctionAvailability(true, glProfile.usesNativeGLES2()?2:1, 0, CTX_PROFILE_ES|CTX_OPTION_ANY); + return true; } protected void updateGLProcAddressTable(int major, int minor, int ctp) { @@ -246,18 +216,12 @@ public abstract class EGLContext extends GLContextImpl { eglQueryStringInitialized = true; } if (eglQueryStringAvailable) { - GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl(); - factory.lockToolkit(); - try { String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(), EGL.EGL_EXTENSIONS); if (DEBUG) { System.err.println("!!! EGL extensions: " + ret); } return ret; - } finally { - factory.unlockToolkit(); - } } else { return ""; } @@ -277,7 +241,7 @@ public abstract class EGLContext extends GLContextImpl { // Currently unimplemented stuff // - public void copy(GLContext source, int mask) throws GLException { + protected void copyImpl(GLContext source, int mask) throws GLException { throw new GLException("Not yet implemented"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java index a36973de1..7eeb19141 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java @@ -60,7 +60,7 @@ public abstract class EGLDrawable extends GLDrawableImpl { return eglDisplay; } - public long getSurface() { + public long getHandle() { return eglSurface; } @@ -98,85 +98,83 @@ public abstract class EGLDrawable extends GLDrawableImpl { protected void setRealizedImpl() { if (realized) { - if ( NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface() ) { - throw new GLException("Couldn't lock surface"); - } - // lockSurface() also resolved the window/surface handles - try { - AbstractGraphicsConfiguration aConfig = component.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice(); - if(aDevice instanceof EGLGraphicsDevice) { - // just fetch the data .. trust but verify .. - eglDisplay = aDevice.getHandle(); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Invalid EGL display in EGLGraphicsDevice from "+aDevice); + AbstractGraphicsConfiguration aConfig = component.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice(); + if(aDevice instanceof EGLGraphicsDevice) { + if(DEBUG) { + System.err.println("EGLDrawable.setRealized: using existing EGL config: "+this); + } + // just fetch the data .. trust but verify .. + eglDisplay = aDevice.getHandle(); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display in EGLGraphicsDevice from "+aDevice); + } + if(aConfig instanceof EGLGraphicsConfiguration) { + eglConfig = (EGLGraphicsConfiguration) aConfig; // done .. + if (null == eglConfig) { + throw new GLException("Null EGLGraphicsConfiguration from "+aConfig); } - if(aConfig instanceof EGLGraphicsConfiguration) { - eglConfig = (EGLGraphicsConfiguration) aConfig; // done .. - if (null == eglConfig) { - throw new GLException("Null EGLGraphicsConfiguration from "+aConfig); - } - int[] tmp = new int[1]; - if ( 0 != component.getSurfaceHandle() && - EGL.eglQuerySurface(eglDisplay, component.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) { - // component holds static EGLSurface - eglSurface = component.getSurfaceHandle(); - if(DEBUG) { - System.err.println("setSurface re-using component's EGLSurface: handle 0x"+Long.toHexString(eglSurface)); - } - } else { - // EGLSurface is ours .. - ownEGLSurface=true; - - eglConfig.updateGraphicsConfiguration(); - - recreateSurface(); + int[] tmp = new int[1]; + if ( 0 != component.getSurfaceHandle() && + EGL.eglQuerySurface(eglDisplay, component.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) { + // component holds static EGLSurface + eglSurface = component.getSurfaceHandle(); + if(DEBUG) { + System.err.println("setSurface re-using component's EGLSurface: handle 0x"+Long.toHexString(eglSurface)); } } else { - throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig); + // EGLSurface is ours .. + ownEGLSurface=true; + + eglConfig.updateGraphicsConfiguration(); + + recreateSurface(); } } else { - // create a new EGL config .. - ownEGLDisplay=true; - // EGLSurface is ours .. - ownEGLSurface=true; - - long nDisplay=0; - if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) { - nDisplay = component.getSurfaceHandle(); // don't even ask .. - } else { - nDisplay = aDevice.getHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY + throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig); + } + } else { + if(DEBUG) { + System.err.println("EGLDrawable.setRealized: creating new EGL config: "+this); + } + // create a new EGL config .. + ownEGLDisplay=true; + // EGLSurface is ours .. + ownEGLSurface=true; + + long nDisplay=0; + if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) { + nDisplay = component.getSurfaceHandle(); // don't even ask .. + } else { + nDisplay = aDevice.getHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY + } + eglDisplay = EGL.eglGetDisplay(nDisplay); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + if(DEBUG) { + System.err.println("eglDisplay("+Long.toHexString(nDisplay)+" <surfaceHandle>): failed, using EGL_DEFAULT_DISPLAY"); } + nDisplay = EGL.EGL_DEFAULT_DISPLAY; eglDisplay = EGL.eglGetDisplay(nDisplay); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - if(DEBUG) { - System.err.println("eglDisplay("+Long.toHexString(nDisplay)+" <surfaceHandle>): failed, using EGL_DEFAULT_DISPLAY"); - } - nDisplay = EGL.EGL_DEFAULT_DISPLAY; - eglDisplay = EGL.eglGetDisplay(nDisplay); - } - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Failed to created EGL display: nhandle 0x"+Long.toHexString(nDisplay)+", "+aDevice+", error 0x"+Integer.toHexString(EGL.eglGetError())); - } else if(DEBUG) { - System.err.println("eglDisplay("+Long.toHexString(nDisplay)+"): 0x"+Long.toHexString(eglDisplay)); - } - if (!EGL.eglInitialize(eglDisplay, null, null)) { - throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); - } - EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay); - DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, aConfig.getScreen().getIndex()); - GLCapabilities caps = (GLCapabilities) aConfig.getChosenCapabilities(); // yes, use the already choosen Capabilities (x11,win32,..) - eglConfig = (EGLGraphicsConfiguration) GraphicsConfigurationFactory.getFactory(e).chooseGraphicsConfiguration(caps, null, s); - if (null == eglConfig) { - throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s); - } else if(DEBUG) { - System.err.println("Chosen eglConfig: "+eglConfig); - } - recreateSurface(); } - } finally { - unlockSurface(); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Failed to created EGL display: nhandle 0x"+Long.toHexString(nDisplay)+", "+aDevice+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } else if(DEBUG) { + System.err.println("eglDisplay("+Long.toHexString(nDisplay)+"): 0x"+Long.toHexString(eglDisplay)); + } + if (!EGL.eglInitialize(eglDisplay, null, null)) { + throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay); + DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, aConfig.getScreen().getIndex()); + GLCapabilities caps = (GLCapabilities) aConfig.getChosenCapabilities(); // yes, use the already choosen Capabilities (x11,win32,..) + eglConfig = (EGLGraphicsConfiguration) GraphicsConfigurationFactory.getFactory(e).chooseGraphicsConfiguration(caps, null, s); + if (null == eglConfig) { + throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s); + } else if(DEBUG) { + System.err.println("Chosen eglConfig: "+eglConfig); + } + recreateSurface(); } } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) { // Destroy the window surface @@ -209,7 +207,13 @@ public abstract class EGLDrawable extends GLDrawableImpl { } public GLDynamicLookupHelper getGLDynamicLookupHelper() { - return EGLDynamicLookupHelper.getEGLDynamicLookupHelper(getGLProfile()); + if (getGLProfile().usesNativeGLES2()) { + return getFactoryImpl().getGLDynamicLookupHelper(2); + } else if (getGLProfile().usesNativeGLES1()) { + return getFactoryImpl().getGLDynamicLookupHelper(1); + } else { + throw new GLException("Unsupported: "+getGLProfile()); + } } public String toString() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java index f74c7858f..935281c6c 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java @@ -44,6 +44,9 @@ import com.jogamp.nativewindow.impl.NullWindow; public class EGLDrawableFactory extends GLDrawableFactoryImpl { + private static final GLDynamicLookupHelper eglES1DynamicLookupHelper; + private static final GLDynamicLookupHelper eglES2DynamicLookupHelper; + static { // Register our GraphicsConfigurationFactory implementations // The act of constructing them causes them to be registered @@ -55,6 +58,36 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory"); } catch (JogampRuntimeException jre) { /* n/a .. */ } } + + // FIXME: Probably need to move EGL from a static model + // to a dynamic one, where there can be 2 instances + // for each ES profile with their own ProcAddressTable. + + GLDynamicLookupHelper tmp=null; + try { + tmp = new GLDynamicLookupHelper(new EGLES1DynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + eglES1DynamicLookupHelper = tmp; + if(null!=eglES1DynamicLookupHelper && eglES1DynamicLookupHelper.isLibComplete()) { + EGL.resetProcAddressTable(eglES1DynamicLookupHelper); + } + + tmp=null; + try { + tmp = new GLDynamicLookupHelper(new EGLES2DynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + eglES2DynamicLookupHelper = tmp; + if(null!=eglES2DynamicLookupHelper && eglES2DynamicLookupHelper.isLibComplete()) { + EGL.resetProcAddressTable(eglES2DynamicLookupHelper); + } } public EGLDrawableFactory() { @@ -62,7 +95,19 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) { - return EGLDynamicLookupHelper.getEGLDynamicLookupHelper(esProfile); + if (2==esProfile) { + if(null==eglES2DynamicLookupHelper) { + throw new GLException("GLDynamicLookupHelper for ES2 not available"); + } + return eglES2DynamicLookupHelper; + } else if (1==esProfile) { + if(null==eglES1DynamicLookupHelper) { + throw new GLException("GLDynamicLookupHelper for ES1 not available"); + } + return eglES1DynamicLookupHelper; + } else { + throw new GLException("Unsupported: ES"+esProfile); + } } protected void shutdown() {} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLibraryBundleInfo.java index 28cfb4f1e..675be64b5 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLibraryBundleInfo.java @@ -41,84 +41,32 @@ import java.security.*; * * Currently two implementations exist, one for ES1 and one for ES2. */ -public abstract class EGLDynamicLookupHelper extends GLDynamicLookupHelper { - private static final EGLDynamicLookupHelper eglES1DynamicLookupHelper; - private static final EGLDynamicLookupHelper eglES2DynamicLookupHelper; +public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo { - static { - EGLDynamicLookupHelper tmp=null; - try { - tmp = new EGLES1DynamicLookupHelper(); - } catch (GLException gle) { - if(DEBUG) { - gle.printStackTrace(); - } - } - eglES1DynamicLookupHelper = tmp; - - tmp=null; - try { - tmp = new EGLES2DynamicLookupHelper(); - } catch (GLException gle) { - if(DEBUG) { - gle.printStackTrace(); - } - } - eglES2DynamicLookupHelper = tmp; + protected EGLDynamicLibraryBundleInfo() { + super(); } - public static EGLDynamicLookupHelper getEGLDynamicLookupHelper(GLProfile glp) { - if (glp.usesNativeGLES2()) { - return getEGLDynamicLookupHelper(2); - } else if (glp.usesNativeGLES1()) { - return getEGLDynamicLookupHelper(1); - } else { - throw new GLException("Unsupported: "+glp); - } - } + /** Might be a desktop GL library, and might need to allow symbol access to subsequent libs */ + public boolean shallLinkGlobal() { return true; } - public static EGLDynamicLookupHelper getEGLDynamicLookupHelper(int esProfile) { - if (2==esProfile) { - if(null==eglES2DynamicLookupHelper) { - throw new GLException("EGLDynamicLookupHelper for ES2 not available"); - } - return eglES2DynamicLookupHelper; - } else if (1==esProfile) { - if(null==eglES1DynamicLookupHelper) { - throw new GLException("EGLDynamicLookupHelper for ES1 not available"); - } - return eglES1DynamicLookupHelper; - } else { - throw new GLException("Unsupported: ES"+esProfile); - } + public final List getToolGetProcAddressFuncNameList() { + List res = new ArrayList(); + res.add("eglGetProcAddress"); + return res; } - protected EGLDynamicLookupHelper() { - super(); - EGL.resetProcAddressTable(this); + public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) { + return EGL.eglGetProcAddress(toolGetProcAddressHandle, funcName); } - protected boolean hasESBinding = false; - public boolean hasESBinding() { return hasESBinding; } - - protected final List/*<String>*/ getGLXLibNames() { + protected List/*<String>*/ getEGLLibNamesList() { List/*<String>*/ eglLibNames = new ArrayList(); - // EGL eglLibNames.add("EGL"); // for windows distributions using the 'unlike' lib prefix, // where our tool does not add it. eglLibNames.add("libEGL"); - return eglLibNames; } - - protected final String getGLXGetProcAddressFuncName() { - return "eglGetProcAddress" ; - } - - protected final long dynamicLookupFunctionOnGLX(long glxGetProcAddressHandle, String glFuncName) { - return EGL.eglGetProcAddress(glxGetProcAddressHandle, glFuncName); - } } - diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLibraryBundleInfo.java index 9599e1457..aad25edc4 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLibraryBundleInfo.java @@ -30,38 +30,22 @@ package com.jogamp.opengl.impl.egl; import java.util.*; import com.jogamp.opengl.impl.*; -/** - * Implementation of the EGLDynamicLookupHelper for ES1. - */ -public class EGLES1DynamicLookupHelper extends EGLDynamicLookupHelper { - - protected EGLES1DynamicLookupHelper() { - super(); +public class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo { + static List/*<String>*/ glueLibNames; + static { + glueLibNames = new ArrayList(); + glueLibNames.addAll(GLDynamicLibraryBundleInfo.getGlueLibNamesPreload()); + glueLibNames.add("jogl_es1"); } - protected void loadGLJNILibrary() { - Throwable t=null; - try { - GLJNILibLoader.loadES1(); - hasESBinding = true; - } catch (UnsatisfiedLinkError ule) { - t=ule; - } catch (SecurityException se) { - t=se; - } catch (NullPointerException npe) { - t=npe; - } catch (RuntimeException re) { - t=re; - } - if(DEBUG && null!=t) { - System.err.println("EGLES1DynamicLookupHelper: ES1 Binding Library not available"); - t.printStackTrace(); - } + protected EGLES1DynamicLibraryBundleInfo() { + super(); } - protected List/*<String>*/ getGLLibNames() { - List/*<String>*/ glesLibNames = new ArrayList(); + public List getToolLibNames() { + List/*<List>*/ libNames = new ArrayList(); + List/*<String>*/ glesLibNames = new ArrayList(); glesLibNames.add("GLES_CM"); glesLibNames.add("GLES_CL"); glesLibNames.add("GLESv1_CM"); @@ -70,8 +54,19 @@ public class EGLES1DynamicLookupHelper extends EGLDynamicLookupHelper { glesLibNames.add("libGLES_CM"); glesLibNames.add("libGLES_CL"); glesLibNames.add("libGLESv1_CM"); + // last but not least, we may even use the desktop GL library, + // which would be eg Mesa + Gallium EGL .. + glesLibNames.add("libGL.so.1"); + glesLibNames.add("libGL.so"); + glesLibNames.add("GL"); + + libNames.add(glesLibNames); + libNames.add(getEGLLibNamesList()); + return libNames; + } - return glesLibNames; + public List/*<String>*/ getGlueLibNames() { + return glueLibNames; } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLibraryBundleInfo.java index c00fa0e93..9691b2bd0 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLibraryBundleInfo.java @@ -30,38 +30,22 @@ package com.jogamp.opengl.impl.egl; import java.util.*; import com.jogamp.opengl.impl.*; -/** - * Implementation of the EGLDynamicLookupHelper for ES2. - */ -public class EGLES2DynamicLookupHelper extends EGLDynamicLookupHelper { +public class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo { + static List/*<String>*/ glueLibNames; + static { + glueLibNames = new ArrayList(); + glueLibNames.addAll(GLDynamicLibraryBundleInfo.getGlueLibNamesPreload()); + glueLibNames.add("jogl_es2"); + } - protected EGLES2DynamicLookupHelper() { + protected EGLES2DynamicLibraryBundleInfo() { super(); } - protected void loadGLJNILibrary() { - Throwable t=null; - try { - GLJNILibLoader.loadES2(); - hasESBinding = true; - } catch (UnsatisfiedLinkError ule) { - t=ule; - } catch (SecurityException se) { - t=se; - } catch (NullPointerException npe) { - t=npe; - } catch (RuntimeException re) { - t=re; - } - if(DEBUG && null!=t) { - System.err.println("EGLES2DynamicLookupHelper: ES2 Binding Library not available"); - t.printStackTrace(); - } - } + public List getToolLibNames() { + List/*<List>*/ libNames = new ArrayList(); - protected List/*<String>*/ getGLLibNames() { List/*<String>*/ glesLibNames = new ArrayList(); - glesLibNames.add("GLES20"); glesLibNames.add("GLESv2"); glesLibNames.add("GLESv2_CM"); @@ -70,8 +54,19 @@ public class EGLES2DynamicLookupHelper extends EGLDynamicLookupHelper { glesLibNames.add("libGLES20"); glesLibNames.add("libGLESv2"); glesLibNames.add("libGLESv2_CM"); + // last but not least, we may even use the desktop GL library, + // which would be eg Mesa + Gallium EGL .. + glesLibNames.add("libGL.so.1"); + glesLibNames.add("libGL.so"); + glesLibNames.add("GL"); + + libNames.add(glesLibNames); + libNames.add(getEGLLibNamesList()); + return libNames; + } - return glesLibNames; + public List/*<String>*/ getGlueLibNames() { + return glueLibNames; } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java index f5f027f94..ae8b5bf70 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java @@ -67,21 +67,16 @@ public class EGLExternalContext extends EGLContext { lastContext = null; } - protected int makeCurrentImpl() throws GLException { + protected void makeCurrentImpl(boolean newCreated) throws GLException { if (firstMakeCurrent) { firstMakeCurrent = false; - // FIXME: set contextHandle - return CONTEXT_CURRENT_NEW; } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { } protected void destroyImpl() throws GLException { - contextHandle = 0 ; - GLContextShareSet.contextDestroyed(this); } public void bindPbufferToTexture() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java index b74991671..cb8b01d8d 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java @@ -47,37 +47,6 @@ public class EGLOnscreenContext extends EGLContext { super(drawable, shareWith); } - // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] - protected int makeCurrentImpl() throws GLException { - int lockRes = drawable.lockSurface(); - boolean exceptionOccurred = false; - try { - if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) { - return CONTEXT_NOT_CURRENT; - } - return super.makeCurrentImpl(); - } catch (RuntimeException e) { - exceptionOccurred = true; - throw e; - } finally { - if (exceptionOccurred || - (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) { - drawable.unlockSurface(); - } - } - } - - // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] - protected void releaseImpl() throws GLException { - try { - super.releaseImpl(); - } finally { - if (!isOptimizable() && drawable.isSurfaceLocked()) { - drawable.unlockSurface(); - } - } - } - public void bindPbufferToTexture() { throw new GLException("Should not call this"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java index 3864fc39c..551a21ed6 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java @@ -59,21 +59,7 @@ public class EGLOnscreenDrawable extends EGLDrawable { } protected void swapBuffersImpl() { - boolean didLock = false; - if (!isSurfaceLocked()) { - // Usually the surface shall be locked within [makeCurrent .. swap .. release] - if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { - return; - } - didLock = true; - } - try { - EGL.eglSwapBuffers(eglDisplay, eglSurface); - } finally { - if (didLock) { - unlockSurface(); - } - } + EGL.eglSwapBuffers(eglDisplay, eglSurface); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java b/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java index 2eb3ca5df..98cc3f323 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java @@ -118,6 +118,7 @@ import java.nio.*; import javax.media.opengl.*; import com.jogamp.opengl.impl.*; +import com.jogamp.common.nio.Buffers; /** * Project.java @@ -173,7 +174,7 @@ public class ProjectDouble { // Slice up one big buffer because some NIO implementations // allocate a huge amount of memory to back even the smallest of // buffers. - DoubleBuffer locbuf = InternalBufferUtil.newDoubleBuffer(128); + DoubleBuffer locbuf = Buffers.newDirectDoubleBuffer(128); int pos = 0; int sz = 16; matrixBuf = slice(locbuf, pos, sz); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java index 501f5f585..42f55f982 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/BuildMipmap.java @@ -48,7 +48,7 @@ import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.glu.GLU; import com.jogamp.opengl.impl.Debug; -import com.jogamp.opengl.impl.InternalBufferUtil; +import com.jogamp.common.nio.Buffers; import java.nio.*; import java.io.*; @@ -89,8 +89,8 @@ public class BuildMipmap { Mipmap.retrieveStoreModes( gl, psm ); try { - newImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.image_size( width, 1, format, - GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer(); + newImage = Buffers.newDirectByteBuffer( Mipmap.image_size( width, 1, format, + GL2.GL_UNSIGNED_SHORT ) ).asShortBuffer(); } catch( OutOfMemoryError ome ) { return( GLU.GLU_OUT_OF_MEMORY ); } @@ -117,7 +117,7 @@ public class BuildMipmap { if( otherImage == null ) { memReq = Mipmap.image_size( newwidth, 1, format, GL2.GL_UNSIGNED_SHORT ); try { - otherImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )).asShortBuffer(); + otherImage = Buffers.newDirectByteBuffer( memReq ).asShortBuffer(); } catch( OutOfMemoryError ome ) { gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() ); gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() ); @@ -178,8 +178,8 @@ public class BuildMipmap { } try { - newImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.image_size( width, height, - format, GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer(); + newImage = Buffers.newDirectByteBuffer( Mipmap.image_size( width, height, + format, GL2.GL_UNSIGNED_SHORT ) ).asShortBuffer(); } catch( OutOfMemoryError ome ) { return( GLU.GLU_OUT_OF_MEMORY ); } @@ -206,7 +206,7 @@ public class BuildMipmap { if( otherImage == null ) { memReq = Mipmap.image_size( newwidth[0], newheight[0], format, GL2.GL_UNSIGNED_SHORT ); try { - otherImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )).asShortBuffer(); + otherImage = Buffers.newDirectByteBuffer( memReq ).asShortBuffer(); } catch( OutOfMemoryError ome ) { gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() ); gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() ); @@ -364,7 +364,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); @@ -481,7 +481,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); @@ -519,7 +519,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); @@ -653,7 +653,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); @@ -880,8 +880,7 @@ public class BuildMipmap { int i, j; try { - newImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.image_size( - width, height, format, GL2.GL_UNSIGNED_BYTE ) )); + newImage = Buffers.newDirectByteBuffer( Mipmap.image_size(width, height, format, GL2.GL_UNSIGNED_BYTE ) ); } catch( OutOfMemoryError err ) { return( GLU.GLU_OUT_OF_MEMORY ); } @@ -924,7 +923,7 @@ public class BuildMipmap { if( otherImage == null ) { memReq = Mipmap.image_size( newwidth[0], newheight[0], format, GL2.GL_UNSIGNED_BYTE ); try { - otherImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + otherImage = Buffers.newDirectByteBuffer( memReq ); } catch( OutOfMemoryError err ) { gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() ); gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() ); @@ -1102,7 +1101,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); @@ -1288,7 +1287,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); @@ -1329,7 +1328,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); @@ -1391,7 +1390,7 @@ public class BuildMipmap { case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ): case( GL2.GL_UNSIGNED_INT_10_10_10_2 ): case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ): - dstImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( memReq )); + dstImage = Buffers.newDirectByteBuffer( memReq ); break; default: return( GLU.GLU_INVALID_ENUM ); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java index 1c0707c57..4e3f6c298 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/Mipmap.java @@ -50,7 +50,7 @@ import javax.media.opengl.GL2GL3; import javax.media.opengl.glu.GLU; import javax.media.opengl.GLException; import java.nio.*; -import com.jogamp.opengl.impl.InternalBufferUtil; +import com.jogamp.common.nio.Buffers; /** * @@ -575,8 +575,8 @@ public class Mipmap { if( !isLegalFormatForPackedPixelType( format, typeout ) ) { return( GLU.GLU_INVALID_OPERATION ); } - beforeimage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( image_size( widthin, heightin, format, GL2GL3.GL_UNSIGNED_SHORT ) )); - afterimage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( image_size( widthout, heightout, format, GL2GL3.GL_UNSIGNED_SHORT ) )); + beforeimage = Buffers.newDirectByteBuffer( image_size( widthin, heightin, format, GL2GL3.GL_UNSIGNED_SHORT ) ); + afterimage = Buffers.newDirectByteBuffer( image_size( widthout, heightout, format, GL2GL3.GL_UNSIGNED_SHORT ) ); if( beforeimage == null || afterimage == null ) { return( GLU.GLU_OUT_OF_MEMORY ); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java index f0bb7fb33..804845fe2 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/glu/mipmap/ScaleInternal.java @@ -48,7 +48,7 @@ import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.glu.GLU; import java.nio.*; -import com.jogamp.opengl.impl.InternalBufferUtil; +import com.jogamp.common.nio.Buffers; /** * @@ -2425,10 +2425,10 @@ public class ScaleInternal { } try { - beforeImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.imageSize3D( widthIn, - heightIn, depthIn, format, GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer(); - afterImage = InternalBufferUtil.nativeOrder(ByteBuffer.allocateDirect( Mipmap.imageSize3D( widthIn, - heightIn, depthIn, format, GL2.GL_UNSIGNED_SHORT ) )).asShortBuffer(); + beforeImage = Buffers.newDirectByteBuffer( Mipmap.imageSize3D( widthIn, + heightIn, depthIn, format, GL2.GL_UNSIGNED_SHORT ) ).asShortBuffer(); + afterImage = Buffers.newDirectByteBuffer( Mipmap.imageSize3D( widthIn, + heightIn, depthIn, format, GL2.GL_UNSIGNED_SHORT ) ).asShortBuffer(); } catch( OutOfMemoryError err ) { return( GLU.GLU_OUT_OF_MEMORY ); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java index 371df1ee5..46b86a557 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java @@ -134,7 +134,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl int[] viewNotReady = new int[1]; // Try to allocate a context with this contextHandle = CGL.createContext(share, - drawable.getNativeWindow().getSurfaceHandle(), + drawable.getHandle(), pixelFormat, viewNotReady, 0); if (contextHandle == 0) { @@ -166,26 +166,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl GLContextShareSet.contextCreated(this); return true; } - - protected int makeCurrentImpl() throws GLException { - if (0 == drawable.getNativeWindow().getSurfaceHandle()) { - throw new GLException("drawable has invalid surface handle: "+drawable); - } - boolean newCreated = false; - if (!isCreated()) { - create(); - newCreated = isCreated(); - if(!newCreated) { - if (DEBUG) { - System.err.println("!!! GL Context creation failed for " + getClass().getName()); - } - return CONTEXT_NOT_CURRENT; - } - if (DEBUG) { - System.err.println("!!! Created OpenGL context " + toHexString(contextHandle) + " for " + getClass().getName()); - } - } - + + protected void makeCurrentImpl(boolean newCreated) throws GLException { if ( isNSContext ) { if (!CGL.makeCurrentContext(contextHandle)) { throw new GLException("Error making Context (NS) current"); @@ -195,12 +177,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl throw new GLException("Error making Context (CGL) current"); } } - - if (newCreated) { - setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - return CONTEXT_CURRENT_NEW; - } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { @@ -214,9 +190,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl } protected void destroyImpl() throws GLException { - if( ! isCreated() ) { - return; - } if ( !isNSContext ) { if (CGL.kCGLNoError != CGL.CGLDestroyContext(contextHandle)) { throw new GLException("Unable to delete OpenGL Context (CGL)"); @@ -224,8 +197,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl if (DEBUG) { System.err.println("!!! Destroyed OpenGL Context (CGL) " + contextHandle); } - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); } else { if (!CGL.deleteContext(contextHandle)) { throw new GLException("Unable to delete OpenGL Context (NS)"); @@ -233,20 +204,12 @@ public abstract class MacOSXCGLContext extends GLContextImpl if (DEBUG) { System.err.println("!!! Destroyed OpenGL Context (NS) " + contextHandle); } - contextHandle = 0; } - GLContextShareSet.contextDestroyed(this); } - public void copy(GLContext source, int mask) throws GLException { + protected void copyImpl(GLContext source, int mask) throws GLException { long dst = getHandle(); - if (0 == dst) { - throw new GLException("Destination OpenGL Context has not been created"); - } long src = source.getHandle(); - if (0 == src) { - throw new GLException("Source OpenGL Context has not been created"); - } if( !isNSContext() ) { if ( ((MacOSXCGLContext)source).isNSContext() ) { throw new GLException("Source OpenGL Context is NS ; Destination Context is CGL."); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java index 3f41d95cb..23fdcbf6d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java @@ -42,7 +42,6 @@ package com.jogamp.opengl.impl.macosx.cgl; import javax.media.nativewindow.*; import javax.media.opengl.*; import com.jogamp.opengl.impl.*; -import com.jogamp.common.os.DynamicLookupHelper; public abstract class MacOSXCGLDrawable extends GLDrawableImpl { // The Java2D/OpenGL pipeline on OS X uses low-level CGLContextObjs @@ -83,17 +82,10 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { } protected void setRealizedImpl() { - if(realized) { - if( NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface() ) { - throw new GLException("Couldn't lock surface"); - } - // locking the surface is essential to update surface data - unlockSurface(); - } } public GLDynamicLookupHelper getGLDynamicLookupHelper() { - return MacOSXCGLDynamicLookupHelper.getMacOSXCGLDynamicLookupHelper(); + return getFactoryImpl().getGLDynamicLookupHelper(0); } protected static String getThreadName() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index e507e4886..7f050412d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -48,9 +48,26 @@ import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.NullWindow; public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { + private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper; + + static { + DesktopGLDynamicLookupHelper tmp = null; + try { + tmp = new DesktopGLDynamicLookupHelper(new MacOSXCGLDynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + macOSXCGLDynamicLookupHelper = tmp; + /** FIXME ?? + if(null!=macOSXCGLDynamicLookupHelper) { + CGL.getCGLProcAddressTable().reset(macOSXCGLDynamicLookupHelper); + } */ + } public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { - return MacOSXCGLDynamicLookupHelper.getMacOSXCGLDynamicLookupHelper(); + return macOSXCGLDynamicLookupHelper; } public MacOSXCGLDrawableFactory() { @@ -60,8 +77,6 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { // The act of constructing them causes them to be registered new MacOSXCGLGraphicsConfigurationFactory(); - MacOSXCGLDynamicLookupHelper.getMacOSXCGLDynamicLookupHelper(); // setup and initialize - try { ReflectionUtil.createInstance("com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory", new Object[] {}); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java index 3ed75b245..154cf61b5 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java @@ -35,59 +35,37 @@ import java.util.*; import java.security.*; import javax.media.opengl.GLException; -public class MacOSXCGLDynamicLookupHelper extends DesktopGLDynamicLookupHelper { - private static final MacOSXCGLDynamicLookupHelper macOSXCGLDynamicLookupHelper; - - static { - MacOSXCGLDynamicLookupHelper tmp = null; - try { - tmp = new MacOSXCGLDynamicLookupHelper(); - } catch (GLException gle) { - if(DEBUG) { - gle.printStackTrace(); - } - } - macOSXCGLDynamicLookupHelper = tmp; - } - - public static MacOSXCGLDynamicLookupHelper getMacOSXCGLDynamicLookupHelper() { - return macOSXCGLDynamicLookupHelper; - } - - protected MacOSXCGLDynamicLookupHelper() { +public class MacOSXCGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { + protected MacOSXCGLDynamicLibraryBundleInfo() { super(); } - public synchronized void loadGLULibrary() { - if(null==gluLib) { - List/*<String>*/ gluLibNames = new ArrayList(); - gluLibNames.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"); - gluLibNames.add("GLU"); - gluLib = loadFirstAvailable(gluLibNames, null, false); - if(null != gluLib) { - glLibraries.add(gluLib); - } - } - } - NativeLibrary gluLib = null; + public List getToolLibNames() { + List/*<List>*/ libNamesList = new ArrayList(); - protected final List/*<String>*/ getGLLibNames() { List/*<String>*/ glesLibNames = new ArrayList(); + glesLibNames.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"); glesLibNames.add("GL"); - return glesLibNames; - } - protected final List/*<String>*/ getGLXLibNames() { - return null; + libNamesList.add(glesLibNames); + + return libNamesList; } - protected final String getGLXGetProcAddressFuncName() { - return "getProcAddress" ; // dummy + public final List getToolGetProcAddressFuncNameList() { + return null; + /** OSX manual says: NSImage use is discouraged + List res = new ArrayList(); + res.add("GetProcAddress"); // dummy + return res; */ } - protected long dynamicLookupFunctionOnGLX(long glxGetProcAddressHandle, String glFuncName) { - return CGL.getProcAddress(glFuncName); // manual implementation + public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) { + return 0; + /** OSX manual says: NSImage use is discouraged + return CGL.getProcAddress(glFuncName); // manual implementation + */ } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java index 9865fdfca..e8518925a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java @@ -60,56 +60,52 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { } protected static MacOSXExternalCGLContext create(GLDrawableFactory factory, GLProfile glp) { - ((GLDrawableFactoryImpl)factory).lockToolkit(); - try { - long pixelFormat = 0; - long currentDrawable = 0; - long contextHandle = CGL.getCurrentContext(); // Check: MacOSX 10.3 .. - boolean isNSContext = 0 != contextHandle; - if( isNSContext ) { - currentDrawable = CGL.getNSView(contextHandle); - long ctx = CGL.getCGLContext(contextHandle); - if (ctx == 0) { - throw new GLException("Error: NULL Context (CGL) of Context (NS) 0x" +Long.toHexString(contextHandle)); - } - pixelFormat = CGL.CGLGetPixelFormat(ctx); - if(DEBUG) { - System.err.println("MacOSXExternalCGLContext Create Context (NS) 0x"+Long.toHexString(contextHandle)+ - ", Context (CGL) 0x"+Long.toHexString(ctx)+ - ", pixelFormat 0x"+Long.toHexString(pixelFormat)); - } - } else { - contextHandle = CGL.CGLGetCurrentContext(); - if (contextHandle == 0) { - throw new GLException("Error: current Context (CGL) null, no Context (NS)"); - } - pixelFormat = CGL.CGLGetPixelFormat(contextHandle); - if(DEBUG) { - System.err.println("MacOSXExternalCGLContext Create Context (CGL) 0x"+Long.toHexString(contextHandle)+ - ", pixelFormat 0x"+Long.toHexString(pixelFormat)); - } + long pixelFormat = 0; + long currentDrawable = 0; + long contextHandle = CGL.getCurrentContext(); // Check: MacOSX 10.3 .. + boolean isNSContext = 0 != contextHandle; + if( isNSContext ) { + currentDrawable = CGL.getNSView(contextHandle); + long ctx = CGL.getCGLContext(contextHandle); + if (ctx == 0) { + throw new GLException("Error: NULL Context (CGL) of Context (NS) 0x" +Long.toHexString(contextHandle)); } - - if (0 == pixelFormat) { - throw new GLException("Error: current pixelformat of current Context 0x"+Long.toHexString(contextHandle)+" is null"); + pixelFormat = CGL.CGLGetPixelFormat(ctx); + if(DEBUG) { + System.err.println("MacOSXExternalCGLContext Create Context (NS) 0x"+Long.toHexString(contextHandle)+ + ", Context (CGL) 0x"+Long.toHexString(ctx)+ + ", pixelFormat 0x"+Long.toHexString(pixelFormat)); } - GLCapabilities caps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(glp, pixelFormat); + } else { + contextHandle = CGL.CGLGetCurrentContext(); + if (contextHandle == 0) { + throw new GLException("Error: current Context (CGL) null, no Context (NS)"); + } + pixelFormat = CGL.CGLGetPixelFormat(contextHandle); if(DEBUG) { - System.err.println("MacOSXExternalCGLContext Create "+caps); + System.err.println("MacOSXExternalCGLContext Create Context (CGL) 0x"+Long.toHexString(contextHandle)+ + ", pixelFormat 0x"+Long.toHexString(pixelFormat)); } + } - AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); - MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat); - - NullWindow nw = new NullWindow(cfg); - nw.setSurfaceHandle(currentDrawable); - return new MacOSXExternalCGLContext(new Drawable(factory, nw), isNSContext, contextHandle); - } finally { - ((GLDrawableFactoryImpl)factory).unlockToolkit(); + if (0 == pixelFormat) { + throw new GLException("Error: current pixelformat of current Context 0x"+Long.toHexString(contextHandle)+" is null"); + } + GLCapabilities caps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(glp, pixelFormat); + if(DEBUG) { + System.err.println("MacOSXExternalCGLContext Create "+caps); } + + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat); + + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(currentDrawable); + return new MacOSXExternalCGLContext(new Drawable(factory, nw), isNSContext, contextHandle); } - protected void create() { + protected boolean createImpl() throws GLException { + return true; } public int makeCurrent() throws GLException { @@ -129,20 +125,16 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { lastContext = null; } - protected int makeCurrentImpl() throws GLException { + protected void makeCurrentImpl(boolean newCreated) throws GLException { if (firstMakeCurrent) { firstMakeCurrent = false; - return CONTEXT_CURRENT_NEW; } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { } protected void destroyImpl() throws GLException { - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); } public void setOpenGLMode(int mode) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java index ede0c28eb..568204384 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java @@ -54,52 +54,13 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { this.drawable = drawable; } - protected int makeCurrentImpl() throws GLException { - int lockRes = drawable.lockSurface(); - boolean exceptionOccurred = false; - try { - if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) { - return CONTEXT_NOT_CURRENT; - } - int ret = super.makeCurrentImpl(); - if ((ret == CONTEXT_CURRENT) || - (ret == CONTEXT_CURRENT_NEW)) { - // Assume the canvas might have been resized or moved and tell the OpenGL - // context to update itself. This used to be done only upon receiving a - // reshape event but that doesn't appear to be sufficient. An experiment - // was also done to add a HierarchyBoundsListener to the GLCanvas and - // do this updating only upon reshape of this component or reshape or movement - // of an ancestor, but this also wasn't sufficient and left garbage on the - // screen in some situations. - CGL.updateContext(contextHandle); - } else { - if (!isOptimizable()) { - // This can happen if the window currently is zero-sized, for example. - // Make sure we don't leave the surface locked in this case. - drawable.unlockSurface(); - lockRes = NativeWindow.LOCK_SURFACE_NOT_READY; - } - } - return ret; - } catch (RuntimeException e) { - exceptionOccurred = true; - throw e; - } finally { - if (exceptionOccurred || - (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY)) { - drawable.unlockSurface(); - } - } + protected void makeCurrentImpl(boolean newCreated) throws GLException { + super.makeCurrentImpl(newCreated); + CGL.updateContext(contextHandle); } protected void releaseImpl() throws GLException { - try { - super.releaseImpl(); - } finally { - if (!isOptimizable() && drawable.isSurfaceLocked()) { - drawable.unlockSurface(); - } - } + super.releaseImpl(); } protected void swapBuffers() { @@ -115,8 +76,8 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { CGL.updateContext(contextHandle); } - protected void create() { - create(false, false); + protected boolean createImpl() { + return create(false, false); } public void setOpenGLMode(int mode) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java index 391908540..9c630d24b 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java @@ -38,45 +38,22 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { // FIXME: not clear whether this is really necessary, but since // the API docs seem to imply it is and since it doesn't seem to // impact performance, leaving it in - CGL.setContextTextureImageToPBuffer(contextHandle, drawable.getPbuffer(), GL.GL_FRONT); + CGL.setContextTextureImageToPBuffer(contextHandle, drawable.getHandle(), GL.GL_FRONT); } public void releasePbufferFromTexture() { } - protected int makeCurrentImpl() throws GLException { - if (drawable.getPbuffer() == 0) { - if (DEBUG) { - System.err.println("Pbuffer not instantiated yet for " + this); - } - // pbuffer not instantiated yet - return CONTEXT_NOT_CURRENT; - } - + protected void makeCurrentImpl(boolean newCreated) throws GLException { if (getOpenGLMode() != drawable.getOpenGLMode()) { setOpenGLMode(drawable.getOpenGLMode()); } - if (contextHandle == 0) { - create(); - if(!isCreated()) { - return CONTEXT_NOT_CURRENT; - } - if(!isNSContext()) { - throw new GLException("Not a NS Context"); - } - if (DEBUG) { - System.err.println("!!! Created OpenGL context (NS) " + toHexString(contextHandle) + " for " + getClass().getName()); - } - } - if (!impl.makeCurrent(contextHandle)) { throw new GLException("Error making Context (NS) current"); } - if (isCreated()) { - setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - + if (newCreated) { // Initialize render-to-texture support if requested DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities(); @@ -99,10 +76,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0); - - return CONTEXT_CURRENT_NEW; } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { @@ -112,22 +86,15 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { } protected void destroyImpl() throws GLException { - if (contextHandle != 0) { if (!impl.destroy(contextHandle)) { throw new GLException("Unable to delete OpenGL context"); } if (DEBUG) { System.err.println("!!! Destroyed OpenGL context " + contextHandle); } - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); - } } protected void setSwapIntervalImpl(int interval) { - if (contextHandle == 0) { - throw new GLException("OpenGL context not current"); - } impl.setSwapInterval(contextHandle, interval); currentSwapInterval = impl.getSwapInterval() ; } @@ -136,7 +103,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { return GLPbuffer.APPLE_FLOAT; } - protected void create() { + protected boolean createImpl() throws GLException { DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities(); if (capabilities.getPbufferFloatingPointBuffers() && @@ -155,7 +122,11 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { if (!impl.makeCurrent(contextHandle)) { throw new GLException("Error making Context (NS:"+isNSContext()+") current"); } + if(!isNSContext()) { // FIXME: ?? + throw new GLException("Not a NS Context"); + } setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); + return true; } //--------------------------------------------------------------------------- @@ -231,7 +202,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { throw new GLException("Error creating context for pbuffer"); } // Must now associate the pbuffer with our newly-created context - CGL.setContextPBuffer(contextHandle, drawable.getPbuffer()); + CGL.setContextPBuffer(contextHandle, drawable.getHandle()); return contextHandle; } @@ -335,7 +306,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { throw new GLException("Error code " + res + " while creating context"); } // Attach newly-created context to the pbuffer - res = CGL.CGLSetPBuffer(ctx.get(0), drawable.getPbuffer(), 0, 0, 0); + res = CGL.CGLSetPBuffer(ctx.get(0), drawable.getHandle(), 0, 0, 0); if (res != CGL.kCGLNoError) { throw new GLException("Error code " + res + " while attaching context to pbuffer"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java index afdc40dbb..64d646cfb 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java @@ -96,7 +96,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { } } - public long getPbuffer() { + public long getHandle() { return pBuffer; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java index 9a90cbdc4..b42f1132c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java @@ -70,29 +70,13 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL this.graphics = g; } - protected int makeCurrentImpl() throws GLException { - if (contextHandle == 0) { - create(); - if(!isCreated()) { - return CONTEXT_NOT_CURRENT; - } - if (DEBUG) { - System.err.println("!!! Created GL Context (NS) for " + getClass().getName()); - } - } - + protected void makeCurrentImpl(boolean newCreated) throws GLException { if (!Java2D.makeOGLContextCurrentOnSurface(graphics, contextHandle)) { throw new GLException("Error making context current"); - } - - if (isCreated()) { - setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - return CONTEXT_CURRENT_NEW; - } - return CONTEXT_CURRENT; + } } - protected void create() { + protected boolean createImpl() { // Find and configure share context MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this); long share = 0; @@ -118,11 +102,13 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL long ctx = Java2D.createOGLContextOnSurface(graphics, share); if (ctx == 0) { - return; + return false; } + setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION // FIXME: think about GLContext sharing contextHandle = ctx; isNSContext = true; + return true; } protected void releaseImpl() throws GLException { @@ -132,15 +118,10 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL } protected void destroyImpl() throws GLException { - if (contextHandle != 0) { Java2D.destroyOGLContext(contextHandle); if (DEBUG) { System.err.println("!!! Destroyed OpenGL context " + contextHandle); } - contextHandle = 0; - // FIXME - // GLContextShareSet.contextDestroyed(this); - } } public void setOpenGLMode(int mode) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java index 87a37da04..5e3d55b04 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java @@ -51,9 +51,9 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { // All entries to CreateDummyWindow must synchronize on one object // to avoid accidentally registering the dummy window class twice synchronized (WindowsDummyWGLDrawable.class) { - hwnd = WGL.CreateDummyWindow(0, 0, 1, 1); + hwnd = GDI.CreateDummyWindow(0, 0, 1, 1); } - hdc = WGL.GetDC(hwnd); + hdc = GDI.GetDC(hwnd); NullWindow nw = (NullWindow) getNativeWindow(); nw.setSurfaceHandle(hdc); WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration(); @@ -61,9 +61,9 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities(); caps.setDepthBits(16); PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps); - int pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); + int pixelFormat = GDI.ChoosePixelFormat(hdc, pfd); if ((pixelFormat == 0) || - (!WGL.SetPixelFormat(hdc, pixelFormat, pfd))) { + (!GDI.SetPixelFormat(hdc, pixelFormat, pfd))) { destroy(); } } @@ -90,12 +90,12 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { public void destroy() { if (hdc != 0) { - WGL.ReleaseDC(hwnd, hdc); + GDI.ReleaseDC(hwnd, hdc); hdc = 0; } if (hwnd != 0) { - WGL.ShowWindow(hwnd, WGL.SW_HIDE); - WGL.DestroyWindow(hwnd); + GDI.ShowWindow(hwnd, GDI.SW_HIDE); + GDI.DestroyWindow(hwnd); hwnd = 0; } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java index 55c9dc378..1f1fb0d40 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java @@ -69,7 +69,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { if (ctx == 0) { throw new GLException("Error: attempted to make an external GLContext without a context current"); } - int pfdID = WGL.GetPixelFormat(hdc); + int pfdID = GDI.GetPixelFormat(hdc); if (pfdID == 0) { throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat"); } @@ -100,20 +100,16 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { lastContext = null; } - protected int makeCurrentImpl() throws GLException { + protected void makeCurrentImpl(boolean newCreated) throws GLException { if (firstMakeCurrent) { firstMakeCurrent = false; - return CONTEXT_CURRENT_NEW; } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { } protected void destroyImpl() throws GLException { - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); } // Need to provide the display connection to extension querying APIs diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java index 74db45932..41e469224 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java @@ -55,7 +55,7 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { if (0==hdc) { throw new GLException("Error: attempted to make an external GLDrawable without a drawable current"); } - int pfdID = WGL.GetPixelFormat(hdc); + int pfdID = GDI.GetPixelFormat(hdc); if (pfdID == 0) { throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat"); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java index bf466d455..8079cd42a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java @@ -89,27 +89,27 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { header.setBiYPelsPerMeter(0); header.setBiClrUsed(0); header.setBiClrImportant(0); - header.setBiCompression(WGL.BI_RGB); + header.setBiCompression(GDI.BI_RGB); header.setBiSizeImage(width * height * bitsPerPixel / 8); - long hdc = WGL.CreateCompatibleDC(0); + long hdc = GDI.CreateCompatibleDC(0); if (hdc == 0) { - System.out.println("LastError: " + WGL.GetLastError()); + System.out.println("LastError: " + GDI.GetLastError()); throw new GLException("Error creating device context for offscreen OpenGL context"); } ((SurfaceChangeable)nw).setSurfaceHandle(hdc); - hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, null, 0, 0); + hbitmap = GDI.CreateDIBSection(hdc, info, GDI.DIB_RGB_COLORS, null, 0, 0); if (hbitmap == 0) { - WGL.DeleteDC(hdc); + GDI.DeleteDC(hdc); hdc = 0; throw new GLException("Error creating offscreen bitmap of width " + width + ", height " + height); } - if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) { - WGL.DeleteObject(hbitmap); + if ((origbitmap = GDI.SelectObject(hdc, hbitmap)) == 0) { + GDI.DeleteObject(hbitmap); hbitmap = 0; - WGL.DeleteDC(hdc); + GDI.DeleteDC(hdc); hdc = 0; throw new GLException("Error selecting bitmap into new device context"); } @@ -121,9 +121,9 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { NativeWindow nw = getNativeWindow(); if (nw.getSurfaceHandle() != 0) { // Must destroy bitmap and device context - WGL.SelectObject(nw.getSurfaceHandle(), origbitmap); - WGL.DeleteObject(hbitmap); - WGL.DeleteDC(nw.getSurfaceHandle()); + GDI.SelectObject(nw.getSurfaceHandle(), origbitmap); + GDI.DeleteObject(hbitmap); + GDI.DeleteDC(nw.getSurfaceHandle()); origbitmap = 0; hbitmap = 0; ((SurfaceChangeable)nw).setSurfaceHandle(0); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java index aeb13110e..475faeecc 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java @@ -46,43 +46,8 @@ import javax.media.opengl.*; import com.jogamp.opengl.impl.*; public class WindowsOnscreenWGLContext extends WindowsWGLContext { - protected WindowsOnscreenWGLDrawable drawable; - public WindowsOnscreenWGLContext(WindowsOnscreenWGLDrawable drawable, GLContext shareWith) { super(drawable, shareWith); - this.drawable = drawable; - } - - // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] - protected int makeCurrentImpl() throws GLException { - int lockRes = drawable.lockSurface(); - boolean exceptionOccurred = false; - try { - if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) { - return CONTEXT_NOT_CURRENT; - } - int ret = super.makeCurrentImpl(); - return ret; - } catch (RuntimeException e) { - exceptionOccurred = true; - throw e; - } finally { - if (exceptionOccurred || - (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) { - drawable.unlockSurface(); - } - } - } - - // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] - protected void releaseImpl() throws GLException { - try { - super.releaseImpl(); - } finally { - if (!isOptimizable() && drawable.isSurfaceLocked()) { - drawable.unlockSurface(); - } - } - } + } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java index a9e02e11f..1da5b80c9 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java @@ -68,7 +68,7 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext { WGLExt wglExt = getWGLExt(); gl.glBindTexture(textureTarget, texture); if (rtt && hasRTT) { - if (!wglExt.wglBindTexImageARB(drawable.getPbuffer(), WGLExt.WGL_FRONT_LEFT_ARB)) { + if (!wglExt.wglBindTexImageARB(drawable.getPbufferHandle(), WGLExt.WGL_FRONT_LEFT_ARB)) { throw new GLException("Binding of pbuffer to texture failed: " + wglGetLastError()); } } @@ -84,18 +84,15 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext { } if (rtt && hasRTT) { WGLExt wglExt = getWGLExt(); - if (!wglExt.wglReleaseTexImageARB(drawable.getPbuffer(), WGLExt.WGL_FRONT_LEFT_ARB)) { + if (!wglExt.wglReleaseTexImageARB(drawable.getPbufferHandle(), WGLExt.WGL_FRONT_LEFT_ARB)) { throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError()); } } } - protected int makeCurrentImpl() throws GLException { - int res = super.makeCurrentImpl(); - if (DEBUG && VERBOSE) { - System.err.println("WindowsPbufferWGLContext: super.makeCurrentImpl() = " + res); - } - if (res == CONTEXT_CURRENT_NEW) { + protected void makeCurrentImpl(boolean newCreated) throws GLException { + super.makeCurrentImpl(newCreated); + if (newCreated) { GLCapabilities capabilities = drawable.getChosenGLCapabilities(); // Initialize render-to-texture support if requested @@ -142,7 +139,6 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext { } } } - return res; } public int getFloatingPointMode() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index c7034e93b..c8c62914a 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -89,18 +89,21 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { // not be called here, so we skip the use of any composable // pipelines (see WindowsOnscreenWGLContext.makeCurrentImpl) if (wglExt.wglReleasePbufferDCARB(buffer, nw.getSurfaceHandle()) == 0) { - throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError()); + throw new GLException("Error releasing pbuffer device context: error code " + GDI.GetLastError()); } ((SurfaceChangeable)nw).setSurfaceHandle(0); } if (!wglExt.wglDestroyPbufferARB(buffer)) { - throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError()); + throw new GLException("Error destroying pbuffer: error code " + GDI.GetLastError()); } buffer = 0; } } - public long getPbuffer() { + public long getPbufferHandle() { + // The actual to-be-used handle for makeCurrent etc, + // is the derived DC, set in the NativeWindow surfaceHandle + // returned by getHandle(). return buffer; } @@ -293,7 +296,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, true, false, true); PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { + if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { if (DEBUG) { System.err.println("Unable to describe pixel format (Continue: true) " + whichFormat + "/" + nformats + " pfdID " + pformats[whichFormat]+":\n\t"+newCaps); } @@ -304,7 +307,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true); } else { PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { + if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); } GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, false, true); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index 3ecd3bdbc..33f1bc829 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -51,8 +51,7 @@ public class WindowsWGLContext extends GLContextImpl { private boolean wglGetExtensionsStringEXTInitialized; private boolean wglGetExtensionsStringEXTAvailable; private boolean wglMakeContextCurrentInitialized; - private boolean wglMakeContextCurrentARBAvailable; - private boolean wglMakeContextCurrentEXTAvailable; + private boolean wglMakeContextCurrentAvailable; private static final Map/*<String, String>*/ functionNameMap; private static final Map/*<String, String>*/ extensionNameMap; private WGLExt wglExt; @@ -95,17 +94,14 @@ public class WindowsWGLContext extends GLContextImpl { public boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long ctx) { WGLExt wglExt = getWGLExt(); if (!wglMakeContextCurrentInitialized) { - wglMakeContextCurrentARBAvailable = isFunctionAvailable("wglMakeContextCurrentARB"); - wglMakeContextCurrentEXTAvailable = isFunctionAvailable("wglMakeContextCurrentEXT"); + wglMakeContextCurrentAvailable = isFunctionAvailable("wglMakeContextCurrent"); wglMakeContextCurrentInitialized = true; if(DEBUG) { - System.err.println("WindowsWGLContext.wglMakeContextCurrent: ARB "+wglMakeContextCurrentARBAvailable+", EXT "+wglMakeContextCurrentEXTAvailable); + System.err.println("WindowsWGLContext.wglMakeContextCurrent: "+wglMakeContextCurrentAvailable); } } - if(wglMakeContextCurrentARBAvailable) { - return wglExt.wglMakeContextCurrentARB(hDrawDC, hReadDC, ctx); - } else if(wglMakeContextCurrentEXTAvailable) { - return wglExt.wglMakeContextCurrentEXT(hDrawDC, hReadDC, ctx); + if(wglMakeContextCurrentAvailable) { + return wglExt.wglMakeContextCurrent(hDrawDC, hReadDC, ctx); } return WGL.wglMakeCurrent(hDrawDC, ctx); } @@ -174,7 +170,7 @@ public class WindowsWGLContext extends GLContextImpl { } } - ctx = wglExt.wglCreateContextAttribsARB(drawable.getNativeWindow().getSurfaceHandle(), share, attribs, 0); + ctx = wglExt.wglCreateContextAttribsARB(drawable.getHandle(), share, attribs, 0); if(DEBUG) { System.err.println("WindowsWGLContext.createContextARB success: "+(0!=ctx)+" - "+getGLVersion(major, minor, ctp, "@creation")+", bwdCompat "+ctBwdCompat+", fwdCompat "+ctFwdCompat); } @@ -182,7 +178,7 @@ public class WindowsWGLContext extends GLContextImpl { // In contrast to GLX no verification with a drawable binding, ie default framebuffer, is necessary, // if no 3.2 is available creation fails already! // Nevertheless .. we do it .. - if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), ctx)) { + if (!WGL.wglMakeCurrent(drawable.getHandle(), ctx)) { if(DEBUG) { System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation")); } @@ -198,10 +194,7 @@ public class WindowsWGLContext extends GLContextImpl { * Creates and initializes an appropriate OpenGL context. Should only be * called by {@link #makeCurrentImpl()}. */ - protected void create() { - if(0!=contextHandle) { - throw new GLException("context is not null: "+contextHandle); - } + protected boolean createImpl() { WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); GLCapabilities glCaps = drawable.getChosenGLCapabilities(); @@ -233,18 +226,18 @@ public class WindowsWGLContext extends GLContextImpl { if(0==contextHandle) { // To use WGL_ARB_create_context, we have to make a temp context current, // so we are able to use GetProcAddress - temp_ctx = WGL.wglCreateContext(drawable.getNativeWindow().getSurfaceHandle()); + temp_ctx = WGL.wglCreateContext(drawable.getHandle()); if (temp_ctx == 0) { - throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle())); + throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getHandle())); } - if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), temp_ctx)) { - throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: 0x"+Integer.toHexString(WGL.GetLastError())); + if (!WGL.wglMakeCurrent(drawable.getHandle(), temp_ctx)) { + throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: 0x"+Integer.toHexString(GDI.GetLastError())); } setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); if( createContextARBTried || - !isFunctionAvailable("wglCreateContextAttribsARB") /* || - !isExtensionAvailable("WGL_ARB_create_context") */ ) { // unresolved case where client version is 1.4 without this extension + !isFunctionAvailable("wglCreateContextAttribsARB") || + !isExtensionAvailable("WGL_ARB_create_context") ) { if(glCaps.getGLProfile().isGL3()) { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(temp_ctx); @@ -253,7 +246,8 @@ public class WindowsWGLContext extends GLContextImpl { // continue with temp context for GL < 3.0 contextHandle = temp_ctx; - return; + setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); + return true; } contextHandle = createContextARB(share, true, major, minor, ctp); createContextARBTried=true; @@ -265,8 +259,8 @@ public class WindowsWGLContext extends GLContextImpl { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(temp_ctx); - if (!wglMakeContextCurrent(drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), contextHandle)) { - throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: 0x" + Integer.toHexString(WGL.GetLastError())); + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: 0x" + Integer.toHexString(GDI.GetLastError())); } } else { if(glCaps.getGLProfile().isGL3()) { @@ -280,10 +274,10 @@ public class WindowsWGLContext extends GLContextImpl { // continue with temp context for GL < 3.0 contextHandle = temp_ctx; - if (!wglMakeContextCurrent(drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), contextHandle)) { + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(contextHandle); - throw new GLException("Error making old context current: 0x" + toHexString(contextHandle) + ", werr: 0x" + Integer.toHexString(WGL.GetLastError())); + throw new GLException("Error making old context current: 0x" + toHexString(contextHandle) + ", werr: 0x" + Integer.toHexString(GDI.GetLastError())); } } @@ -291,78 +285,47 @@ public class WindowsWGLContext extends GLContextImpl { if (!WGL.wglShareLists(share, contextHandle)) { throw new GLException("wglShareLists(" + toHexString(share) + ", " + toHexString(contextHandle) + ") failed: werr 0x" + - Integer.toHexString(WGL.GetLastError())); + Integer.toHexString(GDI.GetLastError())); } } - GLContextShareSet.contextCreated(this); + setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); + return true; } - protected int makeCurrentImpl() throws GLException { - if (0 == drawable.getNativeWindow().getSurfaceHandle()) { - throw new GLException("drawable has invalid surface handle: "+drawable); - } - boolean newCreated = false; - if (!isCreated()) { - create(); // throws exception if fails! - newCreated = true; - if (DEBUG) { - System.err.println(getThreadName() + ": !!! Created GL context " + toHexString(contextHandle) + " for " + getClass().getName()); - } - } - + protected void makeCurrentImpl(boolean newCreated) throws GLException { if (WGL.wglGetCurrentContext() != contextHandle) { - if (!wglMakeContextCurrent(drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), contextHandle)) { - throw new GLException("Error making context current: 0x" + toHexString(contextHandle) + ", werr: 0x" + Integer.toHexString(WGL.GetLastError()) + ", " + this); + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Error making context current: 0x" + toHexString(contextHandle) + ", werr: 0x" + Integer.toHexString(GDI.GetLastError()) + ", " + this); } else { if (DEBUG && VERBOSE) { - System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + + System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getHandle()) + ", contextHandle " + toHexString(contextHandle) + ") succeeded"); } } } if (newCreated) { - setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); config.updateCapabilitiesByWGL(this); - - return CONTEXT_CURRENT_NEW; } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { if (!wglMakeContextCurrent(0, 0, 0)) { - throw new GLException("Error freeing OpenGL context, werr: 0x" + Integer.toHexString(WGL.GetLastError())); + throw new GLException("Error freeing OpenGL context, werr: 0x" + Integer.toHexString(GDI.GetLastError())); } } protected void destroyImpl() throws GLException { - if (DEBUG) { - Exception e = new Exception(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(contextHandle)); - e.printStackTrace(); - } - if (contextHandle != 0) { + WGL.wglMakeCurrent(0, 0); if (!WGL.wglDeleteContext(contextHandle)) { throw new GLException("Unable to delete OpenGL context"); } - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); - } } - public void copy(GLContext source, int mask) throws GLException { - long dst = getHandle(); - long src = source.getHandle(); - if (src == 0) { - throw new GLException("Source OpenGL context has not been created"); - } - if (dst == 0) { - throw new GLException("Destination OpenGL context has not been created"); - } - if (!WGL.wglCopyContext(src, dst, mask)) { + protected void copyImpl(GLContext source, int mask) throws GLException { + if (!WGL.wglCopyContext(source.getHandle(), getHandle(), mask)) { throw new GLException("wglCopyContext failed"); } } @@ -374,8 +337,7 @@ public class WindowsWGLContext extends GLContextImpl { wglGetExtensionsStringEXTInitialized=false; wglGetExtensionsStringEXTAvailable=false; wglMakeContextCurrentInitialized=false; - wglMakeContextCurrentARBAvailable=false; - wglMakeContextCurrentEXTAvailable=false; + wglMakeContextCurrentAvailable=false; if (wglExtProcAddressTable == null) { // FIXME: cache ProcAddressTables by OpenGL context type bits so we can diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java index 274390b2c..b1bc9b5ce 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java @@ -64,62 +64,39 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { return; // nothing todo .. } - if(NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) { - throw new GLException("WindowsWGLDrawable.setRealized(true): lockSurface - surface not ready"); - } - try { - NativeWindow nativeWindow = getNativeWindow(); - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - config.updateGraphicsConfiguration(getFactory(), nativeWindow); - if (DEBUG) { - System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config); - } - } finally { - unlockSurface(); + NativeWindow nativeWindow = getNativeWindow(); + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + config.updateGraphicsConfiguration(getFactory(), nativeWindow); + if (DEBUG) { + System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config); } } protected void swapBuffersImpl() { - boolean didLock = false; - - if ( !isSurfaceLocked() ) { - // Usually the surface shall be locked within [makeCurrent .. swap .. release] - if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { - return; - } - didLock = true; + long startTime = 0; + if (PROFILING) { + startTime = System.currentTimeMillis(); } - try { - long startTime = 0; - if (PROFILING) { - startTime = System.currentTimeMillis(); - } - - if (!WGL.SwapBuffers(getNativeWindow().getSurfaceHandle()) && (WGL.GetLastError() != 0)) { - throw new GLException("Error swapping buffers"); - } + if (!GDI.SwapBuffers(getHandle()) && (GDI.GetLastError() != 0)) { + throw new GLException("Error swapping buffers"); + } - if (PROFILING) { - long endTime = System.currentTimeMillis(); - profilingSwapBuffersTime += (endTime - startTime); - int ticks = PROFILING_TICKS; - if (++profilingSwapBuffersTicks == ticks) { - System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" + - ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)"); - profilingSwapBuffersTime = 0; - profilingSwapBuffersTicks = 0; - } - } - } finally { - if (didLock) { - unlockSurface(); - } + if (PROFILING) { + long endTime = System.currentTimeMillis(); + profilingSwapBuffersTime += (endTime - startTime); + int ticks = PROFILING_TICKS; + if (++profilingSwapBuffersTicks == ticks) { + System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" + + ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)"); + profilingSwapBuffersTime = 0; + profilingSwapBuffersTicks = 0; + } } } public GLDynamicLookupHelper getGLDynamicLookupHelper() { - return WindowsWGLDynamicLookupHelper.getWindowsWGLDynamicLookupHelper(); + return getFactoryImpl().getGLDynamicLookupHelper(0); } protected static String getThreadName() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 8072ad2de..3fbe769e5 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -52,8 +52,25 @@ import com.jogamp.nativewindow.impl.NullWindow; public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private static final boolean VERBOSE = Debug.verbose(); + private static final DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper; + + static { + DesktopGLDynamicLookupHelper tmp = null; + try { + tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + windowsWGLDynamicLookupHelper = tmp; + if(null!=windowsWGLDynamicLookupHelper) { + WGL.getWGLProcAddressTable().reset(windowsWGLDynamicLookupHelper); + } + } + public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { - return WindowsWGLDynamicLookupHelper.getWindowsWGLDynamicLookupHelper(); + return windowsWGLDynamicLookupHelper; } public WindowsWGLDrawableFactory() { @@ -62,7 +79,6 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { // Register our GraphicsConfigurationFactory implementations // The act of constructing them causes them to be registered new WindowsWGLGraphicsConfigurationFactory(); - WindowsWGLDynamicLookupHelper.getWindowsWGLDynamicLookupHelper(); // setup and load .. try { ReflectionUtil.createInstance("com.jogamp.opengl.impl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory", new Object[] {}); @@ -190,14 +206,14 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } static String wglGetLastError() { - long err = WGL.GetLastError(); + long err = GDI.GetLastError(); String detail = null; switch ((int) err) { - case WGL.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break; - case WGL.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break; - case WGL.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break; - case WGL.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break; - case WGL.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break; + case GDI.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break; + case GDI.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break; + case GDI.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break; + case GDI.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break; + case GDI.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break; default: detail = "(Unknown error code " + err + ")"; break; } return detail; @@ -231,17 +247,17 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { rampData[i + 2 * GAMMA_RAMP_LENGTH] = scaledValue; } - long screenDC = WGL.GetDC(0); - boolean res = WGL.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData)); - WGL.ReleaseDC(0, screenDC); + long screenDC = GDI.GetDC(0); + boolean res = GDI.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData)); + GDI.ReleaseDC(0, screenDC); return res; } protected Buffer getGammaRamp() { ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]); - long screenDC = WGL.GetDC(0); - boolean res = WGL.GetDeviceGammaRamp(screenDC, rampData); - WGL.ReleaseDC(0, screenDC); + long screenDC = GDI.GetDC(0); + boolean res = GDI.GetDeviceGammaRamp(screenDC, rampData); + GDI.ReleaseDC(0, screenDC); if (!res) { return null; } @@ -253,8 +269,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { // getGammaRamp failed earlier return; } - long screenDC = WGL.GetDC(0); - WGL.SetDeviceGammaRamp(screenDC, originalGammaRamp); - WGL.ReleaseDC(0, screenDC); + long screenDC = GDI.GetDC(0); + GDI.SetDeviceGammaRamp(screenDC, originalGammaRamp); + GDI.ReleaseDC(0, screenDC); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java new file mode 100644 index 000000000..7bff1e3c1 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDynamicLibraryBundleInfo.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010, Sven Gothel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sven Gothel nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jogamp.opengl.impl.windows.wgl; + +import com.jogamp.opengl.impl.*; +import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.common.os.NativeLibrary; +import com.jogamp.common.os.Platform; +import java.util.*; +import java.security.*; +import javax.media.opengl.GLException; + +public class WindowsWGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { + protected WindowsWGLDynamicLibraryBundleInfo() { + super(); + } + + public List getToolLibNames() { + List/*<String>*/ libNamesList = new ArrayList(); + + libNamesList.add("OpenGL32"); + + return libNamesList; + } + + + public final List getToolGetProcAddressFuncNameList() { + List res = new ArrayList(); + res.add("wglGetProcAddress"); + return res; + } + + public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) { + return WGL.wglGetProcAddress(toolGetProcAddressHandle, funcName); + } +} + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java index aed4012a4..eb5719566 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -67,7 +67,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio glp = GLProfile.getDefault(); } PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - if (WGL.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { throw new GLException("Unable to describe pixel format " + pfdID); } @@ -215,10 +215,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio } } } else { - long lastErr = WGL.GetLastError(); + long lastErr = GDI.GetLastError(); // Intel Extreme graphics fails with a zero error code if (lastErr != 0) { - throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError()); + throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + GDI.GetLastError()); } } return availableCaps; @@ -539,7 +539,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio // PIXELFORMAT public static GLCapabilities PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) { - if ((pfd.getDwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) { + if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { return null; } GLCapabilities res = new GLCapabilities(glp); @@ -553,11 +553,11 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio res.setAccumAlphaBits(pfd.getCAccumAlphaBits()); res.setDepthBits (pfd.getCDepthBits()); res.setStencilBits (pfd.getCStencilBits()); - res.setDoubleBuffered((pfd.getDwFlags() & WGL.PFD_DOUBLEBUFFER) != 0); - res.setStereo ((pfd.getDwFlags() & WGL.PFD_STEREO) != 0); - res.setHardwareAccelerated( ((pfd.getDwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) || - ((pfd.getDwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0) ); - res.setOnscreen ( onscreen && ((pfd.getDwFlags() & WGL.PFD_DRAW_TO_WINDOW) != 0) ); + res.setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); + res.setStereo ((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); + res.setHardwareAccelerated( ((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0) || + ((pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0) ); + res.setOnscreen ( onscreen && ((pfd.getDwFlags() & GDI.PFD_DRAW_TO_WINDOW) != 0) ); res.setPBuffer ( usePBuffer ); /* FIXME: Missing ?? if (GLXUtil.isMultisampleAvailable()) { @@ -580,21 +580,21 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); } PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - int pfdFlags = (WGL.PFD_SUPPORT_OPENGL | - WGL.PFD_GENERIC_ACCELERATED); + int pfdFlags = (GDI.PFD_SUPPORT_OPENGL | + GDI.PFD_GENERIC_ACCELERATED); if (caps.getDoubleBuffered()) { - pfdFlags |= WGL.PFD_DOUBLEBUFFER; + pfdFlags |= GDI.PFD_DOUBLEBUFFER; } if (caps.isOnscreen()) { - pfdFlags |= WGL.PFD_DRAW_TO_WINDOW; + pfdFlags |= GDI.PFD_DRAW_TO_WINDOW; } else { - pfdFlags |= WGL.PFD_DRAW_TO_BITMAP; + pfdFlags |= GDI.PFD_DRAW_TO_BITMAP; } if (caps.getStereo()) { - pfdFlags |= WGL.PFD_STEREO; + pfdFlags |= GDI.PFD_STEREO; } pfd.setDwFlags(pfdFlags); - pfd.setIPixelType((byte) WGL.PFD_TYPE_RGBA); + pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA); pfd.setCColorBits((byte) colorDepth); pfd.setCRedBits ((byte) caps.getRedBits()); pfd.setCGreenBits((byte) caps.getGreenBits()); @@ -610,7 +610,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits()); pfd.setCDepthBits((byte) caps.getDepthBits()); pfd.setCStencilBits((byte) caps.getStencilBits()); - pfd.setILayerType((byte) WGL.PFD_MAIN_PLANE); + pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE); /* FIXME: Missing: caps.getSampleBuffers() diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index ab3227257..e76e63f23 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -118,7 +118,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio GLCapabilities chosenCaps = null; if (onscreen) { - if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) { + if ((pixelFormat = GDI.GetPixelFormat(hdc)) != 0) { // Pixelformat already set by either // - a previous updateGraphicsConfiguration() call on the same HDC, // - the graphics driver, copying the HDC's pixelformat to the new one, @@ -171,13 +171,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio } } else { if (DEBUG) { - System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() ); + System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + GDI.GetLastError() ); Thread.dumpStack(); } } if (DEBUG) { if (recommendedPixelFormat <= 0) { - System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format: "+WGL.GetLastError()); + System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format: "+GDI.GetLastError()); if (capabilities.getSampleBuffers()) { System.err.print(" for multisampled GLCapabilities"); } @@ -200,23 +200,23 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio if (!gotAvailableCaps) { if (DEBUG) { - System.err.println(getThreadName() + ": Using ChoosePixelFormat ... (LastError: "+WGL.GetLastError()+")"); + System.err.println(getThreadName() + ": Using ChoosePixelFormat ... (LastError: "+GDI.GetLastError()+")"); } pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities); - recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd); + recommendedPixelFormat = GDI.ChoosePixelFormat(hdc, pfd); if (DEBUG) { - System.err.println(getThreadName() + ": ChoosePixelFormat(HDC "+toHexString(hdc)+") = " + recommendedPixelFormat + " (LastError: "+WGL.GetLastError()+")"); + System.err.println(getThreadName() + ": ChoosePixelFormat(HDC "+toHexString(hdc)+") = " + recommendedPixelFormat + " (LastError: "+GDI.GetLastError()+")"); System.err.println(getThreadName() + ": Used " + capabilities); } - numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null); + numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null); if (numFormats == 0) { throw new GLException("Unable to enumerate pixel formats of window " + - toHexString(hdc) + " for GLCapabilitiesChooser (LastError: "+WGL.GetLastError()+")"); + toHexString(hdc) + " for GLCapabilitiesChooser (LastError: "+GDI.GetLastError()+")"); } availableCaps = new GLCapabilities[numFormats]; for (int i = 0; i < numFormats; i++) { - if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { + if (GDI.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { throw new GLException("Error describing pixel format " + (1 + i) + " of device context"); } availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer); @@ -261,23 +261,23 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):"); System.err.println(chosenCaps); } - if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { - throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError()); + if (GDI.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { + throw new GLException("Error re-describing the chosen pixel format: " + GDI.GetLastError()); } } else { // For now, use ChoosePixelFormat for offscreen surfaces until // we figure out how to properly choose an offscreen- // compatible pixel format pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities); - pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); + pixelFormat = GDI.ChoosePixelFormat(hdc, pfd); } if(!pixelFormatSet) { - if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) { - long lastError = WGL.GetLastError(); + if (!GDI.SetPixelFormat(hdc, pixelFormat, pfd)) { + long lastError = GDI.GetLastError(); if (DEBUG) { System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() + ", current DC = " + WGL.wglGetCurrentDC()); - System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc)); + System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + GDI.GetPixelFormat(hdc)); } throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java index 804a262fe..ddcac9628 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java @@ -37,28 +37,25 @@ import javax.media.opengl.*; import com.jogamp.nativewindow.impl.x11.*; public class GLXUtil { - public static boolean isMultisampleAvailable(long display) { - X11Util.XLockDisplay(display); - try { - String exts = GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS); - if (exts != null) { - return (exts.indexOf("GLX_ARB_multisample") >= 0); - } - return false; - } finally { - X11Util.XUnlockDisplay(display); + public static String getExtension(long display) { + return GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS); + } + + public static boolean isMultisampleAvailable(String extensions) { + if (extensions != null) { + return (extensions.indexOf("GLX_ARB_multisample") >= 0); } + return false; + } + + public static boolean isMultisampleAvailable(long display) { + return isMultisampleAvailable(getExtension(display)); } /** Workaround for apparent issue with ATI's proprietary drivers where direct contexts still send GLX tokens for GL calls */ public static String getVendorName(long display) { - X11Util.XLockDisplay(display); - try { - return GLX.glXGetClientString(display, GLX.GLX_VENDOR); - } finally { - X11Util.XUnlockDisplay(display); - } + return GLX.glXGetClientString(display, GLX.GLX_VENDOR); } public static boolean isVendorNVIDIA(String vendor) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java index 03783f3b9..afd005bb4 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java @@ -64,13 +64,10 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { int scrn = screen.getIndex(); long visualID = config.getVisualID(); - X11Util.XLockDisplay(dpy); - try{ - dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID); - } finally { - X11Util.XUnlockDisplay(dpy); - } + dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID); nw.setSurfaceHandle( dummyWindow ); + + updateHandle(); } public void setSize(int width, int height) { @@ -86,9 +83,9 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { public void destroy() { if(0!=dummyWindow) { + destroyHandle(); X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - long dpy = config.getScreen().getDevice().getHandle(); - X11Lib.DestroyDummyWindow(dpy, dummyWindow); + X11Lib.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java index 8792ac08e..a1e4585f7 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java @@ -59,36 +59,32 @@ public class X11ExternalGLXContext extends X11GLXContext { } protected static X11ExternalGLXContext create(GLDrawableFactory factory, GLProfile glp) { - ((GLDrawableFactoryImpl)factory).lockToolkit(); - try { - long ctx = GLX.glXGetCurrentContext(); - if (ctx == 0) { - throw new GLException("Error: current context null"); - } - long display = GLX.glXGetCurrentDisplay(); - if (display == 0) { - throw new GLException("Error: current display null"); - } - long drawable = GLX.glXGetCurrentDrawable(); - if (drawable == 0) { - throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); - } - int[] val = new int[1]; - GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val, 0); - X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); - - GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val, 0); - X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); - - NullWindow nw = new NullWindow(cfg); - nw.setSurfaceHandle(drawable); - return new X11ExternalGLXContext(new Drawable(factory, nw), ctx); - } finally { - ((GLDrawableFactoryImpl)factory).unlockToolkit(); + long ctx = GLX.glXGetCurrentContext(); + if (ctx == 0) { + throw new GLException("Error: current context null"); } + long display = GLX.glXGetCurrentDisplay(); + if (display == 0) { + throw new GLException("Error: current display null"); + } + long drawable = GLX.glXGetCurrentDrawable(); + if (drawable == 0) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); + } + int[] val = new int[1]; + GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val, 0); + X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); + + GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); + + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(drawable); + return new X11ExternalGLXContext(new Drawable(factory, nw), ctx); } - protected void create() { + protected boolean createImpl() { + return true; } public int makeCurrent() throws GLException { @@ -108,20 +104,16 @@ public class X11ExternalGLXContext extends X11GLXContext { lastContext = null; } - protected int makeCurrentImpl() throws GLException { + protected void makeCurrentImpl(boolean newCreated) throws GLException { if (firstMakeCurrent) { firstMakeCurrent = false; - return CONTEXT_CURRENT_NEW; } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { } protected void destroyImpl() throws GLException { - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); } // Need to provide the display connection to extension querying APIs diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java index f10bd38c6..8a8702a3e 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java @@ -62,46 +62,41 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable { } protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, GLProfile glp) { - ((GLDrawableFactoryImpl)factory).lockToolkit(); - try { - long context = GLX.glXGetCurrentContext(); - if (context == 0) { - throw new GLException("Error: current context null"); - } - long display = GLX.glXGetCurrentDisplay(); - if (display == 0) { - throw new GLException("Error: current display null"); - } - long drawable = GLX.glXGetCurrentDrawable(); - if (drawable == 0) { - throw new GLException("Error: attempted to make an external GLDrawable without a drawable current"); - } - int[] val = new int[1]; - GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); - X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); - - GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0); - X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); - - int w, h; - GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0); - w=val[0]; - GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0); - h=val[0]; - - GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0); - if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) { - if (DEBUG) { - System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")"); - } - } - NullWindow nw = new NullWindow(cfg); - nw.setSurfaceHandle(drawable); - nw.setSize(w, h); - return new X11ExternalGLXDrawable(factory, nw, GLX.GLX_RGBA_TYPE); - } finally { - ((GLDrawableFactoryImpl)factory).unlockToolkit(); + long context = GLX.glXGetCurrentContext(); + if (context == 0) { + throw new GLException("Error: current context null"); } + long display = GLX.glXGetCurrentDisplay(); + if (display == 0) { + throw new GLException("Error: current display null"); + } + long drawable = GLX.glXGetCurrentDrawable(); + if (drawable == 0) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable current"); + } + int[] val = new int[1]; + GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); + X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); + + GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); + + int w, h; + GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0); + w=val[0]; + GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0); + h=val[0]; + + GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0); + if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) { + if (DEBUG) { + System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")"); + } + } + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(drawable); + nw.setSize(w, h); + return new X11ExternalGLXDrawable(factory, nw, GLX.GLX_RGBA_TYPE); } public GLContext createContext(GLContext shareWith) { @@ -125,8 +120,8 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable { super(drawable, shareWith); } - protected void create() { - createContext(true); + protected boolean createImpl() { + return createContext(true); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index baca6bfa4..baa6ce1aa 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -60,6 +60,11 @@ public abstract class X11GLXContext extends GLContextImpl { // GLX extension functions. private GLXExtProcAddressTable glXExtProcAddressTable; + // This indicates whether the context we have created is indirect + // and therefore requires the toolkit to be locked around all GL + // calls rather than just all GLX calls + protected boolean isDirect; + static { functionNameMap = new HashMap(); functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV"); @@ -193,10 +198,7 @@ public abstract class X11GLXContext extends GLContextImpl { } } if(0!=ctx) { - if (!glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - ctx)) { + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), ctx)) { if(DEBUG) { System.err.println("X11GLXContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation")); } @@ -213,10 +215,8 @@ public abstract class X11GLXContext extends GLContextImpl { * called by {@link #create()}. * Note: The direct parameter may be overwritten by the direct state of a shared context. */ - protected void createContext(boolean direct) { - if(0!=contextHandle) { - throw new GLException("context is not null: "+contextHandle); - } + protected boolean createContext(boolean direct) { + isDirect = false; // default X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); long display = config.getScreen().getDevice().getHandle(); @@ -244,14 +244,12 @@ public abstract class X11GLXContext extends GLContextImpl { if (contextHandle == 0) { throw new GLException("Unable to create context(0)"); } - if (!glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - contextHandle)) { + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { throw new GLException("Error making temp context(0) current: display "+toHexString(display)+", context "+toHexString(contextHandle)+", drawable "+drawable); } setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION - return; + isDirect = GLX.glXIsDirect(display, contextHandle); + return true; } int minor[] = new int[1]; @@ -276,17 +274,14 @@ public abstract class X11GLXContext extends GLContextImpl { if (temp_ctx == 0) { throw new GLException("Unable to create temp OpenGL context(1)"); } - if (!glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - temp_ctx)) { + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), temp_ctx)) { throw new GLException("Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(temp_ctx)+", drawable "+drawable); } setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION if( createContextARBTried || - !isFunctionAvailable("glXCreateContextAttribsARB") /* || - !isExtensionAvailable("GLX_ARB_create_context") */ ) { // unresolved case where client version is 1.4 without this extension + !isFunctionAvailable("glXCreateContextAttribsARB") || + !isExtensionAvailable("GLX_ARB_create_context") ) { if(glp.isGL3()) { glXMakeContextCurrent(display, 0, 0, 0); GLX.glXDestroyContext(display, temp_ctx); @@ -298,7 +293,8 @@ public abstract class X11GLXContext extends GLContextImpl { // continue with temp context for GL < 3.0 contextHandle = temp_ctx; - return; + isDirect = GLX.glXIsDirect(display, contextHandle); + return true; } contextHandle = createContextARB(share, direct, major, minor, ctp); createContextARBTried=true; @@ -308,10 +304,7 @@ public abstract class X11GLXContext extends GLContextImpl { if(0!=temp_ctx) { glXMakeContextCurrent(display, 0, 0, 0); GLX.glXDestroyContext(display, temp_ctx); - if (!glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - contextHandle)) { + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { throw new GLException("Cannot make previous verified context current"); } } @@ -327,146 +320,63 @@ public abstract class X11GLXContext extends GLContextImpl { // continue with temp context for GL <= 3.0 contextHandle = temp_ctx; - if (!glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - contextHandle)) { + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { glXMakeContextCurrent(display, 0, 0, 0); GLX.glXDestroyContext(display, temp_ctx); throw new GLException("Error making context(1) current: display "+toHexString(display)+", context "+toHexString(contextHandle)+", drawable "+drawable); } } + isDirect = GLX.glXIsDirect(display, contextHandle); + return true; } - // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] - protected int makeCurrentImpl() throws GLException { - boolean exceptionOccurred = false; - int lockRes = drawable.lockSurface(); - try { - if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) { - return CONTEXT_NOT_CURRENT; - } - if (0 == drawable.getNativeWindow().getSurfaceHandle()) { - throw new GLException("drawable has invalid surface handle: "+drawable); - } - return makeCurrentImplAfterLock(); - } catch (RuntimeException e) { - exceptionOccurred = true; - throw e; - } finally { - if (exceptionOccurred || - (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) { - drawable.unlockSurface(); - } - } - } - - // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] - protected void releaseImpl() throws GLException { - try { - releaseImplAfterLock(); - } finally { - if (!isOptimizable() && drawable.isSurfaceLocked()) { - drawable.unlockSurface(); - } - } - } - - protected int makeCurrentImplAfterLock() throws GLException { + protected void makeCurrentImpl(boolean newCreated) throws GLException { long dpy = drawable.getNativeWindow().getDisplayHandle(); - getDrawableImpl().getFactoryImpl().lockToolkit(); - try { - boolean newCreated = false; - if (!isCreated()) { - create(); // throws exception if fails! - newCreated = true; - GLContextShareSet.contextCreated(this); - if (DEBUG) { - System.err.println(getThreadName() + ": !!! Created GL context " + toHexString(contextHandle) + " for " + getClass().getName()); - } - } - - if (GLX.glXGetCurrentContext() != contextHandle) { - - if (!glXMakeContextCurrent(dpy, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - contextHandle)) { - throw new GLException("Error making context current: "+this); - } - if (DEBUG && (VERBOSE || isCreated())) { - System.err.println(getThreadName() + ": glXMakeCurrent(display " + - toHexString(dpy)+ - ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + - ", drawableRead " + toHexString(drawableRead.getNativeWindow().getSurfaceHandle()) + - ", context " + toHexString(contextHandle) + ") succeeded"); - } + if (GLX.glXGetCurrentContext() != contextHandle) { + if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Error making context current: "+this); } - - if(newCreated) { - setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - return CONTEXT_CURRENT_NEW; + if (DEBUG && (VERBOSE || isCreated())) { + System.err.println(getThreadName() + ": glXMakeCurrent(display " + + toHexString(dpy)+ + ", drawable " + toHexString(drawable.getHandle()) + + ", drawableRead " + toHexString(drawableRead.getHandle()) + + ", context " + toHexString(contextHandle) + ") succeeded"); } - return CONTEXT_CURRENT; - } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); } } - protected void releaseImplAfterLock() throws GLException { - X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); - factory.lockToolkit(); - try { - if (!glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), 0, 0, 0)) { - throw new GLException("Error freeing OpenGL context"); - } - } finally { - factory.unlockToolkit(); + protected void releaseImpl() throws GLException { + long display = drawable.getNativeWindow().getDisplayHandle(); + if (!glXMakeContextCurrent(display, 0, 0, 0)) { + throw new GLException("Error freeing OpenGL context"); } } protected void destroyImpl() throws GLException { - getDrawableImpl().getFactoryImpl().lockToolkit(); - try { - if (contextHandle != 0) { - if (DEBUG) { - System.err.println("glXDestroyContext(" + - toHexString(drawable.getNativeWindow().getDisplayHandle()) + - ", " + - toHexString(contextHandle) + ")"); - } - GLX.glXDestroyContext(drawable.getNativeWindow().getDisplayHandle(), contextHandle); - if (DEBUG) { - System.err.println("!!! Destroyed OpenGL context " + contextHandle); - } - contextHandle = 0; - GLContextShareSet.contextDestroyed(this); - } - } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); + long display = drawable.getNativeWindow().getDisplayHandle(); + if (DEBUG) { + System.err.println("glXDestroyContext(dpy " + + toHexString(display)+ + ", ctx " + + toHexString(contextHandle) + ")"); + } + GLX.glXDestroyContext(display, contextHandle); + if (DEBUG) { + System.err.println("!!! Destroyed OpenGL context " + contextHandle); } } - public void copy(GLContext source, int mask) throws GLException { + protected void copyImpl(GLContext source, int mask) throws GLException { long dst = getHandle(); long src = source.getHandle(); - if (src == 0) { - throw new GLException("Source OpenGL context has not been created"); - } - if (dst == 0) { - throw new GLException("Destination OpenGL context has not been created"); - } - if (drawable.getNativeWindow().getDisplayHandle() == 0) { + long display = drawable.getNativeWindow().getDisplayHandle(); + if (0 == display) { throw new GLException("Connection to X display not yet set up"); } - getDrawableImpl().getFactoryImpl().lockToolkit(); - try { - GLX.glXCopyContext(drawable.getNativeWindow().getDisplayHandle(), src, dst, mask); - // Should check for X errors and raise GLException - } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); - } + GLX.glXCopyContext(display, src, dst, mask); + // Should check for X errors and raise GLException } protected void updateGLProcAddressTable(int major, int minor, int ctp) { @@ -492,18 +402,13 @@ public abstract class X11GLXContext extends GLContextImpl { glXQueryExtensionsStringInitialized = true; } if (glXQueryExtensionsStringAvailable) { - GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl(); - factory.lockToolkit(); - try { + long display = drawable.getNativeWindow().getDisplayHandle(); String ret = GLX.glXQueryExtensionsString(drawable.getNativeWindow().getDisplayHandle(), drawable.getNativeWindow().getScreenIndex()); if (DEBUG) { System.err.println("!!! GLX extensions: " + ret); } return ret; - } finally { - factory.unlockToolkit(); - } } else { return ""; } @@ -526,10 +431,9 @@ public abstract class X11GLXContext extends GLContextImpl { GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); if(!glCaps.isOnscreen()) return; - getDrawableImpl().getFactoryImpl().lockToolkit(); - try { - GLXExt glXExt = getGLXExt(); - if(0==hasSwapIntervalSGI) { + long display = drawable.getNativeWindow().getDisplayHandle(); + GLXExt glXExt = getGLXExt(); + if(0==hasSwapIntervalSGI) { try { hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1; } catch (Throwable t) { hasSwapIntervalSGI=1; } @@ -540,9 +444,6 @@ public abstract class X11GLXContext extends GLContextImpl { currentSwapInterval = interval; } } catch (Throwable t) { hasSwapIntervalSGI=-1; } - } - } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); } } @@ -570,8 +471,15 @@ public abstract class X11GLXContext extends GLContextImpl { throw new GLException("Should not call this"); } - public boolean isOptimizable() { - return (super.isOptimizable() && !isVendorATI); + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()); + sb.append(" ["); + super.append(sb); + sb.append(", direct "); + sb.append(isDirect); + sb.append("] "); + return sb.toString(); } //---------------------------------------------------------------------- diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java index e943abc43..25cfcc723 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java @@ -42,7 +42,7 @@ package com.jogamp.opengl.impl.x11.glx; import javax.media.nativewindow.*; import javax.media.opengl.*; import com.jogamp.opengl.impl.*; -import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.nativewindow.impl.x11.*; public abstract class X11GLXDrawable extends GLDrawableImpl { protected X11GLXDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) { @@ -50,45 +50,22 @@ public abstract class X11GLXDrawable extends GLDrawableImpl { } public GLDynamicLookupHelper getGLDynamicLookupHelper() { - return X11GLXDynamicLookupHelper.getX11GLXDynamicLookupHelper(); + return getFactoryImpl().getGLDynamicLookupHelper(0); } protected void setRealizedImpl() { - if(!realized) { - return; // nothing to do - } - - if(NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) { - throw new GLException("X11GLXDrawable.setRealized(true): lockSurface - surface not ready"); - } - try { + if(realized) { X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); config.updateGraphicsConfiguration(); if (DEBUG) { System.err.println("!!! X11GLXDrawable.setRealized(true): "+config); } - } finally { - unlockSurface(); } } protected void swapBuffersImpl() { - boolean didLock = false; - if (!isSurfaceLocked()) { - // Usually the surface shall be locked within [makeCurrent .. swap .. release] - if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { - return; - } - didLock = true; - } - try { - GLX.glXSwapBuffers(component.getDisplayHandle(), component.getSurfaceHandle()); - } finally { - if (didLock) { - unlockSurface(); - } - } + GLX.glXSwapBuffers(getNativeWindow().getDisplayHandle(), getHandle()); } //--------------------------------------------------------------------------- diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index fe2176f61..822a3d0b3 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -49,17 +49,31 @@ import com.jogamp.nativewindow.impl.x11.*; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { + private static final DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper; + static { X11Util.initSingleton(); // ensure it's loaded and setup + + DesktopGLDynamicLookupHelper tmp = null; + try { + tmp = new DesktopGLDynamicLookupHelper(new X11GLXDynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + x11GLXDynamicLookupHelper = tmp; + if(null!=x11GLXDynamicLookupHelper) { + GLX.getGLXProcAddressTable().reset(x11GLXDynamicLookupHelper); + } } public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { - return X11GLXDynamicLookupHelper.getX11GLXDynamicLookupHelper(); + return x11GLXDynamicLookupHelper; } public X11GLXDrawableFactory() { super(); - X11GLXDynamicLookupHelper.getX11GLXDynamicLookupHelper(); // ensure it's loaded and setup // Register our GraphicsConfigurationFactory implementations // The act of constructing them causes them to be registered new X11GLXGraphicsConfigurationFactory(); @@ -75,12 +89,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { isVendorATI = GLXUtil.isVendorATI(vendorName); isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); sharedScreen = new X11GraphicsScreen(sharedDevice, 0); - X11Util.XLockDisplay(tlsDisplay); - try{ - sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault()); - } finally { - X11Util.XUnlockDisplay(tlsDisplay); - } + sharedDrawable = new X11DummyGLXDrawable(sharedScreen, X11GLXDrawableFactory.this, GLProfile.getDefault()); if(isVendorATI() && GLProfile.isAWTAvailable()) { X11Util.markThreadLocalDisplayUncloseable(tlsDisplay); // failure to close with ATI and AWT usage } @@ -89,7 +98,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } // We have to keep this within this thread, // since we have a 'chicken-and-egg' problem otherwise on the <init> lock of this thread. - X11Util.XLockDisplay(sharedScreen.getDevice().getHandle()); try{ X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); ctx.makeCurrent(); @@ -97,8 +105,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { sharedContext = ctx; } catch (Throwable t) { throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t); - } finally { - X11Util.XUnlockDisplay(sharedScreen.getDevice().getHandle()); } if(null==sharedContext) { throw new GLException("X11GLXDrawableFactory - Shared Context is null"); @@ -137,13 +143,15 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { System.err.println("!!! Drawable: "+sharedDrawable); System.err.println("!!! Screen : "+sharedScreen); } + + // don't free native resources from this point on, + // since we might be in a critical shutdown hook sequence + if(null!=sharedContext) { - sharedContext.destroy(); // implies release, if current + // may cause deadlock: sharedContext.destroy(); sharedContext=null; } - // don't free native resources from this point on, - // since we might be in a critical shutdown hook sequence if(null!=sharedDrawable) { // may cause deadlock: sharedDrawable.destroy(); sharedDrawable=null; @@ -152,7 +160,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { // may cause deadlock: X11Util.closeThreadLocalDisplay(null); sharedScreen = null; } - // don't close pending XDisplay, since they might be a different thread as the opener + // don't close pending XDisplay, since this might be a different thread as the opener X11Util.shutdown( false, DEBUG ); } @@ -231,13 +239,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { - NullWindow nw = null; - X11Util.XLockDisplay(sharedScreen.getDevice().getHandle()); - try{ - nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen)); - }finally{ - X11Util.XUnlockDisplay(sharedScreen.getDevice().getHandle()); - } + NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen)); if(nw != null) { nw.setSize(width, height); } @@ -278,21 +280,16 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { long display = sharedScreen.getDevice().getHandle(); - X11Util.XLockDisplay(display); - try { - int[] size = new int[1]; - boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, - X11Lib.DefaultScreen(display), - size, 0); - if (!res) { - return 0; - } - gotGammaRampLength = true; - gammaRampLength = size[0]; - return gammaRampLength; - } finally { - X11Util.XUnlockDisplay(display); + int[] size = new int[1]; + boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, + X11Lib.DefaultScreen(display), + size, 0); + if (!res) { + return 0; } + gotGammaRampLength = true; + gammaRampLength = size[0]; + return gammaRampLength; } protected boolean setGammaRamp(float[] ramp) { @@ -303,18 +300,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } long display = sharedScreen.getDevice().getHandle(); - X11Util.XLockDisplay(display); - try { - boolean res = X11Lib.XF86VidModeSetGammaRamp(display, - X11Lib.DefaultScreen(display), - rampData.length, - rampData, 0, - rampData, 0, - rampData, 0); - return res; - } finally { - X11Util.XUnlockDisplay(display); - } + boolean res = X11Lib.XF86VidModeSetGammaRamp(display, + X11Lib.DefaultScreen(display), + rampData.length, + rampData, 0, + rampData, 0, + rampData, 0); + return res; } protected Buffer getGammaRamp() { @@ -330,21 +322,16 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); long display = sharedScreen.getDevice().getHandle(); - X11Util.XLockDisplay(display); - try { - boolean res = X11Lib.XF86VidModeGetGammaRamp(display, - X11Lib.DefaultScreen(display), - size, - redRampData, - greenRampData, - blueRampData); - if (!res) { - return null; - } - return rampData; - } finally { - X11Util.XUnlockDisplay(display); + boolean res = X11Lib.XF86VidModeGetGammaRamp(display, + X11Lib.DefaultScreen(display), + size, + redRampData, + greenRampData, + blueRampData); + if (!res) { + return null; } + return rampData; } protected void resetGammaRamp(Buffer originalGammaRamp) { @@ -366,16 +353,11 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); long display = sharedScreen.getDevice().getHandle(); - X11Util.XLockDisplay(display); - try { - X11Lib.XF86VidModeSetGammaRamp(display, - X11Lib.DefaultScreen(display), - size, - redRampData, - greenRampData, - blueRampData); - } finally { - X11Util.XUnlockDisplay(display); - } + X11Lib.XF86VidModeSetGammaRamp(display, + X11Lib.DefaultScreen(display), + size, + redRampData, + greenRampData, + blueRampData); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDynamicLibraryBundleInfo.java index d0b0acaa3..d958996a8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDynamicLibraryBundleInfo.java @@ -25,7 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package com.jogamp.opengl.impl.windows.wgl; +package com.jogamp.opengl.impl.x11.glx; import com.jogamp.opengl.impl.*; import com.jogamp.common.os.DynamicLookupHelper; @@ -35,57 +35,54 @@ import java.util.*; import java.security.*; import javax.media.opengl.GLException; -public class WindowsWGLDynamicLookupHelper extends DesktopGLDynamicLookupHelper { - private static final WindowsWGLDynamicLookupHelper windowsWGLDynamicLookupHelper; - - static { - WindowsWGLDynamicLookupHelper tmp = null; - try { - tmp = new WindowsWGLDynamicLookupHelper(); - } catch (GLException gle) { - if(DEBUG) { - gle.printStackTrace(); - } - } - windowsWGLDynamicLookupHelper = tmp; - } - - public static WindowsWGLDynamicLookupHelper getWindowsWGLDynamicLookupHelper() { - return windowsWGLDynamicLookupHelper; - } - - protected WindowsWGLDynamicLookupHelper() { +public class X11GLXDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { + protected X11GLXDynamicLibraryBundleInfo() { super(); } - public synchronized void loadGLULibrary() { - if(null==gluLib) { - List/*<String>*/ gluLibNames = new ArrayList(); - gluLibNames.add("GLU32"); - gluLib = loadFirstAvailable(gluLibNames, null, false); - if(null != gluLib) { - glLibraries.add(gluLib); - } - } - } - NativeLibrary gluLib = null; + public List getToolLibNames() { + List/*<List>*/ libNamesList = new ArrayList(); - protected final List/*<String>*/ getGLLibNames() { List/*<String>*/ glesLibNames = new ArrayList(); - glesLibNames.add("OpenGL32"); - return glesLibNames; - } - protected final List/*<String>*/ getGLXLibNames() { - return null; + // Be aware that on DRI systems, eg ATI fglrx, etc, + // you have to set LIBGL_DRIVERS_PATH env variable. + // Eg on Ubuntu 64bit systems this is: + // export LIBGL_DRIVERS_PATH=/usr/lib/fglrx/dri:/usr/lib32/fglrx/dri + // + + // this is the default GL lib name, according to the spec + glesLibNames.add("libGL.so.1"); + + // try this one as well, if spec fails + glesLibNames.add("libGL.so"); + + // last but not least .. the generic one + glesLibNames.add("GL"); + + libNamesList.add(glesLibNames); + + return libNamesList; } - protected final String getGLXGetProcAddressFuncName() { - return "wglGetProcAddress" ; + /** + * This respects old DRI requirements:<br> + * <pre> + * http://dri.sourceforge.net/doc/DRIuserguide.html + * </pre> + */ + public boolean shallLinkGlobal() { return true; } + + public final List getToolGetProcAddressFuncNameList() { + List res = new ArrayList(); + res.add("glXGetProcAddressARB"); + res.add("glXGetProcAddress"); + return res; } - protected long dynamicLookupFunctionOnGLX(long glxGetProcAddressHandle, String glFuncName) { - return WGL.wglGetProcAddress(glFuncName); + public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) { + return GLX.glXGetProcAddress(toolGetProcAddressHandle, funcName); } } + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDynamicLookupHelper.java deleted file mode 100644 index 867a80bb8..000000000 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDynamicLookupHelper.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2010, Sven Gothel - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sven Gothel nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jogamp.opengl.impl.x11.glx; - -import com.jogamp.opengl.impl.*; -import com.jogamp.common.os.DynamicLookupHelper; -import com.jogamp.common.os.NativeLibrary; -import com.jogamp.common.os.Platform; -import java.util.*; -import java.security.*; -import javax.media.opengl.GLException; - -public class X11GLXDynamicLookupHelper extends DesktopGLDynamicLookupHelper { - private static final X11GLXDynamicLookupHelper x11GLXDynamicLookupHelper; - - static { - X11GLXDynamicLookupHelper tmp = null; - try { - tmp = new X11GLXDynamicLookupHelper(); - } catch (GLException gle) { - if(DEBUG) { - gle.printStackTrace(); - } - } - x11GLXDynamicLookupHelper = tmp; - } - - public static X11GLXDynamicLookupHelper getX11GLXDynamicLookupHelper() { - return x11GLXDynamicLookupHelper; - } - - protected X11GLXDynamicLookupHelper() { - super(); - GLX.getGLXProcAddressTable().reset(this); - } - - public synchronized void loadGLULibrary() { - if(null==gluLib) { - List/*<String>*/ gluLibNames = new ArrayList(); - gluLibNames.add("libGLU.so"); - if(Platform.is32Bit()) { - gluLibNames.add("/usr/lib32/libGLU.so"); - } else { - gluLibNames.add("/usr/lib64/libGLU.so"); - } - gluLibNames.add("GLU"); - gluLib = loadFirstAvailable(gluLibNames, null, true); - if(null != gluLib) { - glLibraries.add(gluLib); - } - } - } - NativeLibrary gluLib = null; - - protected final List/*<String>*/ getGLLibNames() { - List/*<String>*/ glesLibNames = new ArrayList(); - - // first reassemble old DRIHack order, ie using hardcoded names .. - glesLibNames.add("libGL.so.1"); - if(Platform.is32Bit()) { - glesLibNames.add("/usr/lib32/libGL.so.1"); - } else { - glesLibNames.add("/usr/lib64/libGL.so.1"); - } - - // at last .. the generic one, should be default! - glesLibNames.add("GL"); - return glesLibNames; - } - - protected final List/*<String>*/ getGLXLibNames() { - return null; - } - - protected boolean shallGLLibLoadedGlobal() { return true; } - - protected boolean shallGLXLibLoadedGlobal() { return true; } - - protected final String getGLXGetProcAddressFuncName() { - return "glXGetProcAddressARB" ; - } - - protected long dynamicLookupFunctionOnGLX(long glxGetProcAddressHandle, String glFuncName) { - return GLX.glXGetProcAddressARB(glFuncName); - } -} - - diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java index 35daf0ae0..589d7b2db 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -73,7 +73,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem if(null==caps) { throw new GLException("GLCapabilities null of "+toHexString(fbcfg)); } - XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); + XVisualInfo xvi = GLX.glXGetVisualFromFBConfig(display, fbcfg); if(null==xvi) { throw new GLException("XVisualInfo null of "+toHexString(fbcfg)); } @@ -326,7 +326,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem public static long glXFBConfigID2FBConfig(long display, int screen, int id) { int[] attribs = new int[] { GLX.GLX_FBCONFIG_ID, id, 0 }; int[] count = { -1 }; - PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + PointerBuffer fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<1) { return 0; } @@ -336,20 +336,14 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem // Visual Info public static XVisualInfo XVisualID2XVisualInfo(long display, long visualID) { - XVisualInfo res = null; - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try{ - int[] count = new int[1]; - XVisualInfo template = XVisualInfo.create(); - template.setVisualid(visualID); - XVisualInfo[] infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualIDMask, template, count, 0); - if (infos == null || infos.length == 0) { + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setVisualid(visualID); + XVisualInfo[] infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask, template, count, 0); + if (infos == null || infos.length == 0) { return null; - } - res = XVisualInfo.create(infos[0]); - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } + } + XVisualInfo res = XVisualInfo.create(infos[0]); if (DEBUG) { System.err.println("!!! Fetched XVisualInfo for visual ID " + toHexString(visualID)); System.err.println("!!! Resulting XVisualInfo: visualid = " + toHexString(res.getVisualid())); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index a160734d3..5c04a29fe 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -80,8 +80,6 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac GLCapabilities capsFB = null; long display = x11Screen.getDevice().getHandle(); - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - X11Util.XLockDisplay(display); try { int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); @@ -92,7 +90,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, display, screen); int[] count = { -1 }; - PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + PointerBuffer fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<1) { throw new Exception("Could not fetch FBConfig for "+caps); } @@ -101,14 +99,11 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac fbid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); - xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); + xvis = GLX.glXGetVisualFromFBConfig(display, fbcfg); if (xvis==null) { throw new GLException("Error: Choosen FBConfig has no visual"); } } catch (Throwable t) { - } finally { - X11Util.XUnlockDisplay(display); - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid); @@ -189,113 +184,103 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - X11Util.XLockDisplay(display); - try{ - int screen = x11Screen.getIndex(); - boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); - int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen); - int[] count = { -1 }; - - // determine the recommended FBConfig .. - fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); - if (fbcfgsL == null || fbcfgsL.limit()<1) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]); - } - } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0))); - } - } else { - recommendedFBConfig = fbcfgsL.get(0); - } - - // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..) - fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, null, 0, count, 0); - if (fbcfgsL == null || fbcfgsL.limit()<1) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); - } - return null; - } + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen); + int[] count = { -1 }; - // make GLCapabilities and seek the recommendedIndex - caps = new GLCapabilities[fbcfgsL.limit()]; - for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capabilities+"): fbcfg: "+toHexString(fbcfgsL.get(i))); - } - } else { - caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); - if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) { - recommendedIndex=i; - if (DEBUG) { - System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]); - } - } - } - } + // determine the recommended FBConfig .. + fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]); + } + } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0))); + } + } else { + recommendedFBConfig = fbcfgsL.get(0); + } - if(null==chooser) { - chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1) - } + // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..) + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); + } + return null; + } - if (chosen < 0) { - if(null==chooser) { - // nothing recommended .. so use our default implementation - chooser = new DefaultGLCapabilitiesChooser(); - } - try { - chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); - } catch (NativeWindowException e) { - if(DEBUG) { - e.printStackTrace(); - } - chosen = -1; - } + // make GLCapabilities and seek the recommendedIndex + caps = new GLCapabilities[fbcfgsL.limit()]; + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capabilities+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } - if (chosen < 0) { - // keep on going .. - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first"); - } - // seek first available one .. - for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) ; - if(chosen==caps.length) { - // give up .. - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out"); - } - return null; - } - } else if (chosen >= caps.length) { - if(DEBUG) { - System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")"); + } else { + caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), + false, onscreen, usePBuffer, isMultisampleAvailable); + if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) { + recommendedIndex=i; + if (DEBUG) { + System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]); } - return null; } + } + } - retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); + if(null==chooser) { + chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1) + } - retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen)); - if (retXVisualInfo==null) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosen) +" (Continue: "+(false==caps[chosen].isOnscreen())+"):\n\t"+caps[chosen]); - } - if(caps[chosen].isOnscreen()) { - // Onscreen drawables shall have a XVisual .. - return null; - } - } - }finally{ - X11Util.XUnlockDisplay(display); + if (chosen < 0) { + if(null==chooser) { + // nothing recommended .. so use our default implementation + chooser = new DefaultGLCapabilitiesChooser(); + } + try { + chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + } catch (NativeWindowException e) { + if(DEBUG) { + e.printStackTrace(); + } + chosen = -1; + } + } + if (chosen < 0) { + // keep on going .. + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first"); + } + // seek first available one .. + for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) ; + if(chosen==caps.length) { + // give up .. + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out"); + } + return null; + } + } else if (chosen >= caps.length) { + if(DEBUG) { + System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")"); + } + return null; + } + + retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); + + retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosen)); + if (retXVisualInfo==null) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosen) +" (Continue: "+(false==caps[chosen].isOnscreen())+"):\n\t"+caps[chosen]); + } + if(caps[chosen].isOnscreen()) { + // Onscreen drawables shall have a XVisual .. + return null; } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID); @@ -322,66 +307,56 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - X11Util.XLockDisplay(display); - try{ - int screen = x11Screen.getIndex(); - boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); - int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen); - XVisualInfo[] infos = null; - - XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0); - if (DEBUG) { - System.err.print("!!! glXChooseVisual recommended "); - if (recommendedVis == null) { - System.err.println("null visual"); - } else { - System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); - } - } - int[] count = new int[1]; - XVisualInfo template = XVisualInfo.create(); - template.setScreen(screen); - infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, template, count, 0); - if (infos == null || infos.length<1) { - throw new GLException("Error while enumerating available XVisualInfos"); - } - caps = new GLCapabilities[infos.length]; - for (int i = 0; i < infos.length; i++) { - caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); - // Attempt to find the visual chosen by glXChooseVisual - if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { - recommendedIndex = i; - } - } - try { - chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); - } catch (NativeWindowException e) { - if(DEBUG) { - e.printStackTrace(); - } - chosen = -1; - } - if (chosen < 0) { - // keep on going .. - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first"); - } - chosen = 0; // default .. - } else if (chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); - } - if (infos[chosen] == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]); - } - retXVisualInfo = XVisualInfo.create(infos[chosen]); - }finally{ - X11Util.XUnlockDisplay(display); + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen); + XVisualInfo[] infos = null; + + XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); + if (DEBUG) { + System.err.print("!!! glXChooseVisual recommended "); + if (recommendedVis == null) { + System.err.println("null visual"); + } else { + System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); + } + } + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setScreen(screen); + infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + caps = new GLCapabilities[infos.length]; + for (int i = 0; i < infos.length; i++) { + caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); + // Attempt to find the visual chosen by glXChooseVisual + if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { + recommendedIndex = i; } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } + try { + chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + } catch (NativeWindowException e) { + if(DEBUG) { + e.printStackTrace(); + } + chosen = -1; + } + if (chosen < 0) { + // keep on going .. + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first"); + } + chosen = 0; // default .. + } else if (chosen >= caps.length) { + throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); + } + if (infos[chosen] == null) { + throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]); + } + retXVisualInfo = XVisualInfo.create(infos[chosen]); return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java index bea953ee9..5482d5566 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java @@ -71,7 +71,7 @@ public class X11OffscreenGLXContext extends X11GLXContext { return true; } - protected void create() { - createContext(false); + protected boolean createImpl() { + return createContext(false); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java index 5771e9c42..230387c1c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -73,33 +73,22 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { long dpy = aDevice.getHandle(); int screen = aScreen.getIndex(); - getFactoryImpl().lockToolkit(); - try { - X11Util.XLockDisplay(dpy); - try{ - - pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen), - component.getWidth(), component.getHeight(), bitsPerPixel); - if (pixmap == 0) { - throw new GLException("XCreatePixmap failed"); - } - long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap); - if (drawable == 0) { - X11Lib.XFreePixmap(dpy, pixmap); - pixmap = 0; - throw new GLException("glXCreateGLXPixmap failed"); - } - ((SurfaceChangeable)nw).setSurfaceHandle(drawable); - if (DEBUG) { - System.err.println("Created pixmap " + toHexString(pixmap) + - ", GLXPixmap " + toHexString(drawable) + - ", display " + toHexString(dpy)); - } - }finally{ - X11Util.XUnlockDisplay(dpy); - } - } finally { - getFactoryImpl().unlockToolkit(); + pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen), + component.getWidth(), component.getHeight(), bitsPerPixel); + if (pixmap == 0) { + throw new GLException("XCreatePixmap failed"); + } + long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap); + if (drawable == 0) { + X11Lib.XFreePixmap(dpy, pixmap); + pixmap = 0; + throw new GLException("glXCreateGLXPixmap failed"); + } + ((SurfaceChangeable)nw).setSurfaceHandle(drawable); + if (DEBUG) { + System.err.println("Created pixmap " + toHexString(pixmap) + + ", GLXPixmap " + toHexString(drawable) + + ", display " + toHexString(dpy)); } } @@ -109,46 +98,36 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { NativeWindow nw = getNativeWindow(); long display = nw.getDisplayHandle(); - getFactoryImpl().lockToolkit(); - try { - X11Util.XLockDisplay(display); - try{ - long drawable = nw.getSurfaceHandle(); - if (DEBUG) { - System.err.println("Destroying pixmap " + toHexString(pixmap) + - ", GLXPixmap " + toHexString(drawable) + - ", display " + toHexString(display)); - } - - // Must destroy pixmap and GLXPixmap - - if (DEBUG) { - long cur = GLX.glXGetCurrentContext(); - if (cur != 0) { - System.err.println("WARNING: found context " + toHexString(cur) + " current during pixmap destruction"); - } - } - - // FIXME: workaround for crashes on NVidia hardware when - // destroying pixmap (no context is current at the point of the - // crash, at least from the point of view of - // glXGetCurrentContext) - GLX.glXMakeCurrent(display, 0, 0); + long drawable = nw.getSurfaceHandle(); + if (DEBUG) { + System.err.println("Destroying pixmap " + toHexString(pixmap) + + ", GLXPixmap " + toHexString(drawable) + + ", display " + toHexString(display)); + } - GLX.glXDestroyGLXPixmap(display, drawable); - X11Lib.XFreePixmap(display, pixmap); - drawable = 0; - pixmap = 0; - ((SurfaceChangeable)nw).setSurfaceHandle(0); + // Must destroy pixmap and GLXPixmap - }finally{ - X11Util.XUnlockDisplay(display); + if (DEBUG) { + long cur = GLX.glXGetCurrentContext(); + if (cur != 0) { + System.err.println("WARNING: found context " + toHexString(cur) + " current during pixmap destruction"); } - } finally { - getFactoryImpl().unlockToolkit(); - display = 0; } + + // FIXME: workaround for crashes on NVidia hardware when + // destroying pixmap (no context is current at the point of the + // crash, at least from the point of view of + // glXGetCurrentContext) + GLX.glXMakeCurrent(display, 0, 0); + + GLX.glXDestroyGLXPixmap(display, drawable); + X11Lib.XFreePixmap(display, pixmap); + drawable = 0; + pixmap = 0; + ((SurfaceChangeable)nw).setSurfaceHandle(0); + display = 0; } + protected void swapBuffersImpl() { if(DEBUG) { System.err.println("unhandled swapBuffersImpl() called for: "+this); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java index 710f93e98..bb1e2fd4c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java @@ -47,22 +47,12 @@ import com.jogamp.opengl.impl.*; import com.jogamp.opengl.impl.x11.*; public class X11OnscreenGLXContext extends X11GLXContext { - // This indicates whether the context we have created is indirect - // and therefore requires the toolkit to be locked around all GL - // calls rather than just all GLX calls - protected boolean isIndirect; - public X11OnscreenGLXContext(X11OnscreenGLXDrawable drawable, GLContext shareWith) { super(drawable, shareWith); } - public boolean isOptimizable() { - return super.isOptimizable() && !isIndirect; - } - - protected void create() { - createContext(true); - isIndirect = !GLX.glXIsDirect(drawable.getNativeWindow().getDisplayHandle(), contextHandle); + protected boolean createImpl() { + return createContext(true); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java index 43468b858..a9aafa5af 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java @@ -43,10 +43,54 @@ import javax.media.nativewindow.*; import javax.media.opengl.*; import com.jogamp.opengl.impl.*; import com.jogamp.opengl.impl.x11.*; +import com.jogamp.nativewindow.impl.x11.*; public class X11OnscreenGLXDrawable extends X11GLXDrawable { + /** GLXWindow can't be made current on AWT with NVidia driver, hence disabled for now */ + public static final boolean USE_GLXWINDOW = false; + long glXWindow; // GLXWindow, a GLXDrawable representation + boolean useGLXWindow; + protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeWindow component) { super(factory, component, false); + glXWindow=0; + useGLXWindow=false; + } + + public long getHandle() { + if(useGLXWindow) { + return glXWindow; + } + return getNativeWindow().getSurfaceHandle(); + } + + protected void destroyHandle() { + if(0!=glXWindow) { + GLX.glXDestroyWindow(getNativeWindow().getDisplayHandle(), glXWindow); + glXWindow = 0; + useGLXWindow=false; + } + } + + /** must be locked already */ + protected void updateHandle() { + if(USE_GLXWINDOW) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + if(config.getFBConfig()>=0) { + useGLXWindow=true; + long dpy = getNativeWindow().getDisplayHandle(); + if(0!=glXWindow) { + GLX.glXDestroyWindow(dpy, glXWindow); + } + glXWindow = GLX.glXCreateWindow(dpy, config.getFBConfig(), getNativeWindow().getSurfaceHandle(), null, 0); + if (DEBUG) { + System.err.println("!!! X11OnscreenGLXDrawable.setRealized(true): glXWindow: "+toHexString(getNativeWindow().getSurfaceHandle())+" -> "+toHexString(glXWindow)); + } + if(0==glXWindow) { + throw new GLException("X11OnscreenGLXDrawable.setRealized(true): GLX.glXCreateWindow() failed: "+this); + } + } + } } public GLContext createContext(GLContext shareWith) { @@ -60,5 +104,4 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable { public int getHeight() { return component.getHeight(); } - } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java index 1b70adf6b..debf28127 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java @@ -67,7 +67,7 @@ public class X11PbufferGLXContext extends X11GLXContext { return drawable.getFloatingPointMode(); } - protected void create() { - createContext(true); + protected boolean createImpl() { + return createContext(true); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java index 50b32b9ec..009fa147f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java @@ -76,21 +76,14 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { } public void destroy() { - getFactoryImpl().lockToolkit(); - try { - NativeWindow nw = getNativeWindow(); - if (nw.getSurfaceHandle() != 0) { - GLX.glXDestroyPbuffer(nw.getDisplayHandle(), nw.getSurfaceHandle()); - } - ((SurfaceChangeable)nw).setSurfaceHandle(0); - } finally { - getFactoryImpl().unlockToolkit(); + NativeWindow nw = getNativeWindow(); + if (nw.getSurfaceHandle() != 0) { + GLX.glXDestroyPbuffer(nw.getDisplayHandle(), nw.getSurfaceHandle()); } + ((SurfaceChangeable)nw).setSurfaceHandle(0); } private void createPbuffer() { - getFactoryImpl().lockToolkit(); - try { X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); AbstractGraphicsScreen aScreen = config.getScreen(); AbstractGraphicsDevice aDevice = aScreen.getDevice(); @@ -139,9 +132,6 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0); int height = tmp[0]; ((SurfaceChangeable)nw).setSize(width, height); - } finally { - getFactoryImpl().unlockToolkit(); - } } public int getFloatingPointMode() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java index dc6c60664..9e52040cf 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -87,57 +87,51 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration GraphicsConfiguration gc; X11GraphicsConfiguration x11Config; - // Need the lock here, since it could be an AWT owned display connection - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device); - if(0==displayHandle) { - displayHandle = X11Util.createThreadLocalDefaultDisplay(); - if(DEBUG) { - System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display"); - } - } else { - if(DEBUG) { - System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle)); - } - } - ((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle); - X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle); - - X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex()); + long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device); + if(0==displayHandle) { + displayHandle = X11Util.createThreadLocalDisplay(null); if(DEBUG) { - System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen); + System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display"); } - - gc = device.getDefaultConfiguration(); - AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc); + } else { if(DEBUG) { - System.err.println("AWT Colormodel compatible: "+capabilities); + System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle)); } + } + ((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle); + X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle); - x11Config = (X11GraphicsConfiguration) - GraphicsConfigurationFactory.getFactory(x11Device).chooseGraphicsConfiguration(capabilities, - chooser, - x11Screen); - if (x11Config == null) { - throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+x11Screen); - } + X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex()); + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen); + } + + gc = device.getDefaultConfiguration(); + AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc); + if(DEBUG) { + System.err.println("AWT Colormodel compatible: "+capabilities); + } + + x11Config = (X11GraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(x11Device).chooseGraphicsConfiguration(capabilities, + chooser, + x11Screen); + if (x11Config == null) { + throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+x11Screen); + } - long visualID = x11Config.getVisualID(); - // Now figure out which GraphicsConfiguration corresponds to this - // visual by matching the visual ID - GraphicsConfiguration[] configs = device.getConfigurations(); - for (int i = 0; i < configs.length; i++) { - GraphicsConfiguration config = configs[i]; - if (config != null) { - if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) { - return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), - config, x11Config); - } + long visualID = x11Config.getVisualID(); + // Now figure out which GraphicsConfiguration corresponds to this + // visual by matching the visual ID + GraphicsConfiguration[] configs = device.getConfigurations(); + for (int i = 0; i < configs.length; i++) { + GraphicsConfiguration config = configs[i]; + if (config != null) { + if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) { + return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), + config, x11Config); } } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } // Either we weren't able to reflectively introspect on the // X11GraphicsConfig or something went wrong in the steps above; diff --git a/src/jogl/classes/com/jogamp/openmax/OMXInstance.java b/src/jogl/classes/com/jogamp/openmax/OMXInstance.java index 2ebae9b58..97f07da1c 100644 --- a/src/jogl/classes/com/jogamp/openmax/OMXInstance.java +++ b/src/jogl/classes/com/jogamp/openmax/OMXInstance.java @@ -84,7 +84,7 @@ public class OMXInstance { } eglContext = eglCtx.getHandle(); eglDisplay = eglDrawable.getDisplay(); - eglSurface = eglDrawable.getSurface(); + eglSurface = eglDrawable.getHandle(); eglExt = eglCtx.getEGLExt(); if(null==eglExt) { throw new RuntimeException("No valid EGLExt"); diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index efc914de9..21c1b96a0 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -278,10 +278,17 @@ public abstract class GLContext { /** * Classname, GL, GLDrawable */ - public final String toString() { + public String toString() { StringBuffer sb = new StringBuffer(); sb.append(getClass().getName()); - sb.append(" [OpenGL "); + sb.append(" ["); + this.append(sb); + sb.append("] "); + return sb.toString(); + } + + public final StringBuffer append(StringBuffer sb) { + sb.append("OpenGL "); sb.append(getGLVersionMajor()); sb.append("."); sb.append(getGLVersionMinor()); @@ -289,6 +296,8 @@ public abstract class GLContext { sb.append(Integer.toHexString(ctxOptions)); sb.append(", "); sb.append(getGLVersion()); + sb.append(", handle "); + sb.append(toHexString(contextHandle)); sb.append(", "); sb.append(getGL()); if(getGLDrawable()!=getGLDrawableRead()) { @@ -300,8 +309,7 @@ public abstract class GLContext { sb.append(",\n\tDrawable Read/Write: "); sb.append(getGLDrawable()); } - sb.append("] "); - return sb.toString(); + return sb; } /** Returns a non-null (but possibly empty) string containing the diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java index 469cc5170..46296ca52 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java @@ -157,6 +157,15 @@ public interface GLDrawable { public NativeWindow getNativeWindow(); + /** + * This is the GL/Windowing drawable handle.<br> + * It is usually the {@link javax.media.nativewindow.NativeWindow#getSurfaceHandle()}, + * ie the native surface handle of the underlying windowing toolkit.<br> + * However, on X11/GLX this reflects a GLXDrawable, which represents a GLXWindow, GLXPixmap, or GLXPbuffer.<br> + * On EGL, this represents the EGLSurface.<br> + */ + public long getHandle(); + public GLDrawableFactory getFactory(); public String toString(); diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index ca6bc7564..81c7d4b4a 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -95,20 +95,9 @@ public abstract class GLDrawableFactory { * Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones. */ static { - GLDrawableFactory tmp = null; - try { - tmp = (GLDrawableFactory) ReflectionUtil.createInstance("com.jogamp.opengl.impl.egl.EGLDrawableFactory"); - } catch (JogampRuntimeException jre) { - if (GLProfile.DEBUG) { - System.err.println("GLDrawableFactory.static - EGLDrawableFactory - not available"); - jre.printStackTrace(); - } - } - eglFactory = tmp; - nativeOSType = NativeWindowFactory.getNativeWindowType(true); - tmp = null; + GLDrawableFactory tmp = null; String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true, AccessController.getContext()); if (null == factoryClassName) { if ( nativeOSType.equals(NativeWindowFactory.TYPE_X11) ) { @@ -142,6 +131,17 @@ public abstract class GLDrawableFactory { } } nativeOSFactory = tmp; + + tmp = null; + try { + tmp = (GLDrawableFactory) ReflectionUtil.createInstance("com.jogamp.opengl.impl.egl.EGLDrawableFactory"); + } catch (JogampRuntimeException jre) { + if (GLProfile.DEBUG) { + System.err.println("GLDrawableFactory.static - EGLDrawableFactory - not available"); + jre.printStackTrace(); + } + } + eglFactory = tmp; } /** diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 88eac0a92..3d0f4a3ce 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -40,8 +40,10 @@ import com.jogamp.common.util.*; import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.impl.GLJNILibLoader; import com.jogamp.opengl.impl.GLDrawableFactoryImpl; -import com.jogamp.opengl.impl.egl.EGLDynamicLookupHelper; +import com.jogamp.opengl.impl.GLDynamicLookupHelper; +import com.jogamp.opengl.impl.GLDynamicLibraryBundleInfo; import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper; +import com.jogamp.opengl.impl.DesktopGLDynamicLibraryBundleInfo; import com.jogamp.common.jvm.JVMUtil; import java.util.HashMap; import java.util.Iterator; @@ -860,7 +862,7 @@ public class GLProfile implements Cloneable { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { - JVMUtil.initSingleton(); + NativeWindowFactory.initSingleton(); AccessControlContext acc = AccessController.getContext(); @@ -895,9 +897,11 @@ public class GLProfile implements Cloneable { GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2); hasNativeOSFactory = null != factory; if(hasNativeOSFactory) { - DesktopGLDynamicLookupHelper deskGLLookupHelper = (DesktopGLDynamicLookupHelper) factory.getGLDynamicLookupHelper(0); - hasDesktopGL = deskGLLookupHelper.hasGLBinding(); - hasDesktopGLES12 = deskGLLookupHelper.hasGLES12Binding(); + DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) factory.getGLDynamicLookupHelper(0); + if(null!=glLookupHelper) { + hasDesktopGL = glLookupHelper.hasGLBinding(); + hasDesktopGLES12 = glLookupHelper.hasGLES12Binding(); + } } } catch (LinkageError le) { t=le; @@ -937,18 +941,18 @@ public class GLProfile implements Cloneable { hasGL2ES12Impl = hasGL2ES12Impl && GLContext.isGL2Available(); } - if ( ReflectionUtil.isClassAvailable("com.jogamp.opengl.impl.egl.EGLDynamicLookupHelper") ) { + if ( ReflectionUtil.isClassAvailable("com.jogamp.opengl.impl.egl.EGLDrawableFactory") ) { t=null; try { GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2); if(null != factory) { - EGLDynamicLookupHelper eglLookupHelper = (EGLDynamicLookupHelper) factory.getGLDynamicLookupHelper(2); + GLDynamicLookupHelper eglLookupHelper = factory.getGLDynamicLookupHelper(2); if(null!=eglLookupHelper) { - hasGLES2Impl = eglLookupHelper.hasESBinding(); + hasGLES2Impl = eglLookupHelper.isLibComplete(); } - eglLookupHelper = (EGLDynamicLookupHelper) factory.getGLDynamicLookupHelper(1); + eglLookupHelper = factory.getGLDynamicLookupHelper(1); if(null!=eglLookupHelper) { - hasGLES1Impl = eglLookupHelper.hasESBinding(); + hasGLES1Impl = eglLookupHelper.isLibComplete(); } } } catch (LinkageError le) { @@ -991,6 +995,15 @@ public class GLProfile implements Cloneable { } } + /** + * It is mandatory to call this methods ASAP, before anything else.<br> + * You may issue the call in your main class static initializer block, or in the static main function.<br> + * This will kick off JOGL's static initialization.<br> + * It is essential to do this at the very beginning, so JOGL has a chance to initialize multithreading support.<br> + */ + public static void initSingleton() { + } + private static final String list2String(String[] list) { StringBuffer msg = new StringBuffer(); msg.append("["); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index be42e1da1..77b8e45d3 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -44,6 +44,7 @@ import javax.media.nativewindow.*; import javax.media.nativewindow.awt.*; import com.jogamp.opengl.impl.*; +import com.jogamp.nativewindow.impl.jawt.JAWTUtil; import java.awt.Canvas; import java.awt.Color; @@ -73,9 +74,15 @@ import java.security.*; public class GLCanvas extends Canvas implements AWTGLAutoDrawable { - private static final boolean DEBUG = Debug.debug("GLCanvas"); + private static final boolean DEBUG; + private static final GLProfile defaultGLProfile; + + static { + NativeWindowFactory.initSingleton(); + defaultGLProfile = GLProfile.getDefault(); + DEBUG = Debug.debug("GLCanvas"); + } - static private GLProfile defaultGLProfile = GLProfile.getDefault(); private GLProfile glProfile; private GLDrawableHelper drawableHelper = new GLDrawableHelper(); private GraphicsConfiguration chosen; @@ -396,22 +403,27 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { /* * Save the chosen capabilities for use in getGraphicsConfiguration(). */ - awtConfig = chooseGraphicsConfiguration(capabilities, chooser, device); - if(DEBUG) { - Exception e = new Exception("Created Config: "+awtConfig); - e.printStackTrace(); - } - if(null!=awtConfig) { - // update .. - chosen = awtConfig.getGraphicsConfiguration(); + JAWTUtil.lockToolkit(); + try { + awtConfig = chooseGraphicsConfiguration(capabilities, chooser, device); + if(DEBUG) { + Exception e = new Exception("Created Config: "+awtConfig); + e.printStackTrace(); + } + if(null!=awtConfig) { + // update .. + chosen = awtConfig.getGraphicsConfiguration(); + } + if(null==awtConfig) { + throw new GLException("Error: AWTGraphicsConfiguration is null"); + } + drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); + context = (GLContextImpl) drawable.createContext(shareWith); + context.setSynchronized(true); + } finally { + JAWTUtil.unlockToolkit(); } - if(null==awtConfig) { - throw new GLException("Error: AWTGraphicsConfiguration is null"); - } - drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); - context = (GLContextImpl) drawable.createContext(shareWith); - context.setSynchronized(true); if(DEBUG) { System.err.println("Created Drawable: "+drawable); @@ -538,6 +550,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { return drawable.getNativeWindow(); } + public long getHandle() { + return drawable.getHandle(); + } + public GLDrawableFactory getFactory() { return drawable.getFactory(); } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 61e1429b6..955949415 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -137,6 +137,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { private int viewportY; static { + NativeWindowFactory.initSingleton(); + // Force eager initialization of part of the Java2D class since // otherwise it's likely it will try to be initialized while on // the Queue Flusher Thread, which is not allowed @@ -469,6 +471,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { throw new GLException("FIXME"); } + public long getHandle() { + throw new GLException("FIXME"); + } + public final GLDrawableFactory getFactory() { return factory; } diff --git a/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java index 48388d4e9..16f42053b 100755 --- a/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java @@ -47,6 +47,9 @@ import com.jogamp.newt.*; import java.io.IOException; public class TestGLProfile01NEWT { + static { + GLProfile.initSingleton(); + } static GLProfile glp; @BeforeClass @@ -93,7 +96,7 @@ public class TestGLProfile01NEWT { } @Test - public void test02GLProfileMaxProgrammable() { + public void test03GLProfileMaxProgrammable() { // Assuming at least one programmable profile is available GLProfile glp = GLProfile.getMaxProgrammable(); System.out.println("GLProfile <static> getMaxProgrammable(): "+glp); @@ -118,6 +121,28 @@ public class TestGLProfile01NEWT { dumpVersion(glp); } + @Test + public void test04GLProfileGL2ES1() { + if(!GLProfile.isGL2ES1Available()) { + System.out.println("GLProfile GL2ES1 n/a"); + return; + } + GLProfile glp = GLProfile.getGL2ES1(); + System.out.println("GLProfile <static> GL2ES1: "+glp); + dumpVersion(glp); + } + + @Test + public void test05GLProfileGL2ES2() { + if(!GLProfile.isGL2ES2Available()) { + System.out.println("GLProfile GL2ES2 n/a"); + return; + } + GLProfile glp = GLProfile.getGL2ES2(); + System.out.println("GLProfile <static> GL2ES2: "+glp); + dumpVersion(glp); + } + protected void dumpVersion(GLProfile glp) { GLCapabilities caps = new GLCapabilities(glp); GLWindow glWindow = GLWindow.create(caps, false); diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java index 9aec605be..4fd7744db 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java @@ -180,13 +180,23 @@ public class TestGLWindows01NEWT { public void testWindowDecor03TwoWin() throws InterruptedException { GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - Display display = NewtFactory.createDisplay(null); // local display - Assert.assertNotNull(display); - Screen screen = NewtFactory.createScreen(display, 0); // screen 0 - Assert.assertNotNull(screen); - GLWindow window1 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); - GLWindow window2 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + Display display1 = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display1); + Display display2 = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display2); + Assert.assertEquals(display1, display2); // must be equal: same thread - same display + + Screen screen1 = NewtFactory.createScreen(display1, 0); // screen 0 + Assert.assertNotNull(screen1); + GLWindow window1 = createWindow(screen1, caps, width, height, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window1); + + Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0 + Assert.assertNotNull(screen2); + GLWindow window2 = createWindow(screen2, caps, width, height, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window2); + Animator animator1 = new Animator(window1); animator1.start(); Animator animator2 = new Animator(window2); @@ -194,9 +204,13 @@ public class TestGLWindows01NEWT { while(animator1.isAnimating() && animator1.getDuration()<duration) { Thread.sleep(100); } + animator2.stop(); + Assert.assertEquals(false, animator2.isAnimating()); + destroyWindow(window2, true); + animator1.stop(); - destroyWindow(window2, false); + Assert.assertEquals(false, animator1.isAnimating()); destroyWindow(window1, true); } diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java index 87d0288b3..2c695f788 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java @@ -94,7 +94,7 @@ public class TestParenting01AWT { GLEventListener demo1 = new RedSquare(); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.setSize(600, 300); + // glWindow1.setSize(600, 300); NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); Assert.assertNotNull(newtCanvasAWT); @@ -106,7 +106,7 @@ public class TestParenting01AWT { Assert.assertNotNull(frame); frame.add(newtCanvasAWT); frame.setSize(width, height); - frame.pack(); + // frame.pack(); // visible test frame.setVisible(true); @@ -127,14 +127,14 @@ public class TestParenting01AWT { Assert.assertEquals(false, glWindow1.isDestroyed()); frame.remove(newtCanvasAWT); - Assert.assertNull(glWindow1.getParentNativeWindow()); + // Assert.assertNull(glWindow1.getParentNativeWindow()); Assert.assertEquals(false, glWindow1.isDestroyed()); frame.dispose(); Assert.assertEquals(false, glWindow1.isDestroyed()); glWindow1.destroy(true); - Assert.assertEquals(true, glWindow1.isDestroyed()); + //Assert.assertEquals(true, glWindow1.isDestroyed()); } @Test @@ -152,7 +152,7 @@ public class TestParenting01AWT { GLEventListener demo1 = new RedSquare(); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.setSize(600, 300); + // glWindow1.setSize(600, 300); NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); Assert.assertNotNull(newtCanvasAWT); @@ -169,7 +169,7 @@ public class TestParenting01AWT { frame.add(newtCanvasAWT); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); - frame.pack(); + // frame.pack(); Animator animator1 = new Animator(glWindow1); animator1.start(); @@ -184,6 +184,43 @@ public class TestParenting01AWT { } @Test + public void testWindowParenting02CreateVisibleDestroy3Odd() throws InterruptedException { + int x = 0; + int y = 0; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + GLWindow glWindow1 = GLWindow.create(glCaps); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + // glWindow1.setSize(600, 300); + + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + + Frame frame = new Frame("AWT Parent Frame"); + Assert.assertNotNull(frame); + frame.setSize(width, height); + + // visible test + frame.setVisible(true); + + frame.add(newtCanvasAWT); + // frame.pack(); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { + Thread.sleep(100); + } + + Assert.assertEquals(true, animator1.isAnimating()); // !!! + + frame.dispose(); + glWindow1.destroy(true); + } + + @Test public void testWindowParenting03ReparentNewtWin2Top() throws InterruptedException { int x = 0; int y = 0; @@ -194,7 +231,7 @@ public class TestParenting01AWT { GLEventListener demo1 = new RedSquare(); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.setSize(600, 300); + // glWindow1.setSize(600, 300); NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); @@ -205,7 +242,7 @@ public class TestParenting01AWT { frame.add(newtCanvasAWT); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); - frame.pack(); + // frame.pack(); Animator animator1 = new Animator(glWindow1); animator1.start(); @@ -228,6 +265,9 @@ public class TestParenting01AWT { state++; } + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + frame.dispose(); glWindow1.destroy(true); } @@ -243,7 +283,7 @@ public class TestParenting01AWT { GLEventListener demo1 = new RedSquare(); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.setSize(600, 300); + // glWindow1.setSize(600, 300); NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); @@ -259,7 +299,7 @@ public class TestParenting01AWT { frame.add(newtCanvasAWT, BorderLayout.CENTER); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); - frame.pack(); + // frame.pack(); Animator animator1 = new Animator(glWindow1); animator1.start(); @@ -282,6 +322,9 @@ public class TestParenting01AWT { state++; } + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + frame.dispose(); glWindow1.destroy(true); } @@ -293,11 +336,11 @@ public class TestParenting01AWT { NEWTEventFiFo eventFifo = new NEWTEventFiFo(); - GLWindow glWindow1 = GLWindow.create(glCaps); + GLWindow glWindow1 = GLWindow.create(glCaps, true); GLEventListener demo1 = new RedSquare(); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.setSize(600, 300); + // glWindow1.setSize(600, 300); NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); @@ -323,7 +366,7 @@ public class TestParenting01AWT { frame1.add(newtCanvasAWT, BorderLayout.CENTER); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); - frame1.pack(); + // frame1.pack(); Animator animator1 = new Animator(glWindow1); animator1.start(); @@ -335,17 +378,20 @@ public class TestParenting01AWT { case 0: frame1.remove(newtCanvasAWT); frame2.add(newtCanvasAWT, BorderLayout.CENTER); - frame2.pack(); + //frame2.pack(); break; case 1: frame2.remove(newtCanvasAWT); frame1.add(newtCanvasAWT, BorderLayout.CENTER); - frame1.pack(); + //frame1.pack(); break; } state++; } + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + frame1.dispose(); frame2.dispose(); glWindow1.destroy(true); diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java index 37de52139..f87ce1111 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java @@ -196,10 +196,16 @@ public class TestParenting01NEWT { state++; } animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); animator2.stop(); + Assert.assertEquals(false, animator2.isAnimating()); glWindow1.destroy(true); + Assert.assertEquals(true, glWindow1.isDestroyed()); + Assert.assertEquals(false, glWindow2.isDestroyed()); glWindow2.destroy(true); + Assert.assertEquals(true, glWindow1.isDestroyed()); + Assert.assertEquals(true, glWindow2.isDestroyed()); } @Test @@ -249,9 +255,16 @@ public class TestParenting01NEWT { state++; } animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); animator2.stop(); + Assert.assertEquals(false, animator2.isAnimating()); glWindow1.destroy(true); + Assert.assertEquals(true, glWindow1.isDestroyed()); + Assert.assertEquals(true, glWindow2.isDestroyed()); + glWindow2.destroy(true); + Assert.assertEquals(true, glWindow1.isDestroyed()); + Assert.assertEquals(true, glWindow2.isDestroyed()); } public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { diff --git a/src/junit/com/jogamp/test/junit/newt/TestParentingAWT.java b/src/junit/com/jogamp/test/junit/newt/TestParentingAWT.java new file mode 100755 index 000000000..c42599810 --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestParentingAWT.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2010 Sven Gothel. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Sven Gothel or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.jogamp.test.junit.newt; + +import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; + +import java.awt.Button; +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Frame; +import java.awt.Dimension; + +import javax.media.opengl.*; +import javax.media.nativewindow.*; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.newt.*; +import com.jogamp.newt.event.*; +import com.jogamp.newt.opengl.*; +import com.jogamp.newt.awt.NewtCanvasAWT; + +import java.io.IOException; + +import com.jogamp.test.junit.util.*; +import com.jogamp.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; + +public class TestParentingAWT { + static int width, height; + static long durationPerTest = 800; + static long waitReparent = 0; + static GLCapabilities glCaps; + + @BeforeClass + public static void initClass() { + width = 640; + height = 480; + glCaps = new GLCapabilities(null); + } + + @Test + public void testWindowParenting05ReparentAWTWinHopFrame2Frame() throws InterruptedException { + int x = 0; + int y = 0; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + GLWindow glWindow1 = GLWindow.create(glCaps, true); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + + Frame frame1 = new Frame("AWT Parent Frame"); + frame1.setLayout(new BorderLayout()); + frame1.add(new Button("North"), BorderLayout.NORTH); + frame1.add(new Button("South"), BorderLayout.SOUTH); + frame1.add(new Button("East"), BorderLayout.EAST); + frame1.add(new Button("West"), BorderLayout.WEST); + frame1.setSize(width, height); + frame1.setLocation(0, 0); + frame1.setVisible(true); + + Frame frame2 = new Frame("AWT Parent Frame"); + frame2.setLayout(new BorderLayout()); + frame2.add(new Button("North"), BorderLayout.NORTH); + frame2.add(new Button("South"), BorderLayout.SOUTH); + frame2.add(new Button("East"), BorderLayout.EAST); + frame2.add(new Button("West"), BorderLayout.WEST); + frame2.setSize(width, height); + frame2.setLocation(640, 480); + frame2.setVisible(true); + + frame1.add(newtCanvasAWT, BorderLayout.CENTER); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + + int state = 0; + while(animator1.isAnimating() && animator1.getDuration()<3*durationPerTest) { + Thread.sleep(durationPerTest); + switch(state) { + case 0: + frame1.remove(newtCanvasAWT); + frame2.add(newtCanvasAWT, BorderLayout.CENTER); + break; + case 1: + frame2.remove(newtCanvasAWT); + frame1.add(newtCanvasAWT, BorderLayout.CENTER); + break; + } + state++; + } + + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + + frame1.dispose(); + frame2.dispose(); + glWindow1.destroy(true); + } + + public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { + Assert.assertNotNull(demo); + Assert.assertNotNull(glWindow); + Window window = glWindow.getInnerWindow(); + if(debug) { + MiscUtils.setFieldIfExists(demo, "glDebug", true); + MiscUtils.setFieldIfExists(demo, "glTrace", true); + } + if(!MiscUtils.setFieldIfExists(demo, "window", window)) { + MiscUtils.setFieldIfExists(demo, "glWindow", glWindow); + } + } + + static int atoi(String a) { + int i=0; + try { + durationPerTest = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + durationPerTest = atoi(args[++i]); + } else if(args[i].equals("-wait")) { + waitReparent = atoi(args[++i]); + } + } + String tstname = TestParentingAWT.class.getName(); + org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { + tstname, + "filtertrace=true", + "haltOnError=false", + "haltOnFailure=false", + "showoutput=true", + "outputtoformatters=true", + "logfailedtests=true", + "logtestlistenerevents=true", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); + } + +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/InternalBufferUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/InternalBufferUtil.java deleted file mode 100644 index f590e9b8b..000000000 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/InternalBufferUtil.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package com.jogamp.nativewindow.impl; - -import java.lang.reflect.*; -import java.nio.*; - -/** Internal copy of selected routines from BufferUtil to avoid - outward dependencies on com.jogamp.opengl.util package. */ -public class InternalBufferUtil { - public static final int SIZEOF_BYTE = 1; - public static final int SIZEOF_SHORT = 2; - public static final int SIZEOF_INT = 4; - public static final int SIZEOF_FLOAT = 4; - - //---------------------------------------------------------------------- - // Allocation routines - // - - /** Allocates a new direct ByteBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static ByteBuffer newByteBuffer(int numElements) { - ByteBuffer bb = ByteBuffer.allocateDirect(numElements); - nativeOrder(bb); - return bb; - } - - /** Allocates a new direct IntBuffer with the specified number of - elements. The returned buffer will have its byte order set to - the host platform's native byte order. */ - public static IntBuffer newIntBuffer(int numElements) { - ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT); - return bb.asIntBuffer(); - } - - //---------------------------------------------------------------------- - // Copy routines (type-to-type) - // - - /** Copies the <i>remaining</i> elements (as defined by - <code>limit() - position()</code>) in the passed ByteBuffer into - a newly-allocated direct ByteBuffer. The returned buffer will - have its byte order set to the host platform's native byte - order. The position of the newly-allocated buffer will be zero, - and the position of the passed buffer is unchanged (though its - mark is changed). */ - public static ByteBuffer copyByteBuffer(ByteBuffer orig) { - ByteBuffer dest = newByteBuffer(orig.remaining()); - dest.put(orig); - dest.rewind(); - return dest; - } - - //---------------------------------------------------------------------- - // Conversion routines - // - - public static ByteBuffer nativeOrder(ByteBuffer buf) { - if (!isCDCFP) { - try { - if (byteOrderClass == null) { - byteOrderClass = Class.forName("java.nio.ByteOrder"); - orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass }); - Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null); - nativeOrderObject = nativeOrderMethod.invoke(null, null); - } - } catch (Throwable t) { - // Must be running on CDC / FP - isCDCFP = true; - } - - if (!isCDCFP) { - try { - orderMethod.invoke(buf, new Object[] { nativeOrderObject }); - } catch (Throwable t) { - } - } - } - return buf; - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - // NOTE that this work must be done reflectively at the present time - // because this code must compile and run correctly on both CDC/FP and J2SE - private static boolean isCDCFP; - private static Class byteOrderClass; - private static Object nativeOrderObject; - private static Method orderMethod; -} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java deleted file mode 100644 index 203ae3d12..000000000 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -package com.jogamp.nativewindow.impl; - -import javax.media.nativewindow.*; - -public class LockingNativeWindowFactory extends NativeWindowFactoryImpl { - private ToolkitLock toolkitLock = new RecursiveToolkitLock(); - - public ToolkitLock getToolkitLock() { - return toolkitLock; - } -} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java index 6233bf533..8cf02965b 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java @@ -99,17 +99,4 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory { throw (IllegalArgumentException) new IllegalArgumentException().initCause(ie); } } - - // On most platforms the toolkit lock is a no-op - private ToolkitLock toolkitLock = new ToolkitLock() { - public void lock() { - } - - public void unlock() { - } - }; - - public ToolkitLock getToolkitLock() { - return toolkitLock; - } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullWindow.java index a1c2b594c..7c446addc 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NullWindow.java @@ -37,9 +37,10 @@ package com.jogamp.nativewindow.impl; import javax.media.nativewindow.*; +import com.jogamp.nativewindow.impl.RecursiveToolkitLock; public class NullWindow implements NativeWindow, SurfaceChangeable { - private Exception lockedStack = null; + private RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); protected int width, height, scrnIndex; protected long surfaceHandle, displayHandle; protected AbstractGraphicsConfiguration config; @@ -68,28 +69,20 @@ public class NullWindow implements NativeWindow, SurfaceChangeable { } public synchronized int lockSurface() throws NativeWindowException { - if (null!=lockedStack) { - lockedStack.printStackTrace(); - throw new NativeWindowException("Surface already locked - "+this); - } - lockedStack = new Exception("NullWindow previously locked by "+Thread.currentThread().getName()); + recurLock.lock(); return LOCK_SUCCESS; } public synchronized void unlockSurface() { - if (null!=lockedStack) { - lockedStack = null; - } else { - throw new NativeWindowException("NullWindow not locked"); - } + recurLock.unlock(); } public synchronized boolean isSurfaceLocked() { - return null!=lockedStack; + return recurLock.isLocked(); } public Exception getLockedStack() { - return lockedStack; + return recurLock.getLockedStack(); } public boolean surfaceSwap() { diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java index 52c211615..236ef0754 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java @@ -5,11 +5,12 @@ import javax.media.nativewindow.*; // // Reentrance locking toolkit // -public class RecursiveToolkitLock implements ToolkitLock { +public class RecursiveToolkitLock { private Thread owner = null; private int recursionCount = 0; private Exception lockedStack = null; private static final long timeout = 3000; // maximum wait 3s + private static final boolean TRACE_LOCK = false; public Exception getLockedStack() { return lockedStack; @@ -35,11 +36,27 @@ public class RecursiveToolkitLock implements ToolkitLock { return recursionCount; } + public synchronized void validateLocked() { + if ( !isLocked() ) { + throw new RuntimeException(Thread.currentThread()+": Not locked"); + } + if ( !isOwner() ) { + getLockedStack().printStackTrace(); + throw new RuntimeException(Thread.currentThread()+": Not owner, owner is "+owner); + } + } + /** Recursive and blocking lockSurface() implementation */ public synchronized void lock() { Thread cur = Thread.currentThread(); + if(TRACE_LOCK) { + System.out.println("... LOCK 0 ["+this+"], recursions "+recursionCount+", "+cur); + } if (owner == cur) { ++recursionCount; + if(TRACE_LOCK) { + System.out.println("+++ LOCK 1 ["+this+"], recursions "+recursionCount+", "+cur); + } return; } @@ -55,6 +72,9 @@ public class RecursiveToolkitLock implements ToolkitLock { lockedStack.printStackTrace(); throw new RuntimeException("Waited "+timeout+"ms for: "+owner+" - "+cur+", with recursionCount "+recursionCount+", lock: "+this); } + if(TRACE_LOCK) { + System.out.println("+++ LOCK X ["+this+"], recursions "+recursionCount+", "+cur); + } owner = cur; lockedStack = new Exception("Previously locked by "+owner+", lock: "+this); } @@ -67,13 +87,13 @@ public class RecursiveToolkitLock implements ToolkitLock { /** Recursive and unblocking unlockSurface() implementation */ public synchronized void unlock(Runnable taskAfterUnlockBeforeNotify) { - Thread cur = Thread.currentThread(); - if (owner != cur) { - lockedStack.printStackTrace(); - throw new RuntimeException(cur+": Not owner, owner is "+owner); - } + validateLocked(); + if (recursionCount > 0) { --recursionCount; + if(TRACE_LOCK) { + System.out.println("--- LOCK 1 ["+this+"], recursions "+recursionCount+", "+Thread.currentThread()); + } return; } owner = null; @@ -81,6 +101,9 @@ public class RecursiveToolkitLock implements ToolkitLock { if(null!=taskAfterUnlockBeforeNotify) { taskAfterUnlockBeforeNotify.run(); } + if(TRACE_LOCK) { + System.out.println("--- LOCK X ["+this+"], recursions "+recursionCount+", "+Thread.currentThread()); + } notifyAll(); } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java index 527d7750d..d7c690fc6 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java @@ -64,7 +64,6 @@ public class JAWTUtil { JAWTJNILibLoader.loadAWTImpl(); JAWTJNILibLoader.loadNativeWindow("awt"); - lockedStack = null; headlessMode = GraphicsEnvironment.isHeadless(); boolean ok=false; @@ -108,11 +107,10 @@ public class JAWTUtil { useSunToolkitAWTLock = false; } - private static Exception lockedStack; + public static void initSingleton() { + // just exist to ensure static init has been run + } - // Just a hook to let this class being initialized, - // ie loading the native libraries .. - public static void init() { } public static final boolean hasJava2D() { return j2dExist; @@ -156,47 +154,36 @@ public class JAWTUtil { } } - public static synchronized void lockToolkit() throws NativeWindowException { - if (isJava2DQueueFlusherThread()) return; + private static RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); - if (null!=lockedStack) { - lockedStack.printStackTrace(); - throw new NativeWindowException("JAWT Toolkit already locked - "+Thread.currentThread().getName()); - } - lockedStack = new Exception("JAWT Toolkit already locked by: "+Thread.currentThread().getName()); + public static synchronized void lockToolkit() throws NativeWindowException { + recurLock.lock(); - if (headlessMode) { - // Workaround for running (to some degree) in headless - // environments but still supporting rendering via pbuffers - // For full correctness, would need to implement a Lock class - return; + if(recurLock.getRecursionCount()==0 && + !isJava2DQueueFlusherThread() && + !headlessMode) { + awtLock(); } - - awtLock(); } public static synchronized void unlockToolkit() { - if (isJava2DQueueFlusherThread()) return; - - if (null!=lockedStack) { - lockedStack = null; - if (headlessMode) { - // Workaround for running (to some degree) in headless - // environments but still supporting rendering via pbuffers - // For full correctness, would need to implement a Lock class - return; - } + recurLock.validateLocked(); + if(recurLock.getRecursionCount()==0 && + !isJava2DQueueFlusherThread() && + !headlessMode) { awtUnlock(); } + + recurLock.unlock(); } public static boolean isToolkitLocked() { - return null!=lockedStack; + return recurLock.isLocked(); } public static Exception getLockedStack() { - return lockedStack; + return recurLock.getLockedStack(); } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java index 68e61cd85..a59b34eb0 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java @@ -101,45 +101,37 @@ public abstract class JAWTWindow implements NativeWindow { bounds.setHeight(jawtBounds.getHeight()); } - private volatile Exception lockedStack = null; + private RecursiveToolkitLock recurLock = new RecursiveToolkitLock(); protected abstract int lockSurfaceImpl() throws NativeWindowException; public final synchronized int lockSurface() throws NativeWindowException { - // We have to be the owner of the JAWT ToolkitLock 'lock' to benefit from it's - // recursive and blocking lock capabitlites. - // Otherwise a followup ToolkitLock would deadlock, - // since we already have locked JAWT with the surface lock. - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - - // recursion not necessary here, due to the blocking ToolkitLock .. - if (null!=lockedStack) { - lockedStack.printStackTrace(); - throw new NativeWindowException("JAWT Surface already locked - "+Thread.currentThread().getName()+" "+this); + recurLock.lock(); + + if(recurLock.getRecursionCount() == 0) { + return lockSurfaceImpl(); } - lockedStack = new Exception("JAWT Surface previously locked by "+Thread.currentThread().getName()); - return lockSurfaceImpl(); + return LOCK_SUCCESS; } protected abstract void unlockSurfaceImpl() throws NativeWindowException; public synchronized void unlockSurface() { - if (null!=lockedStack) { - lockedStack = null; - } else { - throw new NativeWindowException("JAWT Surface not locked"); + recurLock.validateLocked(); + + if(recurLock.getRecursionCount()==0) { + unlockSurfaceImpl(); } - unlockSurfaceImpl(); - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + recurLock.unlock(); } public synchronized boolean isSurfaceLocked() { - return null!=lockedStack; + return recurLock.isLocked(); } public Exception getLockedStack() { - return lockedStack; + return recurLock.getLockedStack(); } public boolean surfaceSwap() { diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java index f7151d9f1..c74a62b7e 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java @@ -56,74 +56,83 @@ public class X11JAWTWindow extends JAWTWindow { protected void initNative() throws NativeWindowException { if(0==config.getScreen().getDevice().getHandle()) { AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice(); - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice()); - if(0==displayHandle) { - displayHandle = X11Util.createThreadLocalDefaultDisplay(); - } - awtDevice.setHandle(displayHandle); - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice()); + if(0==displayHandle) { + displayHandle = X11Util.createThreadLocalDisplay(null); } + awtDevice.setHandle(displayHandle); } } protected int lockSurfaceImpl() throws NativeWindowException { - int ret = NativeWindow.LOCK_SUCCESS; - ds = JAWT.getJAWT().GetDrawingSurface(component); - if (ds == null) { - // Widget not yet realized - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } - int res = ds.Lock(); - dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; - if (!dsLocked) { - unlockSurface(); - throw new NativeWindowException("Unable to lock surface"); - } - // See whether the surface changed and if so destroy the old - // OpenGL context so it will be recreated (NOTE: removeNotify - // should handle this case, but it may be possible that race - // conditions can cause this code to be triggered -- should test - // more) - if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { - ret = LOCK_SURFACE_CHANGED; - } - dsi = ds.GetDrawingSurfaceInfo(); - if (dsi == null) { - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } - x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(); - if (x11dsi == null) { - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } - drawable = x11dsi.getDrawable(); - if (drawable == 0) { - unlockSurface(); - return LOCK_SURFACE_NOT_READY; - } else { - updateBounds(dsi.getBounds()); + // JAWTUtil.lockToolkit(); + // config.getNativeGraphicsConfiguration().getScreen().getDevice().lock(); + try { + int ret = NativeWindow.LOCK_SUCCESS; + ds = JAWT.getJAWT().GetDrawingSurface(component); + if (ds == null) { + // Widget not yet realized + unlockSurface(); + return LOCK_SURFACE_NOT_READY; + } + int res = ds.Lock(); + dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; + if (!dsLocked) { + unlockSurface(); + throw new NativeWindowException("Unable to lock surface"); + } + // See whether the surface changed and if so destroy the old + // OpenGL context so it will be recreated (NOTE: removeNotify + // should handle this case, but it may be possible that race + // conditions can cause this code to be triggered -- should test + // more) + if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { + ret = LOCK_SURFACE_CHANGED; + } + dsi = ds.GetDrawingSurfaceInfo(); + if (dsi == null) { + unlockSurface(); + return LOCK_SURFACE_NOT_READY; + } + x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(); + if (x11dsi == null) { + unlockSurface(); + return LOCK_SURFACE_NOT_READY; + } + drawable = x11dsi.getDrawable(); + if (drawable == 0) { + unlockSurface(); + return LOCK_SURFACE_NOT_READY; + } else { + updateBounds(dsi.getBounds()); + } + return ret; + } finally { + // config.getNativeGraphicsConfiguration().getScreen().getDevice().unlock(); + // JAWTUtil.unlockToolkit(); } - return ret; } protected void unlockSurfaceImpl() throws NativeWindowException { - if(null!=ds) { - if (null!=dsi) { - ds.FreeDrawingSurfaceInfo(dsi); - } - if (dsLocked) { - ds.Unlock(); + // JAWTUtil.lockToolkit(); + // config.getNativeGraphicsConfiguration().getScreen().getDevice().lock(); + try { + if(null!=ds) { + if (null!=dsi) { + ds.FreeDrawingSurfaceInfo(dsi); + } + if (dsLocked) { + ds.Unlock(); + } + JAWT.getJAWT().FreeDrawingSurface(ds); } - JAWT.getJAWT().FreeDrawingSurface(ds); + ds = null; + dsi = null; + x11dsi = null; + } finally { + // config.getNativeGraphicsConfiguration().getScreen().getDevice().unlock(); + // JAWTUtil.unlockToolkit(); } - ds = null; - dsi = null; - x11dsi = null; } // Variables for lockSurface/unlockSurface diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java index 0cd02558a..fbf4524a4 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java @@ -58,19 +58,13 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor int num[] = { -1 }; long display = screen.getDevice().getHandle(); - X11Util.XLockDisplay(display); - try { - XVisualInfo[] xvis = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0); + XVisualInfo[] xvis = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0); - if(xvis==null || num[0]<1) { - return null; - } - - return XVisualInfo.create(xvis[0]); - } finally { - X11Util.XUnlockDisplay(display); + if(xvis==null || num[0]<1) { + return null; } + return XVisualInfo.create(xvis[0]); } public static XVisualInfo getXVisualInfo(AbstractGraphicsScreen screen, Capabilities capabilities) @@ -90,29 +84,24 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor vinfo_template.setC_class(c_class); long display = screen.getDevice().getHandle(); - X11Util.XLockDisplay(display); - try { - XVisualInfo[] vinfos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, vinfo_template, num, 0); - XVisualInfo best=null; - int rdepth = capabilities.getRedBits() + capabilities.getGreenBits() + capabilities.getBlueBits() + capabilities.getAlphaBits(); - for (int i = 0; vinfos!=null && i < num[0]; i++) { - if ( best == null || - best.getDepth() < vinfos[i].getDepth() ) - { - best = vinfos[i]; - if(rdepth <= best.getDepth()) - break; - } - } - if ( null!=best && ( rdepth <= best.getDepth() || 24 == best.getDepth()) ) { - ret = XVisualInfo.create(best); + XVisualInfo[] vinfos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0); + XVisualInfo best=null; + int rdepth = capabilities.getRedBits() + capabilities.getGreenBits() + capabilities.getBlueBits() + capabilities.getAlphaBits(); + for (int i = 0; vinfos!=null && i < num[0]; i++) { + if ( best == null || + best.getDepth() < vinfos[i].getDepth() ) + { + best = vinfos[i]; + if(rdepth <= best.getDepth()) + break; } - best = null; - - return ret; - } finally { - X11Util.XUnlockDisplay(display); } + if ( null!=best && ( rdepth <= best.getDepth() || 24 == best.getDepth()) ) { + ret = XVisualInfo.create(best); + } + best = null; + + return ret; } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java index 6e3c62d3b..924185210 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java @@ -52,7 +52,6 @@ import com.jogamp.nativewindow.impl.*; */ public class X11Util { private static final boolean DEBUG = Debug.debug("X11Util"); - private static final boolean DEBUG_XDISPLAY_LOCK = false; public static final String nullDisplayName; @@ -62,12 +61,7 @@ public class X11Util { initialize( true ); long dpy = X11Lib.XOpenDisplay(null); - XLockDisplay(dpy); - try { - nullDisplayName = X11Lib.XDisplayString(dpy); - } finally { - XUnlockDisplay(dpy); - } + nullDisplayName = X11Lib.XDisplayString(dpy); X11Lib.XCloseDisplay(dpy); if(DEBUG) { System.out.println("X11 Display(NULL) <"+nullDisplayName+">"); @@ -136,30 +130,17 @@ public class X11Util { return num; } - /** - * @return If name is null, it returns the previous queried NULL display name, - * otherwise the name. */ - public static String validateDisplayName(String name) { - return ( null == name ) ? nullDisplayName : name ; - } - - public static String validateDisplayName(String name, long handle) { - if(null==name && 0!=handle) { - name = getNameOfDisplay(handle); - } - return ( null == name ) ? nullDisplayName : name ; - } + /******************************* + ** + ** TLS Management + ** + *******************************/ /** Returns a clone of the thread local display map, you may {@link Object#wait()} on it */ public static Map getCurrentDisplayMap() { return (Map) ((HashMap)getCurrentDisplayMapImpl()).clone(); } - /** Returns this thread current default display. If it doesn not exist, it is being created, otherwise the reference count is increased */ - public static long createThreadLocalDefaultDisplay() { - return createThreadLocalDisplay(null); - } - /** Returns this thread named display. If it doesn not exist, it is being created, otherwise the reference count is increased */ public static long createThreadLocalDisplay(String name) { name = validateDisplayName(name); @@ -237,65 +218,6 @@ public class X11Util { return closeThreadLocalDisplay(ndpy.getName()); } - public static boolean setSynchronizeDisplay(long handle, boolean onoff) { - boolean res=false; - XLockDisplay(handle); - try { - res = X11Lib.XSynchronize(handle, onoff); - } finally { - XUnlockDisplay(handle); - } - return res; - } - - public static String getNameOfDisplay(long handle) { - String name; - XLockDisplay(handle); - try { - name = X11Lib.XDisplayString(handle); - } finally { - XUnlockDisplay(handle); - } - return name; - } - - public static void XLockDisplay(long handle) { - if(DEBUG_XDISPLAY_LOCK) { - NamedDisplay ndpy; - synchronized(globalLock) { - ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); - } - if(null==ndpy) { - throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped, thread "+Thread.currentThread().getName()); - } - ndpy.lock(); - try { - X11Lib.XLockDisplay(handle); - } catch (Throwable t) { - ndpy.unlock(); - throw new RuntimeException(t); - } - } else { - X11Lib.XLockDisplay(handle); - } - } - - public static void XUnlockDisplay(long handle) { - if(DEBUG_XDISPLAY_LOCK) { - NamedDisplay ndpy; - synchronized(globalLock) { - ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); - } - if(null==ndpy) { - throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped, thread "+Thread.currentThread().getName()); - } - X11Lib.XUnlockDisplay(handle); - ndpy.unlock(); - } else { - X11Lib.XUnlockDisplay(handle); - } - } - public static boolean markThreadLocalDisplayUncloseable(long handle) { NamedDisplay ndpy; synchronized(globalLock) { @@ -349,5 +271,52 @@ public class X11Util { return (NamedDisplay) displayMap.get(name); } + /******************************* + ** + ** Non TLS Functions + ** + *******************************/ + + /** + * @return If name is null, it returns the previous queried NULL display name, + * otherwise the name. */ + public static String validateDisplayName(String name) { + return ( null == name ) ? nullDisplayName : name ; + } + + public static String validateDisplayName(String name, long handle) { + if(null==name && 0!=handle) { + name = getNameOfDisplay(handle); + } + return validateDisplayName(name); + } + + public static boolean setSynchronizeDisplay(long handle, boolean onoff) { + boolean res = X11Lib.XSynchronize(handle, onoff); + return res; + } + + public static String getNameOfDisplay(long handle) { + String name = X11Lib.XDisplayString(handle); + return name; + } + + public static void XLockDisplay(long handle) { + if(DEBUG) { + System.out.println("... X11 Display Lock try 0x"+Long.toHexString(handle)); + } + X11Lib.XLockDisplay(handle); + if(DEBUG) { + System.out.println("+++ X11 Display Lock got 0x"+Long.toHexString(handle)); + } + } + + public static void XUnlockDisplay(long handle) { + if(DEBUG) { + System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle)); + } + X11Lib.XUnlockDisplay(handle); + } + private static native void initialize(boolean initConcurrentThreadSupport); } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java deleted file mode 100644 index 616220e14..000000000 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2008-2009 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -package com.jogamp.nativewindow.impl.x11.awt; - -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import javax.media.nativewindow.*; - -import com.jogamp.nativewindow.impl.*; -import com.jogamp.nativewindow.impl.jawt.*; -import com.jogamp.nativewindow.impl.jawt.x11.*; -import com.jogamp.nativewindow.impl.x11.*; - -public class X11AWTNativeWindowFactory extends NativeWindowFactoryImpl { - - // When running the AWT on X11 platforms, we use the AWT native - // interface (JAWT) to lock and unlock the toolkit - private ToolkitLock toolkitLock = new ToolkitLock() { - private Thread owner; - private int recursionCount; - - public synchronized void lock() { - Thread cur = Thread.currentThread(); - if (owner == cur) { - ++recursionCount; - return; - } - while (owner != null) { - try { - wait(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - owner = cur; - JAWTUtil.lockToolkit(); - } - - public synchronized void unlock() { - if (owner != Thread.currentThread()) { - throw new RuntimeException("Not owner"); - } - if (recursionCount > 0) { - --recursionCount; - return; - } - owner = null; - JAWTUtil.unlockToolkit(); - notifyAll(); - } - }; - - public ToolkitLock getToolkitLock() { - return toolkitLock; - } -} diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java index 4240ec81e..c133df5b4 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java @@ -55,4 +55,8 @@ public interface AbstractGraphicsDevice extends Cloneable { * if such thing exist. */ public long getHandle(); + + public void lock(); + + public void unlock(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java index fdc849d0f..e18b7b2dc 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java @@ -62,6 +62,12 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice return handle; } + public void lock() { + } + + public void unlock() { + } + public String toString() { return getClass().toString()+"[type "+getType()+", handle 0x"+Long.toHexString(getHandle())+"]"; } diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java index 09c605e1c..7d0c52e3b 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java @@ -53,6 +53,9 @@ package javax.media.nativewindow; such as the window handle. */ public interface NativeWindow extends SurfaceUpdatedListener { + /** Unlocked state */ + public static final int LOCK_SURFACE_UNLOCKED = 0; + /** Returned by {@link #lockSurface()} if the surface is not ready to be locked. */ public static final int LOCK_SURFACE_NOT_READY = 1; diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 14cb830e3..41be6e4b2 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -76,6 +76,7 @@ public abstract class NativeWindowFactory { private static String nativeOSNameCustom; private static final boolean isAWTAvailable; public static final String AWTComponentClassName = "java.awt.Component" ; + public static final String X11UtilClassName = "com.jogamp.nativewindow.impl.x11.X11Util"; /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -112,6 +113,10 @@ public abstract class NativeWindowFactory { nativeWindowingTypeCustom = nativeOSNameCustom; } + if( TYPE_X11.equals(nativeWindowingTypePure) ) { + ReflectionUtil.callStaticMethod( X11UtilClassName, "initSingleton", new Class[] { }, new Object[] { } ); + } + registeredFactories = Collections.synchronizedMap(new HashMap()); String factoryClassName = null; @@ -124,87 +129,25 @@ public abstract class NativeWindowFactory { // We break compile-time dependencies on the AWT here to // make it easier to run this code on mobile devices - isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) && ReflectionUtil.isClassAvailable(AWTComponentClassName) && ReflectionUtil.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice") ; - boolean toolkitLockForced = Debug.getBooleanProperty("nativewindow.locking", true, acc); - boolean awtToolkitLockDisabled = !isAWTAvailable || - Debug.getBooleanProperty("nativewindow.nolocking", true, acc) ; - - NativeWindowFactory _factory = null; - - if( !awtToolkitLockDisabled && TYPE_X11.equals(nativeWindowingTypeCustom) ) { - // There are certain operations that may be done by - // user-level native code which must share the display - // connection with the underlying window toolkit. In JOGL, - // for example, the AWT GLCanvas makes GLX and OpenGL - // calls against an X Drawable that was created by the - // AWT. In this case, the AWT Native Interface ("JAWT") is - // used to lock and unlock this surface, which grabs and - // releases a lock which is also used internally to the - // AWT implementation. This is required because the AWT - // makes X calls from multiple threads: for example, the - // AWT Toolkit thread and one or more Event Dispatch - // Threads. - // - // There are cases where synchronization with the - // toolkit is required in case of a shared resource pattern, - // e.g. with AWT. From recollection, visual selection is - // performed outside of the cover of the - // toolkit's lock, and the toolkit's display connection is - // used for this operation, so for correctness the toolkit - // must be locked during glXChooseFBConfig / - // glXChooseVisual. Synchronization with the toolkit is - // definitely needed for support of external GLDrawables, - // where JOGL creates additional OpenGL contexts on a - // surface that was created by a third party. External - // GLDrawables are the foundation of the Java 2D / JOGL - // bridge. While this bridge may be historical at this - // point, support for external GLDrawables on platforms - // that can support them (namely, WGL and X11 platforms; - // Mac OS X does not currently have the required - // primitives in its OpenGL window system binding) makes - // the JOGL library more powerful. - // - // The X11AWTNativeWindowFactory provides a locking - // mechanism compatible with the AWT. It may be desirable - // to replace this window factory when using third-party - // toolkits like Newt even when running on Java SE when - // the AWT is available. - - try { - Constructor factoryConstructor = - ReflectionUtil.getConstructor("com.jogamp.nativewindow.impl.x11.awt.X11AWTNativeWindowFactory", new Class[] {}); - _factory = (NativeWindowFactory) factoryConstructor.newInstance(null); - } catch (Exception e) { } - } - - if (toolkitLockForced && null==_factory) { - try { - Constructor factoryConstructor = - ReflectionUtil.getConstructor("com.jogamp.nativewindow.impl.LockingNativeWindowFactory", new Class[] {}); - _factory = (NativeWindowFactory) factoryConstructor.newInstance(null); - } catch (Exception e) { } - } - - if (null !=_factory) { - factory = _factory; - } - if ( isAWTAvailable ) { // register either our default factory or (if exist) the X11/AWT one -> AWT Component registerFactory(ReflectionUtil.getClass(AWTComponentClassName, false), factory); } - defaultFactory = factory; if(DEBUG) { - System.err.println("NativeWindowFactory toolkitLockForced "+toolkitLockForced+ - ", awtToolkitLockDisabled "+awtToolkitLockDisabled+", defaultFactory "+factory); + System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+ + ", defaultFactory "+factory); } } + public static void initSingleton() { + // just exist to ensure static init has been run + } + /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ public static boolean isAWTAvailable() { return isAWTAvailable; } @@ -216,32 +159,12 @@ public abstract class NativeWindowFactory { return useCustom?nativeWindowingTypeCustom:nativeWindowingTypePure; } - /** Sets the default NativeWindowFactory. Certain operations on - X11 platforms require synchronization, and the implementation - of this synchronization may be specific to the window toolkit - in use. It is impractical to require that all of the APIs that - might require synchronization receive a {@link ToolkitLock - ToolkitLock} as argument. For this reason the concept of a - default NativeWindowFactory is introduced. The toolkit lock - provided via {@link #getToolkitLock getToolkitLock} from this - default NativeWindowFactory will be used for synchronization - within the Java binding to OpenGL. By default, if the AWT is - available, the default toolkit will support the AWT. */ + /** Sets the default NativeWindowFactory. */ public static void setDefaultFactory(NativeWindowFactory factory) { defaultFactory = factory; } - /** Gets the default NativeWindowFactory. Certain operations on - X11 platforms require synchronization, and the implementation - of this synchronization may be specific to the window toolkit - in use. It is impractical to require that all of the APIs that - might require synchronization receive a {@link ToolkitLock - ToolkitLock} as argument. For this reason the concept of a - default NativeWindowFactory is introduced. The toolkit lock - provided via {@link #getToolkitLock getToolkitLock} from this - default NativeWindowFactory will be used for synchronization - within the Java binding to OpenGL. By default, if the AWT is - available, the default toolkit will support the AWT. */ + /** Gets the default NativeWindowFactory. */ public static NativeWindowFactory getDefaultFactory() { return defaultFactory; } @@ -308,10 +231,4 @@ public abstract class NativeWindowFactory { NativeWindow. Implementors of concrete NativeWindowFactory subclasses should override this method. */ protected abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException; - - /** Returns the object which provides support for synchronizing - with the underlying window toolkit.<br> - @see ToolkitLock - */ - public abstract ToolkitLock getToolkitLock(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java deleted file mode 100644 index 6f83896fa..000000000 --- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -package javax.media.nativewindow; - -/** Provides an interface for locking and unlocking the underlying - window toolkit, where this is necessary in the OpenGL - implementation. This mechanism is generally only needed on X11 - platforms. Currently it is only used when the AWT is in use. - Implementations of this lock, if they are not no-ops, must support - reentrant locking and unlocking. <P> - - The ToolkitLock implementation can be aquired by - {@link NativeWindowFactory#getToolkitLock NativeWindowFactory's getToolkitLock()}.<P> - - All toolkit shared resources shall be accessed by encapsulating the - code with a locking block as follows. - <PRE> - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long displayHandle = X11Util.getThreadLocalDefaultDisplay(); - ... some code dealing with shared resources - ... ie the window surface - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } - </PRE><P> - - The underlying toolkit's locking mechanism may relate to {@link NativeWindow}'s - {@link NativeWindow#lockSurface lockSurface()}. Hence it is important - that both implementation harmonize well, ie {@link NativeWindow#lockSurface lockSurface()} - shall issue a ToolkitLock lock befor it aquires it's surface lock. This is true - in the AWT implementation for example. Otherwise the surface lock would <i>steal</i> - the ToolkitLock's lock and a deadlock would be unavoidable.<P> - - However the necessity of needing a global state synchronization will of course - impact your performance very much, especially in case of a multithreaded/multiwindow case. - */ -public interface ToolkitLock { - /** Locks the toolkit. */ - public void lock(); - - /** Unlocks the toolkit. */ - public void unlock(); -} diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java index f0ea11011..192abf775 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java @@ -33,6 +33,8 @@ package javax.media.nativewindow.x11; import javax.media.nativewindow.*; +import com.jogamp.nativewindow.impl.*; +import com.jogamp.nativewindow.impl.x11.X11Util; /** Encapsulates a graphics device on X11 platforms. */ @@ -49,5 +51,14 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl public Object clone() { return super.clone(); } + + public void lock() { + X11Util.XLockDisplay(handle); + } + + public void unlock() { + X11Util.XUnlockDisplay(handle); + } + } diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java index a18ee91c2..97bdc37cf 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java @@ -56,53 +56,23 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl /** Creates a new X11GraphicsScreen using a thread local display connection */ public static AbstractGraphicsScreen createDefault() { - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long display = X11Util.createThreadLocalDefaultDisplay(); - X11Util.XLockDisplay(display); - try{ - int scrnIdx = X11Lib.DefaultScreen(display); - return createScreenDevice(display, scrnIdx); - }finally{ - X11Util.XUnlockDisplay(display); - } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } + long display = X11Util.createThreadLocalDisplay(null); + int scrnIdx = X11Lib.DefaultScreen(display); + return createScreenDevice(display, scrnIdx); } public long getDefaultVisualID() { // It still could be an AWT hold handle .. - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long display = getDevice().getHandle(); - X11Util.XLockDisplay(display); - try{ - int scrnIdx = X11Lib.DefaultScreen(display); - return X11Lib.DefaultVisualID(display, scrnIdx); - }finally{ - X11Util.XUnlockDisplay(display); - } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); - } + long display = getDevice().getHandle(); + int scrnIdx = X11Lib.DefaultScreen(display); + return X11Lib.DefaultVisualID(display, scrnIdx); } private static int fetchScreen(X11GraphicsDevice device, int screen) { // It still could be an AWT hold handle .. - NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); - try { - long display = device.getHandle(); - X11Util.XLockDisplay(display); - try{ - if(X11Lib.XineramaEnabled(display)) { - screen = 0; // Xinerama -> 1 screen - } - }finally{ - X11Util.XUnlockDisplay(display); - } - } finally { - NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + long display = device.getHandle(); + if(X11Lib.XineramaEnabled(display)) { + screen = 0; // Xinerama -> 1 screen } return screen; } diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index 778959a31..69ed6ebb8 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -132,13 +132,13 @@ static void _FatalError(JNIEnv *env, const char* msg, ...) (*env)->FatalError(env, buffer); } -static const char * const ClazzNameInternalBufferUtil = "com/jogamp/nativewindow/impl/InternalBufferUtil"; -static const char * const ClazzNameInternalBufferUtilStaticCstrName = "copyByteBuffer"; -static const char * const ClazzNameInternalBufferUtilStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; +static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers"; +static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer"; +static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; static const char * const ClazzNameByteBuffer = "java/nio/ByteBuffer"; static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; -static jclass clazzInternalBufferUtil = NULL; -static jmethodID cstrInternalBufferUtil = NULL; +static jclass clazzBuffers = NULL; +static jmethodID cstrBuffers = NULL; static jclass clazzByteBuffer = NULL; static jclass clazzRuntimeException=NULL; @@ -157,14 +157,14 @@ static void _initClazzAccess(JNIEnv *env) { _FatalError(env, "FatalError: NEWT X11Window: can't use %s", ClazzNameRuntimeException); } - c = (*env)->FindClass(env, ClazzNameInternalBufferUtil); + c = (*env)->FindClass(env, ClazzNameBuffers); if(NULL==c) { - _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameInternalBufferUtil); + _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameBuffers); } - clazzInternalBufferUtil = (jclass)(*env)->NewGlobalRef(env, c); + clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); - if(NULL==clazzInternalBufferUtil) { - _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameInternalBufferUtil); + if(NULL==clazzBuffers) { + _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameBuffers); } c = (*env)->FindClass(env, ClazzNameByteBuffer); if(NULL==c) { @@ -176,11 +176,11 @@ static void _initClazzAccess(JNIEnv *env) { _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameByteBuffer); } - cstrInternalBufferUtil = (*env)->GetStaticMethodID(env, clazzInternalBufferUtil, - ClazzNameInternalBufferUtilStaticCstrName, ClazzNameInternalBufferUtilStaticCstrSignature); - if(NULL==cstrInternalBufferUtil) { + cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, + ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); + if(NULL==cstrBuffers) { _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib:: can't create %s.%s %s", - ClazzNameInternalBufferUtil, ClazzNameInternalBufferUtilStaticCstrName, ClazzNameInternalBufferUtilStaticCstrSignature); + ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); } } @@ -272,7 +272,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Util_initialize(JNIEnv *env, jclass _un * C function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); */ JNIEXPORT jobject JNICALL -Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfoCopied1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) { +Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) { XVisualInfo * _ptr2 = NULL; int * _ptr3 = NULL; XVisualInfo * _res; @@ -296,8 +296,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfoCopied1__JJLjava_nio_ if (_res == NULL) return NULL; jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(XVisualInfo)); - jbyteCopy = (*env)->CallStaticObjectMethod(env, - clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource); + jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); XFree(_res); @@ -389,8 +388,6 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy return 0; } - XLockDisplay(dpy) ; - XSync(dpy, False); scrn = ScreenOfDisplay(dpy, scrn_idx); @@ -449,8 +446,6 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy XSync(dpy, False); - XUnlockDisplay(dpy) ; - DBG_PRINT2( "X11: [CreateWindow] created window %p on display %p\n", window, dpy); return (jlong) window; @@ -472,13 +467,10 @@ JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DestroyDummy _throwNewRuntimeException(NULL, env, "invalid display connection.."); return; } - XLockDisplay(dpy) ; XSync(dpy, False); XUnmapWindow(dpy, w); XSync(dpy, False); XDestroyWindow(dpy, w); XSync(dpy, False); - - XUnlockDisplay(dpy) ; } diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 8710f82ba..c804b3d2d 100755 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -33,8 +33,9 @@ package com.jogamp.newt; -import com.jogamp.newt.event.*; import javax.media.nativewindow.*; +import com.jogamp.nativewindow.impl.RecursiveToolkitLock; +import com.jogamp.newt.event.*; import com.jogamp.newt.impl.Debug; import com.jogamp.newt.util.EDTUtil; import java.util.*; @@ -112,7 +113,7 @@ public abstract class Display { Map displayMap = getCurrentDisplayMap(); Set entrySet = displayMap.entrySet(); Iterator i = entrySet.iterator(); - System.err.println(prefix+" DisplayMap[] entries: "+entrySet.size()+" - "+Thread.currentThread()); + System.err.println(prefix+" DisplayMap[] entries: "+entrySet.size()+" - "+getThreadName()); for(int j=0; i.hasNext(); j++) { Map.Entry entry = (Map.Entry) i.next(); System.err.println(" ["+j+"] "+entry.getKey()+" -> "+entry.getValue()); @@ -142,12 +143,12 @@ public abstract class Display { display.type=type; display.refCount=0; if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") NEW: refCount "+display.refCount+", "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") NEW: refCount "+display.refCount+", "+display+" "+getThreadName()); } } else { tmpDisplay = null; if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") REUSE: refCount "+display.refCount+", "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") REUSE: refCount "+display.refCount+", "+display+" "+getThreadName()); } } synchronized(display) { @@ -163,7 +164,7 @@ public abstract class Display { } setCurrentDisplay(display); if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") CreateNative: "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") CreateNative: "+display+" "+getThreadName()); } } } @@ -192,7 +193,7 @@ public abstract class Display { new Runnable() { public void run() { if(null!=f_dpy.getGraphicsDevice()) { - f_dpy.pumpMessagesImpl(); + f_dpy.dispatchMessages(); } } } ); edt = edtUtil.start(); } @@ -220,7 +221,7 @@ public abstract class Display { if(0==refCount) { removeCurrentDisplay(type, name); if(DEBUG) { - System.err.println("Display.destroy("+getFQName()+") REMOVE: "+this+" "+Thread.currentThread()); + System.err.println("Display.destroy("+getFQName()+") REMOVE: "+this+" "+getThreadName()); } final Display f_dpy = this; final EDTUtil f_edt = edtUtil; @@ -240,7 +241,7 @@ public abstract class Display { aDevice = null; } else { if(DEBUG) { - System.err.println("Display.destroy("+getFQName()+") KEEP: refCount "+refCount+", "+this+" "+Thread.currentThread()); + System.err.println("Display.destroy("+getFQName()+") KEEP: refCount "+refCount+", "+this+" "+getThreadName()); } } if(DEBUG) { @@ -267,7 +268,7 @@ public abstract class Display { protected String validateDisplayName(String name, long handle) { if(null==name && 0!=handle) { - name="wrapping-0x"+Long.toHexString(handle); + name="wrapping-"+toHexString(handle); } return ( null == name ) ? nilString : name ; } @@ -290,11 +291,6 @@ public abstract class Display { } public synchronized void pumpMessages() { - pumpMessagesImpl(); - } - - private void pumpMessagesImpl() { - if(0==refCount) return; dispatchMessages(); } @@ -302,27 +298,73 @@ public abstract class Display { return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", "+aDevice+"]"; } + public static String getThreadName() { + return Thread.currentThread().getName(); + } + + public static String toHexString(int hex) { + return "0x" + Integer.toHexString(hex); + } + + public static String toHexString(long hex) { + return "0x" + Long.toHexString(hex); + } + + protected abstract void dispatchMessagesNative(); + private Object eventsLock = new Object(); private LinkedList/*<NEWTEvent>*/ events = new LinkedList(); + private boolean events2Wait = false; protected void dispatchMessages() { + if(0==refCount) return; // we should not exist .. + if(!events.isEmpty()) { - synchronized(events) { - while (!events.isEmpty()) { - NEWTEvent e = (NEWTEvent) events.removeFirst(); - Object source = e.getSource(); - if(source instanceof Window) { - ((Window)source).sendEvent(e); - } else { - throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + if(events2Wait) { + synchronized(eventsLock) { + while (!events.isEmpty()) { + NEWTEvent e = (NEWTEvent) events.removeFirst(); + Object source = e.getSource(); + if(source instanceof Window) { + ((Window)source).sendEvent(e); + } else { + throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + } + } + events2Wait = false; // clear + eventsLock.notifyAll(); + } + } else { + // swap events list to free ASAP + LinkedList/*<NEWTEvent>*/ _events = null; + synchronized(eventsLock) { + if(!events.isEmpty()) { + _events = events; + events = new LinkedList(); + } + eventsLock.notifyAll(); + } + if( null != _events ) { + while (!_events.isEmpty()) { + NEWTEvent e = (NEWTEvent) _events.removeFirst(); + Object source = e.getSource(); + if(source instanceof Window) { + ((Window)source).sendEvent(e); + } else { + throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + } } } - events.notifyAll(); } } - dispatchMessagesNative(); + // lock(); + try { + dispatchMessagesNative(); + } finally { + // unlock(); + } } public void enqueueEvent(NEWTEvent e) { @@ -330,17 +372,18 @@ public abstract class Display { } public void enqueueEvent(boolean wait, NEWTEvent e) { - synchronized(events) { + synchronized(eventsLock) { if(DEBUG) { System.out.println("Display.enqueueEvent: START - wait "+wait+", "+e); } + events2Wait = wait; events.addLast(e); } if(wait && !events.isEmpty()) { - synchronized(events) { + synchronized(eventsLock) { while(!events.isEmpty()) { try { - events.wait(); + eventsLock.wait(); } catch (InterruptedException ie) { ie.printStackTrace(); } @@ -352,12 +395,13 @@ public abstract class Display { } } + public void lock() { + aDevice.lock(); + } - /** Default impl. nop - Currently only X11 needs a Display lock */ - protected void lockDisplay() { } - - /** Default impl. nop - Currently only X11 needs a Display lock */ - protected void unlockDisplay() { } + public void unlock() { + aDevice.unlock(); + } protected EDTUtil edtUtil = null; protected Thread edt = null; diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 87f0bf0eb..89c1bd146 100755 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -132,14 +132,6 @@ public abstract class Window implements NativeWindow } } - public static String toHexString(int hex) { - return "0x" + Integer.toHexString(hex); - } - - public static String toHexString(long hex) { - return "0x" + Long.toHexString(hex); - } - protected Screen screen; protected NativeWindow parentNativeWindow; @@ -162,14 +154,15 @@ public abstract class Window implements NativeWindow return 0 != windowHandle ; } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.createNative() START ("+Thread.currentThread()+", "+this+")"); + System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")"); } if(validateParentWindowHandle()) { + Display dpy = getScreen().getDisplay(); createNativeImpl(); setVisibleImpl(true); } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.createNative() END ("+Thread.currentThread()+", "+this+")"); + System.err.println("Window.createNative() END ("+getThreadName()+", "+this+")"); } return 0 != windowHandle ; } @@ -185,26 +178,27 @@ public abstract class Window implements NativeWindow private static long getNativeWindowHandle(NativeWindow nativeWindow) { long handle = 0; if(null!=nativeWindow) { - boolean ok = true; + boolean locked=false; try { - nativeWindow.lockSurface(); + if( NativeWindow.LOCK_SURFACE_NOT_READY < nativeWindow.lockSurface() ) { + locked=true; + handle = nativeWindow.getWindowHandle(); + if(0==handle) { + throw new NativeWindowException("Parent native window handle is NULL, after succesful locking: "+nativeWindow); + } + } } catch (NativeWindowException nwe) { - // parent native window not ready .. just skip action for now - ok = false; if(DEBUG_IMPLEMENTATION) { System.err.println("Window.getNativeWindowHandle: not successful yet: "+nwe); } - } - if(ok) { - handle = nativeWindow.getWindowHandle(); - nativeWindow.unlockSurface(); - if(0==handle) { - throw new NativeWindowException("Parent native window handle is NULL, after succesful locking: "+nativeWindow); - } - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.getNativeWindowHandle: "+nativeWindow); + } finally { + if(locked) { + nativeWindow.unlockSurface(); } } + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.getNativeWindowHandle: locked "+locked+", "+nativeWindow); + } } return handle; } @@ -281,7 +275,11 @@ public abstract class Window implements NativeWindow title = ""; } this.title = title; + if(0 != windowHandle) { + setTitleImpl(title); + } } + protected void setTitleImpl(String title) {} public void setUndecorated(boolean value) { undecorated = value; @@ -296,7 +294,11 @@ public abstract class Window implements NativeWindow } public void requestFocus() { + if(0 != windowHandle) { + requestFocusImpl(); + } } + protected void requestFocusImpl() {} // // NativeWindow impl @@ -306,35 +308,35 @@ public abstract class Window implements NativeWindow public int lockSurface() { // We leave the ToolkitLock lock to the specializtion's discretion, // ie the implicit JAWTWindow in case of AWTWindow - if(isDestroyed() || !isNativeWindowValid()) { - return LOCK_SURFACE_NOT_READY; - } - surfaceLock.lock(); - screen.getDisplay().lockDisplay(); + + windowLock.lock(); + + // if(windowLock.getRecursionCount() == 0) { // allow recursion to lock again, always + if(isDestroyed() || !isNativeWindowValid()) { + windowLock.unlock(); + return LOCK_SURFACE_NOT_READY; + } + // } return LOCK_SUCCESS; } /** Recursive and unblocking unlockSurface() implementation */ public void unlockSurface() throws NativeWindowException { - surfaceLock.unlock( new Runnable() { - public void run() { - screen.getDisplay().unlockDisplay(); - } - } ); + windowLock.unlock(); // We leave the ToolkitLock unlock to the specializtion's discretion, // ie the implicit JAWTWindow in case of AWTWindow } public boolean isSurfaceLocked() { - return surfaceLock.isLocked(); + return windowLock.isLocked(); } public Thread getSurfaceLockOwner() { - return surfaceLock.getOwner(); + return windowLock.getOwner(); } public Exception getLockedStack() { - return surfaceLock.getLockedStack(); + return windowLock.getLockedStack(); } /** @@ -352,6 +354,19 @@ public abstract class Window implements NativeWindow destroy(false); } + /** + * @param deep If true, all resources, ie listeners, parent handles, size, position + * and the referenced NEWT screen and display, will be destroyed as well. Be aware that if you call + * this method with deep = true, you will not be able to regenerate the Window. + * @see #destroy() + * @see #invalidate(boolean) + */ + public void destroy(boolean deep) { + if(!isDestroyed()) { + runOnEDTIfAvail(true, new DestroyAction(deep)); + } + } + class DestroyAction implements Runnable { boolean deep; public DestroyAction(boolean deep) { @@ -361,7 +376,7 @@ public abstract class Window implements NativeWindow windowLock(); try { if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.destroy(deep: "+deep+") START "+Thread.currentThread()+", "+this); + System.err.println("Window.destroy(deep: "+deep+") START "+getThreadName()+", "+this); } // Childs first .. @@ -397,22 +412,23 @@ public abstract class Window implements NativeWindow } } Display dpy = null; + Screen scr = null; if( null != screen && 0 != windowHandle ) { - Screen scr = screen; - dpy = (null!=screen) ? screen.getDisplay() : null; + scr = screen; + dpy = screen.getDisplay(); closeNative(); } invalidate(deep); if(deep) { - if(null!=screen) { - screen.destroy(); + if(null!=scr) { + scr.destroy(); } if(null!=dpy) { dpy.destroy(); } } if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.destroy(deep: "+deep+") END "+Thread.currentThread()+", "+this); + System.err.println("Window.destroy(deep: "+deep+") END "+getThreadName()+", "+this); } } finally { windowUnlock(); @@ -421,19 +437,6 @@ public abstract class Window implements NativeWindow } /** - * @param deep If true, all resources, ie listeners, parent handles, size, position - * and the referenced NEWT screen and display, will be destroyed as well. Be aware that if you call - * this method with deep = true, you will not be able to regenerate the Window. - * @see #destroy() - * @see #invalidate(boolean) - */ - public void destroy(boolean deep) { - if(!isDestroyed()) { - runOnEDTIfAvail(true, new DestroyAction(deep)); - } - } - - /** * <p> * render all native window information invalid, * as if the native window was destroyed.<br></p> @@ -461,7 +464,7 @@ public abstract class Window implements NativeWindow windowLock(); try{ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - String msg = new String("!!! Window Invalidate(deep: "+deep+") "+Thread.currentThread()); + String msg = new String("!!! Window Invalidate(deep: "+deep+") "+getThreadName()); System.err.println(msg); //Exception e = new Exception(msg); //e.printStackTrace(); @@ -600,23 +603,23 @@ public abstract class Window implements NativeWindow protected void windowDestroyNotify() { if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyNotify START "+Thread.currentThread()); + System.err.println("Window.windowDestroyNotify START "+getThreadName()); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); if(handleDestroyNotify && !isDestroyed()) { destroy(); } if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyeNotify END "+Thread.currentThread()); + System.err.println("Window.windowDestroyeNotify END "+getThreadName()); } } protected void windowDestroyed() { if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyed "+Thread.currentThread()); + System.err.println("Window.windowDestroyed "+getThreadName()); } invalidate(); } @@ -626,6 +629,68 @@ public abstract class Window implements NativeWindow return false; } + class ReparentAction implements Runnable { + NativeWindow newParent; + Screen newScreen; + public ReparentAction(NativeWindow newParent, Screen newScreen) { + this.newParent = newParent; + this.newScreen = newScreen; + } + public void run() { + windowLock(); + try{ + if ( 0 == windowHandle && null != newScreen ) { + screen = newScreen; + } + long newParentHandle = 0 ; + if(null!=newParent) { + newParentHandle = getNativeWindowHandle(newParent); + if ( 0 == newParentHandle ) { + return; // bail out .. not ready yet + } + } + + if(DEBUG_IMPLEMENTATION) { + System.err.println("reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow)); + } + + if(null!=parentNativeWindow && parentNativeWindow instanceof Window) { + ((Window)parentNativeWindow).getInnerWindow().removeChild(Window.this); + } + parentNativeWindow = newParent; + if(parentNativeWindow instanceof Window) { + ((Window)parentNativeWindow).getInnerWindow().addChild(Window.this); + } + + if(newParentHandle != parentWindowHandle) { + parentWindowHandle = newParentHandle; + if(0!=parentWindowHandle) { + // reset position to 0/0 within parent space + // FIXME .. cache position ? + x = 0; + y = 0; + } + boolean reparentRes = false; + reparentRes = reparentWindowImpl(); + if(!reparentRes) { + parentWindowHandle = 0; + + // do it the hard way .. reconstruction with setVisible(true) + if( 0 != windowHandle ) { + destroy(false); + } + } + } + + if(DEBUG_IMPLEMENTATION) { + System.err.println("reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); + } + } finally { + windowUnlock(); + } + } + } + /** * Change this window's parent window.<br> * <P> @@ -639,54 +704,11 @@ public abstract class Window implements NativeWindow * this Screen is being used. */ public void reparentWindow(NativeWindow newParent, Screen newScreen) { - windowLock(); - try{ - if ( 0 == windowHandle && null != newScreen ) { - screen = newScreen; - } - long newParentHandle = 0 ; - if(null!=newParent) { - newParentHandle = getNativeWindowHandle(newParent); - if ( 0 == newParentHandle ) { - return; // bail out .. not ready yet - } - } - - if(DEBUG_IMPLEMENTATION) { - System.err.println("reparent: START ("+Thread.currentThread()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow)); - } - - if(null!=parentNativeWindow && parentNativeWindow instanceof Window) { - ((Window)parentNativeWindow).getInnerWindow().removeChild(this); - } - parentNativeWindow = newParent; - if(parentNativeWindow instanceof Window) { - ((Window)parentNativeWindow).getInnerWindow().addChild(this); - } - - if(newParentHandle != parentWindowHandle) { - parentWindowHandle = newParentHandle; - if(0!=parentWindowHandle) { - // reset position to 0/0 within parent space - // FIXME .. cache position ? - x = 0; - y = 0; - } - if(!reparentWindowImpl()) { - parentWindowHandle = 0; - - // do it the hard way .. reconstruction with setVisible(true) - if( 0 != windowHandle ) { - destroy(false); - } - } - } - - if(DEBUG_IMPLEMENTATION) { - System.err.println("reparentWindow: END ("+Thread.currentThread()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); + if(!isDestroyed()) { + runOnEDTIfAvail(true, new ReparentAction(newParent, newScreen)); + if( isVisible() ) { + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener } - } finally { - windowUnlock(); } } @@ -733,7 +755,7 @@ public abstract class Window implements NativeWindow } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setVisible: END ("+Thread.currentThread()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible); + System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible); } } finally { windowUnlock(); @@ -768,7 +790,7 @@ public abstract class Window implements NativeWindow */ public void setVisible(boolean visible) { if(DEBUG_IMPLEMENTATION) { - String msg = new String("Window setVisible: START ("+Thread.currentThread()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); + String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); //System.err.println(msg); Exception ee = new Exception(msg); ee.printStackTrace(); @@ -1000,49 +1022,19 @@ public abstract class Window implements NativeWindow // // MouseListener/Event Support // - - public void addMouseListener(MouseListener l) { - if(l == null) { - return; - } - synchronized(mouseListeners) { - ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); - newMouseListeners.add(l); - mouseListeners = newMouseListeners; - } - } - - public void removeMouseListener(MouseListener l) { - if (l == null) { - return; - } - synchronized(mouseListeners) { - ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); - newMouseListeners.remove(l); - mouseListeners = newMouseListeners; - } - } - - public MouseListener[] getMouseListeners() { - synchronized(mouseListeners) { - return (MouseListener[]) mouseListeners.toArray(); - } - } - private ArrayList mouseListeners = new ArrayList(); private int mouseButtonPressed = 0; // current pressed mouse button number private long lastMousePressed = 0; // last time when a mouse button was pressed private int lastMouseClickCount = 0; // last mouse button click count public static final int ClickTimeout = 300; - /** Be aware that this method synthesizes the events: MouseClicked and MouseDragged */ - protected void sendMouseEvent(int eventType, int modifiers, + protected void enqueueMouseEvent(int eventType, int modifiers, int x, int y, int button, int rotation) { if(x<0||y<0||x>=width||y>=height) { return; // .. invalid .. } if(DEBUG_MOUSE_EVENT) { - System.err.println("sendMouseEvent: "+MouseEvent.getEventTypeString(eventType)+ + System.err.println("enqueueMouseEvent: "+MouseEvent.getEventTypeString(eventType)+ ", mod "+modifiers+", pos "+x+"/"+y+", button "+button); } if(button<0||button>MouseEvent.BUTTON_NUMBER) { @@ -1086,12 +1078,41 @@ public abstract class Window implements NativeWindow } else { e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, 0); } - sendMouseEvent(e); + screen.getDisplay().enqueueEvent(e); if(null!=eClicked) { if(DEBUG_MOUSE_EVENT) { - System.err.println("sendMouseEvent: synthesized MOUSE_CLICKED event"); + System.err.println("enqueueMouseEvent: synthesized MOUSE_CLICKED event"); } - sendMouseEvent(eClicked); + screen.getDisplay().enqueueEvent(eClicked); + } + } + + + public void addMouseListener(MouseListener l) { + if(l == null) { + return; + } + synchronized(mouseListeners) { + ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); + newMouseListeners.add(l); + mouseListeners = newMouseListeners; + } + } + + public void removeMouseListener(MouseListener l) { + if (l == null) { + return; + } + synchronized(mouseListeners) { + ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); + newMouseListeners.remove(l); + mouseListeners = newMouseListeners; + } + } + + public MouseListener[] getMouseListeners() { + synchronized(mouseListeners) { + return (MouseListener[]) mouseListeners.toArray(); } } @@ -1141,6 +1162,12 @@ public abstract class Window implements NativeWindow // KeyListener/Event Support // + protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + screen.getDisplay().enqueueEvent( + new KeyEvent(eventType, this, System.currentTimeMillis(), + modifiers, keyCode, keyChar) ); + } + public void addKeyListener(KeyListener l) { if(l == null) { return; @@ -1171,11 +1198,6 @@ public abstract class Window implements NativeWindow private ArrayList keyListeners = new ArrayList(); - protected void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { - sendKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), - modifiers, keyCode, keyChar) ); - } - protected void sendKeyEvent(KeyEvent e) { if(DEBUG_KEY_EVENT) { System.err.println("sendKeyEvent: "+e); @@ -1205,6 +1227,11 @@ public abstract class Window implements NativeWindow // // WindowListener/Event Support // + protected void enqueueWindowEvent(int eventType) { + WindowEvent event = new WindowEvent(eventType, this, System.currentTimeMillis()); + screen.getDisplay().enqueueEvent( event ); + // sendWindowEvent ( event ); // FIXME: Think about performance/lag .. ? + } private ArrayList windowListeners = new ArrayList(); @@ -1236,10 +1263,6 @@ public abstract class Window implements NativeWindow } } - protected void sendWindowEvent(int eventType) { - sendWindowEvent( new WindowEvent(eventType, this, System.currentTimeMillis()) ); - } - protected void sendWindowEvent(WindowEvent e) { if(DEBUG_WINDOW_EVENT) { System.err.println("sendWindowEvent: "+e); @@ -1365,8 +1388,7 @@ public abstract class Window implements NativeWindow return sb.toString(); } - private RecursiveToolkitLock surfaceLock = new RecursiveToolkitLock(); - private RecursiveToolkitLock windowLock = new RecursiveToolkitLock(); + protected RecursiveToolkitLock windowLock = new RecursiveToolkitLock(); private static final boolean TRACE_LOCK = false; @@ -1387,8 +1409,23 @@ public abstract class Window implements NativeWindow protected final boolean windowIsLocked() { return getInnerWindow().windowLock.isLocked(); } + protected RecursiveToolkitLock getWindowLock() { + return getInnerWindow().windowLock; + } protected final void shouldNotCallThis() { throw new NativeWindowException("Should not call this"); } + + public static String getThreadName() { + return Display.getThreadName(); + } + + public static String toHexString(int hex) { + return Display.toHexString(hex); + } + + public static String toHexString(long hex) { + return Display.toHexString(hex); + } } diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 23269a93b..a84e571e4 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -55,7 +55,6 @@ public class NewtCanvasAWT extends java.awt.Canvas { /** * Instantiates a NewtCanvas without a NEWT child.<br> - * @see #setNEWTChild(Window) */ public NewtCanvasAWT() { super(); @@ -74,8 +73,9 @@ public class NewtCanvasAWT extends java.awt.Canvas { if(newtChild!=child) { newtChild = child; if(null!=parent) { + java.awt.Container cont = getContainer(this); // reparent right away, addNotify has been called already - reparentWindow( (null!=newtChild) ? true : false ); + reparentWindow( (null!=newtChild) ? true : false, cont ); } } return this; @@ -100,26 +100,38 @@ public class NewtCanvasAWT extends java.awt.Canvas { } } + static java.awt.Container getContainer(java.awt.Component comp) { + while( null != comp && !(comp instanceof java.awt.Container) ) { + comp = comp.getParent(); + } + if(comp instanceof java.awt.Container) { + return (java.awt.Container) comp; + } + return null; + } + public void addNotify() { super.addNotify(); disableBackgroundErase(); + java.awt.Container cont = getContainer(this); if(DEBUG_IMPLEMENTATION) { // if ( isShowing() == false ) -> Container was not visible yet. // if ( isShowing() == true ) -> Container is already visible. - System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+", displayable "+isDisplayable()); + System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+", displayable "+isDisplayable()+" -> "+cont); } - reparentWindow(true); + reparentWindow(true, cont); } public void removeNotify() { + java.awt.Container cont = getContainer(this); if(DEBUG_IMPLEMENTATION) { - System.err.println("NewtCanvasAWT.removeNotify: "+newtChild); + System.err.println("NewtCanvasAWT.removeNotify: "+newtChild+", from "+cont); } - reparentWindow(false); + reparentWindow(false, cont); super.removeNotify(); } - void reparentWindow(boolean add) { + void reparentWindow(boolean add, java.awt.Container cont) { if(null==newtChild) { return; // nop } @@ -129,20 +141,18 @@ public class NewtCanvasAWT extends java.awt.Canvas { parent = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities()); } if(null!=parent) { - // 1st choice - NEWT size := AWT size - // 2nd choice - AWT size := NEWT size - if(0>=getWidth()*getHeight()) { - setSize(newtChild.getWidth(), newtChild.getHeight()); // #2 + if(DEBUG_IMPLEMENTATION) { + System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild); } + setSize(cont.getWidth(), cont.getHeight()); + newtChild.setSize(cont.getWidth(), cont.getHeight()); + Screen screen = null; if( !newtChild.isNativeWindowValid() ) { screen = NewtFactoryAWT.createCompatibleScreen(parent); } newtChild.reparentWindow(parent, screen); - if ( 0 < getWidth() * getHeight() ) { - newtChild.setSize(getWidth(), getHeight()); // #1 - newtChild.setVisible(true); - } + newtChild.setVisible(true); setWindowAdapter(true); } } else { diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java index 33c291e96..7905a728c 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java @@ -57,6 +57,9 @@ public class AWTParentWindowAdapter // Need to resize the NEWT child window // the resized event will be send via the native window feedback. final java.awt.Component comp = e.getComponent(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: componentResized: "+comp); + } newtWindow.runOnEDTIfAvail(false, new Runnable() { public void run() { if( 0 < comp.getWidth() * comp.getHeight() ) { @@ -87,7 +90,7 @@ public class AWTParentWindowAdapter if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) { final boolean showing = changed.isShowing(); if(DEBUG_IMPLEMENTATION) { - System.out.println("hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed); + System.out.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed); } if(!newtWindow.isDestroyed()) { newtWindow.runOnEDTIfAvail(false, new Runnable() { @@ -100,7 +103,7 @@ public class AWTParentWindowAdapter if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) { final boolean displayability = changed.isDisplayable(); if(DEBUG_IMPLEMENTATION) { - System.out.println("hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed); + System.out.println("AWT: hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed); } } } diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java index 570b0678a..ee7ca97ad 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java @@ -105,6 +105,10 @@ public class AWTWindowAdapter } public void componentShown(java.awt.event.ComponentEvent e) { + final java.awt.Component comp = e.getComponent(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: componentShown: "+comp); + } /** if(null==newtListener) { if(!newtWindow.isDestroyed()) { @@ -118,6 +122,10 @@ public class AWTWindowAdapter } public void componentHidden(java.awt.event.ComponentEvent e) { + final java.awt.Component comp = e.getComponent(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: componentHidden: "+comp); + } /** if(null==newtListener) { if(!newtWindow.isDestroyed()) { diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java index f97625320..a06b7160c 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java @@ -84,8 +84,7 @@ public class AWTWindow extends Window { // non fullscreen dimensions .. private int nfs_width, nfs_height, nfs_x, nfs_y; - public void setTitle(final String title) { - super.setTitle(title); + protected void setTitleImpl(final String title) { runOnEDT(true, new Runnable() { public void run() { if (frame != null) { @@ -265,17 +264,17 @@ public class AWTWindow extends Window { return canvas; } - protected void sendWindowEvent(int eventType) { - super.sendWindowEvent(eventType); + protected void enqueueWindowEvent(int eventType) { + super.enqueueWindowEvent(eventType); } - protected void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { - super.sendKeyEvent(eventType, modifiers, keyCode, keyChar); + protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + super.enqueueKeyEvent(eventType, modifiers, keyCode, keyChar); } - protected void sendMouseEvent(int eventType, int modifiers, + protected void enqueueMouseEvent(int eventType, int modifiers, int x, int y, int button, int rotation) { - super.sendMouseEvent(eventType, modifiers, x, y, button, rotation); + super.enqueueMouseEvent(eventType, modifiers, x, y, button, rotation); } private void runOnEDT(boolean wait, Runnable r) { diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java index 74cb53f7e..1b8a62a9c 100644 --- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java @@ -116,7 +116,7 @@ public class Window extends com.jogamp.newt.Window { return fullscreen; } - public void requestFocus() { + protected void requestFocusImpl() { ((Display)screen.getDisplay()).setFocus(this); } diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java index b6328b02f..8a656a5a8 100755 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java @@ -231,8 +231,8 @@ public class MacWindow extends Window { } } - public void setTitle(String title) { - super.setTitle(title); + protected void setTitleImpl(final String title) { + // FIXME: move nsViewLock up to window lock nsViewLock.lock(); try { if (windowHandle != 0) { @@ -243,8 +243,8 @@ public class MacWindow extends Window { } } - public void requestFocus() { - super.requestFocus(); + protected void requestFocusImpl() { + // FIXME: move nsViewLock up to window lock nsViewLock.lock(); try { if (windowHandle != 0) { @@ -309,7 +309,7 @@ public class MacWindow extends Window { if (DEBUG_IMPLEMENTATION) { System.out.println(" Posted WINDOW_RESIZED event"); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } } @@ -340,15 +340,15 @@ public class MacWindow extends Window { if (DEBUG_IMPLEMENTATION) { System.out.println(" Posted WINDOW_MOVED event"); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); } } private void focusChanged(boolean focusGained) { if (focusGained) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } else { - sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); } } @@ -435,12 +435,12 @@ public class MacWindow extends Window { return keyChar; } - protected void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { int key = convertKeyChar(keyChar); - if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()); + if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()); // Note that we send the key char for the key code on this // platform -- we do not get any useful key codes out of the system - super.sendKeyEvent(eventType, modifiers, key, keyChar); + super.enqueueKeyEvent(eventType, modifiers, key, keyChar); } private void createWindow(final boolean recreate, final int x, final int y, final int width, final int height, final boolean fullscreen) { @@ -482,9 +482,9 @@ public class MacWindow extends Window { ie.printStackTrace(); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } protected static native boolean initIDs0(); diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java index 54623996c..0d12a4a0a 100755 --- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java @@ -135,7 +135,7 @@ public class KDWindow extends Window { } else { ((KDScreen)screen).setScreenSize(width, height); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } private long eglWindowHandle; diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index 5e1b5a43c..aedb4ed7d 100755 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -53,35 +53,21 @@ public class WindowsWindow extends Window { public WindowsWindow() { } - Thread hdcOwner = null; - - public synchronized int lockSurface() throws NativeWindowException { + public int lockSurface() throws NativeWindowException { int res = super.lockSurface(); - if(LOCK_SUCCESS==res && 0!=windowHandle) { - if(hdc!=0) { - throw new NativeWindowException("NEWT Surface handle set HDC "+toHexString(hdc)+" - "+Thread.currentThread().getName()+" ; "+this); - } + if( LOCK_SUCCESS == res && 0 != windowHandle && 0 == hdc ) { hdc = GetDC0(windowHandle); hmon = MonitorFromWindow0(windowHandle); - hdcOwner = Thread.currentThread(); } return res; } - public synchronized void unlockSurface() { - // prevalidate, before we change data .. - Thread cur = Thread.currentThread(); - if ( getSurfaceLockOwner() != cur ) { - getLockedStack().printStackTrace(); - throw new NativeWindowException(cur+": Not owner, owner is "+getSurfaceLockOwner()); - } - if (0!=hdc && 0!=windowHandle) { - if(hdcOwner != cur) { - throw new NativeWindowException("NEWT Surface handle set HDC "+toHexString(hdc)+" by other thread "+hdcOwner+", this "+cur+" ; "+this); - } + public void unlockSurface() { + getWindowLock().validateLocked(); + + if ( 0 != hdc && 0 != windowHandle && getWindowLock().getRecursionCount() == 0) { ReleaseDC0(windowHandle, hdc); hdc=0; - hdcOwner=null; } super.unlockSurface(); } @@ -187,23 +173,14 @@ public class WindowsWindow extends Window { return true; } - // @Override - public void requestFocus() { - super.requestFocus(); + protected void requestFocusImpl() { if (windowHandle != 0L) { - requestFocus0(windowHandle); + requestFocus0(fullscreen?0:parentWindowHandle, windowHandle); } } - // @Override - public void setTitle(String title) { - if (title == null) { - title = ""; - } - if (0!=windowHandle && !title.equals(getTitle())) { - super.setTitle(title); - setTitle0(windowHandle, title); - } + protected void setTitleImpl(final String title) { + setTitle0(windowHandle, title); } public Insets getInsets() { @@ -229,7 +206,7 @@ public class WindowsWindow extends Window { private native void setFullscreen0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated); private native void reparentWindow0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated); private static native void setTitle0(long windowHandle, String title); - private static native void requestFocus0(long windowHandle); + private static native void requestFocus0(long parentWindowHandle, long windowHandle); private void insetsChanged(int left, int top, int right, int bottom) { if (left != -1 && top != -1 && right != -1 && bottom != -1) { @@ -248,7 +225,7 @@ public class WindowsWindow extends Window { nfs_width=width; nfs_height=height; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } } @@ -260,7 +237,7 @@ public class WindowsWindow extends Window { nfs_x=x; nfs_y=y; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); } } @@ -272,9 +249,9 @@ public class WindowsWindow extends Window { */ private void focusChanged(long focusOwner, boolean focusGained) { if (focusGained) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } else { - sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); } } } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java index 54fe0542b..6701d6c8e 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java @@ -40,6 +40,7 @@ import com.jogamp.newt.impl.*; import com.jogamp.nativewindow.impl.x11.X11Util; public class X11Display extends Display { + static { NEWTJNILibLoader.loadNEWT(); @@ -65,7 +66,7 @@ public class X11Display extends Display { } protected void createNative() { - long handle= X11Util.createThreadLocalDisplay(name); + long handle = X11Util.createThreadLocalDisplay(name); if( 0 == handle ) { throw new RuntimeException("Error creating display: "+name); } @@ -89,16 +90,6 @@ public class X11Display extends Display { DispatchMessages0(getHandle(), javaObjectAtom, windowDeleteAtom); } - protected void lockDisplay() { - super.lockDisplay(); - X11Util.XLockDisplay(getHandle()); - } - - protected void unlockDisplay() { - X11Util.XUnlockDisplay(getHandle()); - super.unlockDisplay(); - } - protected long getJavaObjectAtom() { return javaObjectAtom; } protected long getWindowDeleteAtom() { return windowDeleteAtom; } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java index a51eee241..e7fc96019 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -58,21 +58,20 @@ public class X11Window extends Window { X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config; long visualID = x11config.getVisualID(); long w = CreateWindow0(parentWindowHandle, - display.getHandle(), screen.getIndex(), visualID, - display.getJavaObjectAtom(), display.getWindowDeleteAtom(), - x, y, width, height, isUndecorated()); + display.getHandle(), screen.getIndex(), visualID, + display.getJavaObjectAtom(), display.getWindowDeleteAtom(), + x, y, width, height, isUndecorated()); if (w == 0 || w!=windowHandle) { throw new NativeWindowException("Error creating window: "+w); } windowHandleClose = windowHandle; - displayHandleClose = display.getHandle(); } protected void closeNative() { - if(0!=displayHandleClose && 0!=windowHandleClose && null!=getScreen() ) { + if(0!=windowHandleClose && null!=getScreen() ) { X11Display display = (X11Display) getScreen().getDisplay(); try { - CloseWindow0(displayHandleClose, windowHandleClose, display.getJavaObjectAtom()); + CloseWindow0(display.getHandle(), windowHandleClose, display.getJavaObjectAtom()); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("closeNative failed - "+Thread.currentThread().getName(), t); @@ -80,14 +79,12 @@ public class X11Window extends Window { } } finally { windowHandleClose = 0; - displayHandleClose = 0; } } } protected void windowDestroyed() { windowHandleClose = 0; - displayHandleClose = 0; super.windowDestroyed(); } @@ -101,41 +98,31 @@ public class X11Window extends Window { } protected void setPositionImpl(int x, int y) { - // this x/y will be set by windowChanged, called by X11 setPosition0(parentWindowHandle, getDisplayHandle(), windowHandle, x, y); } protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { - setPosSizeDecor0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, w, h, isUndecorated(fullscreen)); + setPosSizeDecor0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, + x, y, w, h, isUndecorated(fullscreen), isVisible()); return fullscreen; } protected boolean reparentWindowImpl() { if(0!=windowHandle) { - reparentWindow0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, isUndecorated()); - // X11 reparent unmaps the window - setVisibleImpl(visible); + reparentWindow0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, + x, y, isUndecorated(), isVisible()); } return true; } - // @Override - public void requestFocus() { - super.requestFocus(); + protected void requestFocusImpl() { if (windowHandle != 0L) { requestFocus0(getDisplayHandle(), windowHandle); } } - // @Override - public void setTitle(String title) { - if (title == null) { - title = ""; - } - if (0!=windowHandle && !title.equals(getTitle())) { - super.setTitle(title); - setTitle0(getDisplayHandle(), windowHandle, title); - } + protected void setTitleImpl(String title) { + setTitle0(getDisplayHandle(), windowHandle, title); } @@ -151,12 +138,12 @@ public class X11Window extends Window { private native void setVisible0(long display, long windowHandle, boolean visible); private native void setSize0(long display, long windowHandle, int width, int height); private native void setPosSizeDecor0(long parentWindowHandle, long display, int screen_index, long windowHandle, - int x, int y, int width, int height, boolean undecorated); + int x, int y, int width, int height, boolean undecorated, boolean isVisible); private native void setTitle0(long display, long windowHandle, String title); private native void requestFocus0(long display, long windowHandle); private native void setPosition0(long parentWindowHandle, long display, long windowHandle, int x, int y); private native void reparentWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle, - int x, int y, boolean undecorated); + int x, int y, boolean undecorated, boolean isVisible); private void windowChanged(int newX, int newY, int newWidth, int newHeight) { if(width != newWidth || height != newHeight) { @@ -169,7 +156,7 @@ public class X11Window extends Window { nfs_width=width; nfs_height=height; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } if( 0==parentWindowHandle && ( x != newX || y != newY ) ) { if(DEBUG_IMPLEMENTATION) { @@ -181,7 +168,7 @@ public class X11Window extends Window { nfs_x=x; nfs_y=y; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); } } @@ -190,9 +177,9 @@ public class X11Window extends Window { */ private void focusChanged(boolean focusGained) { if (focusGained) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } else { - sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); } } @@ -208,5 +195,4 @@ public class X11Window extends Window { } private long windowHandleClose; - private long displayHandleClose; } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index dec41b427..7a223026e 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -161,29 +161,13 @@ public class GLWindow extends Window implements GLAutoDrawable { shouldNotCallThis(); } - protected void dispose() { - if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - Exception e1 = new Exception("GLWindow.dispose() "+Thread.currentThread()+", start: "+this); - e1.printStackTrace(); - } - - if ( null != context && context.isCreated() && null != drawable && drawable.isRealized() ) { - helper.invokeGL(drawable, context, disposeAction, null); - } - - if (context != null) { - context.destroy(); - context = null; - } - if (drawable != null) { - drawable.setRealized(false); - drawable = null; - } - - if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - System.out.println("GLWindow.dispose() "+Thread.currentThread()+", fin: "+this); + class DisposeAction implements Runnable { + public void run() { + // Lock: Covered by DestroyAction .. + helper.dispose(GLWindow.this); } } + private DisposeAction disposeAction = new DisposeAction(); class DestroyAction implements Runnable { boolean deep; @@ -191,12 +175,35 @@ public class GLWindow extends Window implements GLAutoDrawable { this.deep = deep; } public void run() { + // Lock: Have to cover whole workflow (dispose all, context, drawable and window) windowLock(); try { if(null==window || window.isDestroyed()) { return; // nop } - dispose(); + if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { + Exception e1 = new Exception("GLWindow.destroy("+deep+") "+Thread.currentThread()+", start: "+GLWindow.this); + e1.printStackTrace(); + } + + if ( null != context && context.isCreated() && null != drawable && drawable.isRealized() ) { + // Catch dispose GLExceptions by GLEventListener, just 'print' them + // so we can continue with the destruction. + try { + helper.invokeGL(drawable, context, disposeAction, null); + } catch (GLException gle) { + gle.printStackTrace(); + } + } + + if (context != null && null != drawable && drawable.isRealized() ) { + context.destroy(); + context = null; + } + if (drawable != null) { + drawable.setRealized(false); + drawable = null; + } if(null!=window) { window.destroy(deep); @@ -205,6 +212,9 @@ public class GLWindow extends Window implements GLAutoDrawable { if(deep) { helper=null; } + if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { + System.out.println("GLWindow.destroy("+deep+") "+Thread.currentThread()+", fin: "+GLWindow.this); + } } finally { windowUnlock(); } @@ -243,6 +253,7 @@ public class GLWindow extends Window implements GLAutoDrawable { this.visible = visible; } public void run() { + // Lock: Have to cover whole workflow (window, may do nativeCreation, drawable and context) windowLock(); try{ window.setVisible(visible); @@ -489,7 +500,12 @@ public class GLWindow extends Window implements GLAutoDrawable { if(forceReshape) { sendReshape = true; } - helper.invokeGL(drawable, context, displayAction, initAction); + windowLock(); + try{ + helper.invokeGL(drawable, context, displayAction, initAction); + } finally { + windowUnlock(); + } } } } @@ -506,6 +522,7 @@ public class GLWindow extends Window implements GLAutoDrawable { public void swapBuffers() { if(drawable!=null && context != null) { + // Lock: Locked Surface/Window by MakeCurrent/Release if (context != GLContext.getCurrent()) { // Assume we should try to make the context current before swapping the buffers helper.invokeGL(drawable, context, swapBuffersAction, initAction); @@ -517,6 +534,7 @@ public class GLWindow extends Window implements GLAutoDrawable { class InitAction implements Runnable { public void run() { + // Lock: Locked Surface/Window by MakeCurrent/Release helper.init(GLWindow.this); startTime = System.currentTimeMillis(); curTime = startTime; @@ -528,15 +546,9 @@ public class GLWindow extends Window implements GLAutoDrawable { } private InitAction initAction = new InitAction(); - class DisposeAction implements Runnable { - public void run() { - helper.dispose(GLWindow.this); - } - } - private DisposeAction disposeAction = new DisposeAction(); - class DisplayAction implements Runnable { public void run() { + // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release if (sendReshape) { int width = getWidth(); int height = getHeight(); @@ -635,6 +647,10 @@ public class GLWindow extends Window implements GLAutoDrawable { return null!=drawable ? drawable.getNativeWindow() : null; } + public long getHandle() { + return null!=drawable ? drawable.getHandle() : 0; + } + //---------------------------------------------------------------------- // GLDrawable methods that are not really needed // diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c index b67b8dbd3..82f2ba7df 100755 --- a/src/newt/native/KDWindow.c +++ b/src/newt/native/KDWindow.c @@ -96,8 +96,8 @@ static jmethodID windowCreatedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; /** * Display @@ -180,13 +180,13 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes // time = ev->timestamp if(KD_INPUT_POINTER_SELECT==ptr->index) { DBG_PRINT( "event mouse click: src: %p, s:%d, (%d,%d)\n", userData, ptr->select, ptr->x, ptr->y); - (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, + (*env)->CallVoidMethod(env, javaWindow, enqueueMouseEventID, (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED, (jint) 0, (jint) ptr->x, (jint) ptr->y, 1, 0); } else { DBG_PRINT( "event mouse: src: %d, s:%p, i:0x%X (%d,%d)\n", userData, ptr->select, ptr->index, ptr->x, ptr->y); - (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + (*env)->CallVoidMethod(env, javaWindow, enqueueMouseEventID, (jint) EVENT_MOUSE_MOVED, 0, (jint) ptr->x, (jint) ptr->y, 0, 0); } @@ -213,14 +213,14 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_initIDs sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); - sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); - sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); if (windowCreatedID == NULL || sizeChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || - sendMouseEventID == NULL || - sendKeyEventID == NULL) { + enqueueMouseEventID == NULL || + enqueueKeyEventID == NULL) { DBG_PRINT( "initIDs failed\n" ); return JNI_FALSE; } diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index d8d59a7af..ae658b908 100755 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -109,8 +109,8 @@ jint GetDeltaY(NSEvent *event, jint javaMods) { @end -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; static jmethodID insetsChangedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID positionChangedID = NULL; @@ -122,15 +122,15 @@ static jmethodID windowDestroyedID = NULL; + (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz { - sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); - sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V"); positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); - if (sendMouseEventID && sendKeyEventID && sizeChangedID && insetsChangedID && + if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && insetsChangedID && positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID) { return YES; @@ -206,7 +206,7 @@ static jint mods2JavaMods(NSUInteger mods) return javaMods; } -- (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType +- (void) enqueueKeyEvent: (NSEvent*) event eventType: (jint) evType { NSView* nsview = [self contentView]; if( ! [nsview isMemberOfClass:[NewtView class]] ) { @@ -229,23 +229,23 @@ static jint mods2JavaMods(NSUInteger mods) // Note: the key code in the NSEvent does not map to anything we can use jchar keyChar = (jchar) [chars characterAtIndex: i]; - (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID, + (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, evType, javaMods, keyCode, keyChar); } } - (void) keyDown: (NSEvent*) theEvent { - [self sendKeyEvent: theEvent eventType: EVENT_KEY_PRESSED]; + [self enqueueKeyEvent: theEvent eventType: EVENT_KEY_PRESSED]; } - (void) keyUp: (NSEvent*) theEvent { - [self sendKeyEvent: theEvent eventType: EVENT_KEY_RELEASED]; - [self sendKeyEvent: theEvent eventType: EVENT_KEY_TYPED]; + [self enqueueKeyEvent: theEvent eventType: EVENT_KEY_RELEASED]; + [self enqueueKeyEvent: theEvent eventType: EVENT_KEY_TYPED]; } -- (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType +- (void) enqueueMouseEvent: (NSEvent*) event eventType: (jint) evType { NSView* nsview = [self contentView]; if( ! [nsview isMemberOfClass:[NewtView class]] ) { @@ -302,7 +302,7 @@ static jint mods2JavaMods(NSUInteger mods) // ignore 0 increment wheel scroll events return; } - (*env)->CallVoidMethod(env, javaWindowObject, sendMouseEventID, + (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, evType, javaMods, (jint) location.x, (jint) (contentRect.size.height - location.y), @@ -311,70 +311,70 @@ static jint mods2JavaMods(NSUInteger mods) - (void) mouseEntered: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; } - (void) mouseExited: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; } - (void) mouseMoved: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) scrollWheel: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED]; } - (void) mouseDown: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; } - (void) mouseDragged: (NSEvent*) theEvent { // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) mouseUp: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; } - (void) rightMouseDown: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; } - (void) rightMouseDragged: (NSEvent*) theEvent { // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) rightMouseUp: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; } - (void) otherMouseDown: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; } - (void) otherMouseDragged: (NSEvent*) theEvent { // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) otherMouseUp: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; } - (void)windowDidResize: (NSNotification*) notification diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 37fd9c621..5e3311d3b 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -115,8 +115,8 @@ static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; static jmethodID sendPaintEventID = NULL; static RECT* UpdateInsets(JNIEnv *env, HWND hwnd, jobject window); @@ -506,7 +506,7 @@ static int WmChar(JNIEnv *env, jobject window, UINT character, UINT repCnt, if (character == VK_RETURN) { character = J_VK_ENTER; } - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_TYPED, GetModifiers(), (jint) -1, @@ -551,7 +551,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, character = WindowsKeyToJavaChar(wkey, modifiers, SAVE); */ - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_PRESSED, modifiers, (jint) jkey, @@ -562,7 +562,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, WM_KEYDOWN. */ if (jkey == J_VK_DELETE) { - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_TYPED, GetModifiers(), (jint) -1, @@ -586,7 +586,7 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, character = WindowsKeyToJavaChar(wkey, modifiers, SAVE); */ - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_RELEASED, modifiers, (jint) jkey, @@ -595,11 +595,23 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, return 0; } -static void NewtWindows_requestFocus (HWND hwnd) { +static void NewtWindows_requestFocus (HWND hwnd, BOOL topLevel, BOOL reparented) { + DBG_PRINT("*** WindowsWindow: requestFocus.0 window %p\n", (void*)hwnd); if (IsWindow(hwnd)) { - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); + UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; + if(reparented) { + flags |= SWP_FRAMECHANGED; + } + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags); + DBG_PRINT("*** WindowsWindow: requestFocus.1\n"); SetForegroundWindow(hwnd); // Slightly Higher Priority + DBG_PRINT("*** WindowsWindow: requestFocus.2\n"); SetFocus(hwnd);// Sets Keyboard Focus To TheWindow + DBG_PRINT("*** WindowsWindow: requestFocus.3\n"); + if(topLevel) { + SetActiveWindow(hwnd); + } + DBG_PRINT("*** WindowsWindow: requestFocus.X\n"); } } @@ -786,8 +798,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, case WM_LBUTTONDOWN: - NewtWindows_requestFocus ( wnd ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, sendMouseEventID, + NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -796,7 +808,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_LBUTTONUP: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -805,8 +817,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MBUTTONDOWN: - NewtWindows_requestFocus ( wnd ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, sendMouseEventID, + NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -815,7 +827,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MBUTTONUP: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -824,8 +836,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_RBUTTONDOWN: - NewtWindows_requestFocus ( wnd ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, sendMouseEventID, + NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -834,7 +846,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_RBUTTONUP: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -843,7 +855,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MOUSEMOVE: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_MOVED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -859,7 +871,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, eventPt.x = x; eventPt.y = y; ScreenToClient(wnd, &eventPt); - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_WHEEL_MOVED, GetModifiers(), (jint) eventPt.x, (jint) eventPt.y, @@ -1046,8 +1058,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(JZ)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); - sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); - sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); sendPaintEventID = (*env)->GetMethodID(env, clazz, "sendPaintEvent", "(IIIII)V"); if (sizeChangedID == NULL || insetsChangedID == NULL || @@ -1055,9 +1067,9 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI focusChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || - sendMouseEventID == NULL || + enqueueMouseEventID == NULL || sendPaintEventID == NULL || - sendKeyEventID == NULL) + enqueueKeyEventID == NULL) { return JNI_FALSE; } @@ -1130,7 +1142,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi ShowWindow(window, SW_SHOWNORMAL); if(NULL!=parentWindow) { - NewtWindows_requestFocus ( window ); // request focus on this window, if not already .. + NewtWindows_requestFocus ( window, FALSE, FALSE ); // request focus on this window, if not already .. } /* else { // top level already capable of receiving [keyboard] events } */ @@ -1154,6 +1166,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_DestroyWindow0 (JNIEnv *env, jobject obj, jlong window) { + DBG_PRINT("*** WindowsWindow: DestroyWindow window %p\n", window); DestroyWindow((HWND) (intptr_t) window); } @@ -1279,25 +1292,34 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setPositi } } -/* - * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: setFullscreen - * Signature: (JIIIIZ)V - */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullscreen0 - (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) +static void NewtWindows_reparentWindow(HWND hwndP, HWND hwnd, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) { UINT flags; - HWND hwndP = (HWND) (intptr_t) parent; - HWND hwnd = (HWND) (intptr_t) window; HWND hWndInsertAfter; - DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN ; + BOOL isVisible = IsWindowVisible(hwnd); + + DBG_PRINT("*** WindowsWindow: reparentWindow.1 parent %p, window %p, %d/%d %dx%d undeco %d visible %d\n", (void*)hwndP, (void*)hwnd, x, y, width, height, bIsUndecorated, isVisible); + if (!IsWindow(hwnd)) { + DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed window %p is invalid\n", (void*)hwnd); + return; + } + if (NULL!=hwndP && !IsWindow(hwndP)) { + DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed parent window %p is invalid\n", (void*)hwndP); + return; + } + + if (isVisible) { + windowStyle |= WS_VISIBLE; + } // order of call sequence: (MS documentation) - // SetParent(.., NULL), SetWindowLong ( WS_POPUP ) - // SetParent(.., PARENT), SetWindowLong ( WS_CHILD ) + // TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP] + // CHILD: Set WS_CHILD [, Clear WS_POPUP]; SetParent(.., PARENT) + // if ( NULL == hwndP ) { SetParent(hwnd, NULL); + DBG_PRINT("*** WindowsWindow: reparentWindow.2\n"); } if(NULL!=hwndP) { @@ -1308,32 +1330,26 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc windowStyle |= WS_OVERLAPPEDWINDOW; } SetWindowLong(hwnd, GWL_STYLE, windowStyle); + DBG_PRINT("*** WindowsWindow: reparentWindow.3\n"); if ( NULL != hwndP ) { SetParent(hwnd, hwndP ); + DBG_PRINT("*** WindowsWindow: reparentWindow.4\n"); } - if ( NULL == hwndP ) { - flags = SWP_SHOWWINDOW; - hWndInsertAfter = HWND_TOPMOST; - } else { - flags = SWP_NOACTIVATE | SWP_NOZORDER; - hWndInsertAfter = 0; + if(isVisible) { + NewtWindows_requestFocus ( hwnd, ( NULL == hwndP ) ? TRUE : FALSE, TRUE ); } - SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags); - - NewtWindows_requestFocus ( hwnd ); - - (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); + DBG_PRINT("*** WindowsWindow: reparentWindow.X\n"); } /* * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: reparentWindow0 + * Method: setFullscreen * Signature: (JIIIIZ)V */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentWindow0 +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullscreen0 (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) { UINT flags; @@ -1341,28 +1357,13 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentW HWND hwnd = (HWND) (intptr_t) window; HWND hWndInsertAfter; DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + BOOL isVisible = IsWindowVisible(hwnd); - // order of call sequence: (MS documentation) - // SetParent(.., NULL), SetWindowLong ( WS_POPUP ) - // SetParent(.., PARENT), SetWindowLong ( WS_CHILD ) - if ( NULL == hwndP ) { - SetParent(hwnd, NULL); - } + DBG_PRINT("*** WindowsWindow: setFullscreen.1 parent %p, window %p, %d/%d %dx%d undeco %d visible\n", + parent, window, x, y, width, height, bIsUndecorated, isVisible); - if(NULL!=hwndP) { - windowStyle |= WS_CHILD ; - } else if (bIsUndecorated) { - windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; - } else { - windowStyle |= WS_OVERLAPPEDWINDOW; - } - SetWindowLong(hwnd, GWL_STYLE, windowStyle); + NewtWindows_reparentWindow(hwndP, hwnd, x, y, width, height, bIsUndecorated); - if ( NULL != hwndP ) { - SetParent(hwnd, hwndP ); - } - - /** if ( NULL == hwndP ) { flags = SWP_SHOWWINDOW; hWndInsertAfter = HWND_TOPMOST; @@ -1372,11 +1373,23 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentW } SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags); - */ - NewtWindows_requestFocus ( hwnd ); + DBG_PRINT("*** WindowsWindow: setFullscreen.X\n"); + (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); // resize necessary .. +} + +/* + * Class: com_jogamp_newt_impl_windows_WindowsWindow + * Method: reparentWindow0 + * Signature: (JIIIIZ)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentWindow0 + (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) +{ + HWND hwndP = (HWND) (intptr_t) parent; + HWND hwnd = (HWND) (intptr_t) window; - // (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); + NewtWindows_reparentWindow(hwndP, hwnd, x, y, width, height, bIsUndecorated); } /* @@ -1403,8 +1416,8 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setTitle0 * Signature: (J)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_requestFocus0 - (JNIEnv *env, jclass clazz, jlong window) + (JNIEnv *env, jclass clazz, jlong parent, jlong window) { - NewtWindows_requestFocus ( (HWND) (intptr_t) window ) ; + NewtWindows_requestFocus ( (HWND) (intptr_t) window, (0 == parent) ? TRUE : FALSE, FALSE ) ; } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index f77f54cd1..a521d2dbd 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -58,18 +58,7 @@ // #define VERBOSE_ON 1 #ifdef VERBOSE_ON - // Workaround for ancient compiler on Solaris/SPARC - // #define DBG_PRINT(args...) fprintf(stderr, args); - #define DBG_PRINT0(str) fprintf(stderr, str); - #define DBG_PRINT1(str, arg1) fprintf(stderr, str, arg1); - #define DBG_PRINT2(str, arg1, arg2) fprintf(stderr, str, arg1, arg2); - #define DBG_PRINT3(str, arg1, arg2, arg3) fprintf(stderr, str, arg1, arg2, arg3); - #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) fprintf(stderr, str, arg1, arg2, arg3, arg4); - #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5); - #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6); - #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - #define DBG_PRINT9(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) #define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b)) @@ -95,18 +84,7 @@ #else - // Workaround for ancient compiler on Solaris/SPARC - // #define DBG_PRINT(args...) - #define DBG_PRINT0(str) - #define DBG_PRINT1(str, arg1) - #define DBG_PRINT2(str, arg1, arg2) - #define DBG_PRINT3(str, arg1, arg2, arg3) - #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) - #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) - #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) - #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) - #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) - #define DBG_PRINT9(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + #define DBG_PRINT(...) #define DUMP_VISUAL_INFO(a,b) @@ -179,8 +157,8 @@ static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; static jmethodID windowCreatedID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; static jmethodID displayCompletedID = NULL; @@ -189,10 +167,6 @@ static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, cons char buffer[512]; va_list ap; - if(NULL!=unlockDisplay) { - XUnlockDisplay(unlockDisplay); - } - va_start(ap, msg); vsnprintf(buffer, sizeof(buffer), msg, ap); va_end(ap); @@ -293,7 +267,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0 if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; javaObjectAtom = (jlong) XInternAtom(dpy, "JOGL_JAVA_OBJECT", False); if(None==javaObjectAtom) { @@ -308,9 +281,8 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0 } // XSetCloseDownMode(dpy, RetainTemporary); // Just a try .. - XUnlockDisplay(dpy) ; - DBG_PRINT1("X11: X11Display_completeDisplay dpy %p\n", dpy); + DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy); (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom); } @@ -409,13 +381,9 @@ static void NewtWindows_requestFocus0 (Display *dpy, Window w, XWindowAttributes static void NewtWindows_requestFocus1 (Display *dpy, Window w) { XWindowAttributes xwa; - XLockDisplay(dpy) ; - XGetWindowAttributes(dpy, w, &xwa); NewtWindows_requestFocus0 (dpy, w, &xwa); XSync(dpy, False); - - XUnlockDisplay(dpy) ; } /** @@ -480,14 +448,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages char keyChar; char text[255]; - XLockDisplay(dpy) ; - // num_events = XPending(dpy); // I/O Flush .. // num_events = XEventsQueued(dpy, QueuedAfterFlush); // I/O Flush only of no already queued events are available // num_events = XEventsQueued(dpy, QueuedAlready); // no I/O Flush at all, doesn't work on some cards (eg ATI) if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) { - XUnlockDisplay(dpy) ; - // DBG_PRINT1( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); + // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); return; } @@ -504,7 +469,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages return ; } - DBG_PRINT3( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); + DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); displayDispatchErrorHandlerEnable(1, env); @@ -521,8 +486,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages if(NULL==jwindow) { fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window); - - XUnlockDisplay(dpy) ; continue; } @@ -539,49 +502,47 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages break; } - XUnlockDisplay(dpy) ; - switch(evt.type) { case ButtonPress: NewtWindows_requestFocus1 ( dpy, evt.xany.window ); - (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, (jint) evt.xbutton.state, (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); break; case ButtonRelease: - (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, (jint) evt.xbutton.state, (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); break; case MotionNotify: - (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (jint) EVENT_MOUSE_MOVED, (jint) evt.xmotion.state, (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); break; case KeyPress: - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED, + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_PRESSED, (jint) evt.xkey.state, X11KeySym2NewtVKey(keySym), (jchar) keyChar); break; case KeyRelease: - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_RELEASED, (jint) evt.xkey.state, X11KeySym2NewtVKey(keySym), (jchar) keyChar); - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_TYPED, (jint) evt.xkey.state, (jint) -1, (jchar) keyChar); break; case DestroyNotify: - DBG_PRINT1( "X11: event . DestroyNotify call 0x%X\n", (unsigned int)evt.xdestroywindow.window); + DBG_PRINT( "X11: event . DestroyNotify call 0x%X\n", (unsigned int)evt.xdestroywindow.window); (*env)->CallVoidMethod(env, jwindow, windowDestroyedID); break; case CreateNotify: - DBG_PRINT1( "X11: event . CreateNotify call 0x%X\n", (unsigned int)evt.xcreatewindow.window); + DBG_PRINT( "X11: event . CreateNotify call 0x%X\n", (unsigned int)evt.xcreatewindow.window); (*env)->CallVoidMethod(env, jwindow, windowCreatedID); break; case ConfigureNotify: - DBG_PRINT8( "X11: event . ConfigureNotify call 0x%X (parent 0x%X, above 0x%X) %d/%d %dx%d %d\n", + DBG_PRINT( "X11: event . ConfigureNotify call 0x%X (parent 0x%X, above 0x%X) %d/%d %dx%d %d\n", (unsigned int)evt.xconfigure.window, (unsigned int)evt.xconfigure.event, (unsigned int)evt.xconfigure.above, evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height, evt.xconfigure.override_redirect); @@ -591,43 +552,43 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages break; case ClientMessage: if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) { - DBG_PRINT2( "X11: event . ClientMessage call 0x%X type 0x%X !!!\n", (unsigned int)evt.xclient.window, (unsigned int)evt.xclient.message_type); + DBG_PRINT( "X11: event . ClientMessage call 0x%X type 0x%X !!!\n", (unsigned int)evt.xclient.window, (unsigned int)evt.xclient.message_type); (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID); // Called by Window.java: CloseWindow(); } break; case FocusIn: - DBG_PRINT1( "X11: event . FocusIn call 0x%X\n", (unsigned int)evt.xvisibility.window); + DBG_PRINT( "X11: event . FocusIn call 0x%X\n", (unsigned int)evt.xvisibility.window); (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE); break; case FocusOut: - DBG_PRINT1( "X11: event . FocusOut call 0x%X\n", (unsigned int)evt.xvisibility.window); + DBG_PRINT( "X11: event . FocusOut call 0x%X\n", (unsigned int)evt.xvisibility.window); (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE); break; case MapNotify: - DBG_PRINT1( "X11: event . MapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); + DBG_PRINT( "X11: event . MapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); break; case UnmapNotify: - DBG_PRINT1( "X11: event . UnmapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); + DBG_PRINT( "X11: event . UnmapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); break; // unhandled events .. yet .. case VisibilityNotify: - DBG_PRINT1( "X11: event . VisibilityNotify call 0x%X\n", (unsigned int)evt.xvisibility.window); + DBG_PRINT( "X11: event . VisibilityNotify call 0x%X\n", (unsigned int)evt.xvisibility.window); break; case Expose: - DBG_PRINT1( "X11: event . Expose call 0x%X\n", (unsigned int)evt.xexpose.window); + DBG_PRINT( "X11: event . Expose call 0x%X\n", (unsigned int)evt.xexpose.window); /* FIXME: Might want to send a repaint event .. */ break; default: - DBG_PRINT3("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window); + DBG_PRINT("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window); } } } @@ -648,10 +609,11 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_GetScreen0 Display * dpy = (Display *)(intptr_t)display; Screen * scrn= NULL; + DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy); + if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy); scrn = ScreenOfDisplay(dpy,screen_index); if(scrn==NULL) { @@ -660,7 +622,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_GetScreen0 if(scrn==NULL) { fprintf(stderr, "couldn't get screen ..\n"); } - XUnlockDisplay(dpy) ; + DBG_PRINT("X11: X11Screen_GetScreen0 scrn %p DONE\n", scrn); return (jlong) (intptr_t) scrn; } @@ -697,8 +659,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); - sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); - sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); if (windowChangedID == NULL || focusChangedID == NULL || @@ -706,8 +668,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 windowDestroyNotifyID == NULL || windowDestroyedID == NULL || windowCreatedID == NULL || - sendMouseEventID == NULL || - sendKeyEventID == NULL) { + enqueueMouseEventID == NULL || + enqueueKeyEventID == NULL) { return JNI_FALSE; } return JNI_TRUE; @@ -751,15 +713,13 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 return 0; } - XLockDisplay(dpy) ; - XSync(dpy, False); scrn = ScreenOfDisplay(dpy, scrn_idx); if(0==windowParent) { windowParent = XRootWindowOfScreen(scrn); } - DBG_PRINT7( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d\n", + DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d\n", (void*)dpy, (void*)windowParent, x, y, width, height, undecorated); // try given VisualID on screen @@ -775,7 +735,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 XFree(pVisualQuery); pVisualQuery=NULL; } - DBG_PRINT5( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", + DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, (void*)windowParent, visual); if (visual==NULL) @@ -831,12 +791,10 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 XSelectInput(dpy, window, xevent_mask); } - NewtWindows_setDecorations (dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); - + NewtWindows_setDecorations(dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); XSync(dpy, False); - XUnlockDisplay(dpy) ; - DBG_PRINT2( "X11: [CreateWindow] created window 0x%X on display %p\n", (unsigned int)window, dpy); + DBG_PRINT( "X11: [CreateWindow] created window 0x%X on display %p\n", (unsigned int)window, dpy); (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window); return (jlong) window; @@ -857,9 +815,8 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; - DBG_PRINT2( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); + DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True); if(NULL==jwindow) { @@ -878,8 +835,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 XDestroyWindow(dpy, w); XSync(dpy, False); - DBG_PRINT0( "X11: CloseWindow END\n"); - XUnlockDisplay(dpy) ; + DBG_PRINT( "X11: CloseWindow END\n"); (*env)->CallVoidMethod(env, obj, windowDestroyedID); } @@ -894,12 +850,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; - DBG_PRINT1( "X11: setVisible0 vis %d\n", visible); + DBG_PRINT( "X11: setVisible0 vis %d\n", visible); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; if(visible==JNI_TRUE) { XMapRaised(dpy, w); @@ -907,7 +862,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 XUnmapWindow(dpy, w); } XSync(dpy, False); - XUnlockDisplay(dpy) ; } /* @@ -922,12 +876,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 Window w = (Window)window; XWindowChanges xwc; - DBG_PRINT2( "X11: setSize0 %dx%d\n", width, height); + DBG_PRINT( "X11: setSize0 %dx%d\n", width, height); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; memset(&xwc, 0, sizeof(XWindowChanges)); xwc.width=width; @@ -935,7 +888,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc); XSync(dpy, False); - XUnlockDisplay(dpy) ; } /* @@ -950,47 +902,60 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 Window w = (Window)window; XWindowChanges xwc; - DBG_PRINT2( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y); + DBG_PRINT( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; xwc.y=y; XConfigureWindow(dpy, w, CWX|CWY, &xwc); XSync(dpy, False); - - XUnlockDisplay(dpy) ; } static void NewtWindows_reparentWindow - (Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent, jint x, jint y, jboolean undecorated) + (Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent, jint x, jint y, jboolean undecorated, jboolean isVisible) { Window parent = (0!=jparent)?(Window)jparent:XRootWindowOfScreen(scrn); - DBG_PRINT7( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n", + DBG_PRINT( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n", (void*)dpy, (void*) jparent, (void*)parent, (void*)w, x, y, undecorated); - // let parent ignore reparent request - NewtWindows_setOverrideRedirect0 (dpy, w, xwa, True); - if(JNI_TRUE == undecorated) { + if(0 != jparent) { + // move into parent .. NewtWindows_setDecorations (dpy, w, False); + XSync(dpy, False); + NewtWindows_setOverrideRedirect0 (dpy, w, xwa, True); + XSync(dpy, False); + } + + if(JNI_TRUE == isVisible) { + XUnmapWindow(dpy, w); + XSync(dpy, False); } - XSync(dpy, False); XReparentWindow( dpy, w, parent, x, y ); - XRaiseWindow(dpy, w); XSync(dpy, False); - NewtWindows_setOverrideRedirect0 (dpy, w, xwa, ( 0 != jparent ) ? True : False ); - if(JNI_FALSE == undecorated) { - NewtWindows_setDecorations (dpy, w, True); + if(0 == jparent) + { + // move out of parent .. + NewtWindows_setOverrideRedirect0 (dpy, w, xwa, (0 == jparent) ? False : True); + XSync(dpy, False); + NewtWindows_setDecorations (dpy, w, (JNI_TRUE == undecorated) ? False : True); + XSync(dpy, False); } - XSync(dpy, False); - DBG_PRINT0( "X11: reparentWindow X\n"); + if(JNI_TRUE == isVisible) { + XRaiseWindow(dpy, w); + XSync(dpy, False); + + XMapWindow(dpy, w); + XSync(dpy, False); + } + + DBG_PRINT( "X11: reparentWindow X\n"); } /* @@ -1000,7 +965,7 @@ static void NewtWindows_reparentWindow */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, - jint x, jint y, jint width, jint height, jboolean undecorated) + jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -1009,18 +974,18 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 XWindowChanges xwc; XWindowAttributes xwa; - DBG_PRINT8( "X11: setPosSizeDecor0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d\n", - (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated); + DBG_PRINT( "X11: setPosSizeDecor0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d\n", + (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; XSync(dpy, False); XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated); + NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); + XSync(dpy, False); memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; @@ -1028,11 +993,12 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 xwc.width=width; xwc.height=height; XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc); - XSync(dpy, False); - NewtWindows_requestFocus0 ( dpy, w, &xwa ); - XSync(dpy, False); - XUnlockDisplay(dpy) ; + if(JNI_TRUE == isVisible) { + XGetWindowAttributes(dpy, w, &xwa); + NewtWindows_requestFocus0 ( dpy, w, &xwa ); + XSync(dpy, False); + } } /* @@ -1041,28 +1007,28 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 * Signature: (JJIJIIZ)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0 - (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y, jboolean undecorated) + (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y, + jboolean undecorated, jboolean isVisible) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index); XWindowAttributes xwa; - DBG_PRINT6( "X11: reparentWindow0 dpy %p, parent %p, win %p, %d/%d undec %d\n", - (void*)dpy, (void*) jparent, (void*)w, x, y, undecorated); + DBG_PRINT( "X11: reparentWindow0 dpy %p, parent %p, win %p, %d/%d undec %d, visible %d\n", + (void*)dpy, (void*) jparent, (void*)w, x, y, undecorated, isVisible); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; XSync(dpy, False); XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated); + NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); + XSync(dpy, False); - XUnlockDisplay(dpy) ; - DBG_PRINT0( "X11: reparentWindow0 X\n"); + DBG_PRINT( "X11: reparentWindow0 X\n"); } /* @@ -1087,15 +1053,19 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0 Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; - XLockDisplay(dpy) ; #if 1 const char* title_str; if (NULL != title) { title_str = (*env)->GetStringUTFChars(env, title, NULL); if(NULL != title_str) { + DBG_PRINT( "X11: setTitle: <%s> SET\n", title_str); XStoreName(dpy, w, title_str); (*env)->ReleaseStringUTFChars(env, title, title_str); + } else { + DBG_PRINT( "X11: setTitle: NULL - NOT SET (1)\n"); } + } else { + DBG_PRINT( "X11: setTitle: NULL TITLE\n"); } #else char *str_list[] = { NULL }; @@ -1105,18 +1075,22 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0 if (str_list[0] != NULL) { memset(&text_prop, 0, sizeof(XTextProperty)); if ( Success != XmbTextListToTextProperty(dpy, str_list, 1, XStringStyle, &text_prop) ) { - DBG_PRINT0( "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); + DBG_PRINT( "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); fprintf(stderr, "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); } if(NULL!=text_prop.value) { + DBG_PRINT( "X11: setTitle: <%s> SET\n", str_list[0]); XSetWMName(dpy, w, &text_prop); XFree(text_prop.value); + } else { + DBG_PRINT( "X11: setTitle: <%s> NOT SET (1)\n", str_list[0]); } free(str_list[0]); + } else { + DBG_PRINT( "X11: setTitle: NULL\n"); } } #endif - XUnlockDisplay(dpy) ; } |